Skip to content

Commit

Permalink
Basic envers verification
Browse files Browse the repository at this point in the history
  • Loading branch information
dima767 committed May 8, 2019
1 parent 99d1184 commit cb37e82
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 0 deletions.
3 changes: 3 additions & 0 deletions backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ dependencies {
compile 'com.opencsv:opencsv:4.4'

testCompile 'org.skyscreamer:jsonassert:1.5.0'

// Envers for persistent entities versioning
compile 'org.hibernate:hibernate-envers'
}

def generatedSrcDir = new File(buildDir, 'generated/src/main/java')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.envers.Audited;

import javax.persistence.Column;
import javax.persistence.Entity;
Expand All @@ -34,6 +35,7 @@
@JsonSubTypes.Type(value=SignatureValidationFilter.class, name="SignatureValidation"),
@JsonSubTypes.Type(value=RequiredValidUntilFilter.class, name="RequiredValidUntil"),
@JsonSubTypes.Type(value=NameIdFormatFilter.class, name="NameIDFormat")})
@Audited
public class MetadataFilter extends AbstractAuditable {

@JsonProperty("@type")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.envers.Audited;

import javax.persistence.CascadeType;
import javax.persistence.ElementCollection;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.envers.Audited;

import javax.persistence.CascadeType;
import javax.persistence.Column;
Expand All @@ -37,6 +38,7 @@
@JsonSubTypes.Type(value = DynamicHttpMetadataResolver.class, name = "DynamicHttpMetadataResolver"),
@JsonSubTypes.Type(value = FilesystemMetadataResolver.class, name = "FilesystemMetadataResolver"),
@JsonSubTypes.Type(value = ResourceBackedMetadataResolver.class, name = "ResourceBackedMetadataResolver")})
@Audited
public class MetadataResolver extends AbstractAuditable {

@JsonProperty("@type")
Expand Down
3 changes: 3 additions & 0 deletions backend/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ spring.jpa.properties.hibernate.format_sql=false

spring.jpa.hibernate.use-new-id-generator-mappings=true

#Envers versioning
spring.jpa.properties.org.hibernate.envers.store_data_at_delete=true

# Set the following property to periodically write out the generated metadata files. There is no default value; the following is just an example
# shibui.metadata-dir=/opt/shibboleth-idp/metadata/generated
shibui.logout-url=/dashboard
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package edu.internet2.tier.shibboleth.admin.ui.repository.envers

import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration
import edu.internet2.tier.shibboleth.admin.ui.configuration.InternationalizationConfiguration
import edu.internet2.tier.shibboleth.admin.ui.configuration.SearchConfiguration
import edu.internet2.tier.shibboleth.admin.ui.configuration.TestConfiguration
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilter
import edu.internet2.tier.shibboleth.admin.ui.domain.filters.EntityAttributesFilterTarget
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository
import org.hibernate.envers.AuditReaderFactory
import org.hibernate.envers.query.AuditQuery
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.domain.EntityScan
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
import org.springframework.test.context.ContextConfiguration
import org.springframework.transaction.PlatformTransactionManager
import org.springframework.transaction.support.DefaultTransactionDefinition
import spock.lang.Specification

import javax.persistence.EntityManager

import static org.springframework.transaction.TransactionDefinition.PROPAGATION_REQUIRES_NEW

/**
* Testing metadata resolvers basic versioning by envers is functioning.
*/
@DataJpaTest
@ContextConfiguration(classes = [CoreShibUiConfiguration, InternationalizationConfiguration, TestConfiguration, SearchConfiguration])
@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"])
@EntityScan("edu.internet2.tier.shibboleth.admin.ui")
class MetadataResolverEntityBasicEnversVersioningTests extends Specification {

@Autowired
MetadataResolverRepository metadataResolverRepository

@Autowired
EntityManager entityManager

@Autowired
PlatformTransactionManager txMgr

def "test basic audit and version data is created when persisting base metadata resolver with envers enabled"() {
when:
doInExplicitTransaction {
metadataResolverRepository.save(create {new MetadataResolver()})
}
def metadataResolverHistory = metadataResolverHistory()

then:
metadataResolverHistory
}

private metadataResolverHistory() {
def auditReader = AuditReaderFactory.get(entityManager)
AuditQuery auditQuery = auditReader
.createQuery()
.forRevisionsOfEntity(MetadataResolver, false, true)
auditQuery.resultList

}

private static create(Closure concreteResolverSupplier) {
MetadataResolver resolver = concreteResolverSupplier()
resolver.with {
it.name = "testme"
it.metadataFilters.add(new EntityAttributesFilter().with {
it.entityAttributesFilterTarget = new EntityAttributesFilterTarget().with {
it.entityAttributesFilterTargetType = EntityAttributesFilterTarget.EntityAttributesFilterTargetType.ENTITY
it.value = ["hola"]
return it
}
return it
})
}
resolver
}

//This explicit low level transaction dance is required in order to verify history/version data that envers
//writes out only after the explicit transaction is committed, therefore making it impossible to verify within the main tx
//boundary of the test method which commits tx only after an execution of the test method. This let's us explicitly
//start/commit transaction making envers data written out and verifiable
private doInExplicitTransaction(Closure uow) {
def txStatus = txMgr.getTransaction(new DefaultTransactionDefinition(PROPAGATION_REQUIRES_NEW))
uow()
txMgr.commit(txStatus)
}
}

0 comments on commit cb37e82

Please sign in to comment.