Skip to content

Commit

Permalink
Merge branch 'SHIBUI-1337' of bitbucket.org:unicon/shib-idp-ui into f…
Browse files Browse the repository at this point in the history
…eature/SHIBUI-1270
  • Loading branch information
rmathis committed Jul 15, 2019
2 parents db62acb + 33929b4 commit a564b53
Show file tree
Hide file tree
Showing 17 changed files with 260 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class EntityDescriptorControllerVersionEndpointsIntegrationTests extends Specifi
result.statusCodeValue == 404
}

def "GET /api/EntityDescriptor{resourceId}/Versions with 1 entity descriptor version"() {
def "GET /api/EntityDescriptor/{resourceId}/Versions with 1 entity descriptor version"() {
given:
EntityDescriptor ed = new EntityDescriptor(entityID: 'http://test/controller', createdBy: 'anonymousUser')
entityDescriptorRepository.save(ed)
Expand All @@ -50,7 +50,7 @@ class EntityDescriptorControllerVersionEndpointsIntegrationTests extends Specifi
result.body[0].id && result.body[0].creator && result.body[0].date
}

def "GET /api/EntityDescriptor{resourceId}/Versions with 2 entity descriptor versions"() {
def "GET /api/EntityDescriptor/{resourceId}/Versions with 2 entity descriptor versions"() {
given:
EntityDescriptor ed = new EntityDescriptor(entityID: 'http://test/controller', createdBy: 'anonymousUser')
ed = entityDescriptorRepository.save(ed)
Expand All @@ -68,7 +68,7 @@ class EntityDescriptorControllerVersionEndpointsIntegrationTests extends Specifi
result.body[0].date < result.body[1].date
}

def "GET /api/EntityDescriptor{resourceId}/Versions/{version} for non existent version"() {
def "GET /api/EntityDescriptor/{resourceId}/Versions/{version} for non existent version"() {
given:
EntityDescriptor ed = new EntityDescriptor(entityID: 'http://test/controller', createdBy: 'anonymousUser')
ed = entityDescriptorRepository.save(ed)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,20 @@ import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorVersionSer
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.EnableJpaAuditing
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
import org.springframework.test.context.ContextConfiguration
import org.springframework.transaction.PlatformTransactionManager
import spock.lang.Specification

import java.time.LocalDateTime
import java.time.ZonedDateTime


@DataJpaTest
@ContextConfiguration(classes = [CoreShibUiConfiguration, InternationalizationConfiguration, TestConfiguration, SearchConfiguration, EntitiesVersioningConfiguration])
@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"])
@EntityScan("edu.internet2.tier.shibboleth.admin.ui")
@EnableJpaAuditing
class EnversEntityDescriptorVersionServiceTests extends Specification {

@Autowired
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import edu.internet2.tier.shibboleth.admin.ui.configuration.EntitiesVersioningCo
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.EntityDescriptor
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.FilesystemMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.LocalDynamicMetadataResolver
Expand All @@ -18,19 +17,20 @@ import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverVersionSer
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.EnableJpaAuditing
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
import org.springframework.test.context.ContextConfiguration
import org.springframework.transaction.PlatformTransactionManager
import spock.lang.Specification

import java.time.LocalDateTime
import java.time.ZonedDateTime


@DataJpaTest
@ContextConfiguration(classes = [CoreShibUiConfiguration, InternationalizationConfiguration, TestConfiguration, SearchConfiguration, EntitiesVersioningConfiguration])
@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"])
@EntityScan("edu.internet2.tier.shibboleth.admin.ui")
@EnableJpaAuditing
class EnversMetadataResolverVersionServiceTests extends Specification {

@Autowired
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package edu.internet2.tier.shibboleth.admin.ui.service.envers

import edu.internet2.tier.shibboleth.admin.ui.configuration.CoreShibUiConfiguration
import edu.internet2.tier.shibboleth.admin.ui.configuration.EntitiesVersioningConfiguration
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.EntityDescriptor
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.DynamicHttpMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.LocalDynamicMetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver
import edu.internet2.tier.shibboleth.admin.ui.repository.EntityDescriptorRepository
import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository
import edu.internet2.tier.shibboleth.admin.ui.repository.envers.EnversTestsSupport
import edu.internet2.tier.shibboleth.admin.ui.service.EntityDescriptorVersionService
import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverVersionService
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.EnableJpaAuditing
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
import org.springframework.test.context.ContextConfiguration
import org.springframework.transaction.PlatformTransactionManager
import spock.lang.Specification

@DataJpaTest
@ContextConfiguration(classes = [CoreShibUiConfiguration, InternationalizationConfiguration, TestConfiguration, SearchConfiguration, EntitiesVersioningConfiguration])
@EnableJpaRepositories(basePackages = ["edu.internet2.tier.shibboleth.admin.ui"])
@EntityScan("edu.internet2.tier.shibboleth.admin.ui")
@EnableJpaAuditing
class EnversVersioningMetadataTests extends Specification {

@Autowired
MetadataResolverVersionService metadataResolverVersionService

@Autowired
MetadataResolverRepository metadataResolverRepository

@Autowired
EntityDescriptorVersionService entityDescriptorVersionService

@Autowired
EntityDescriptorRepository entityDescriptorRepository

@Autowired
PlatformTransactionManager txMgr

def "versioning service uses versioning metadata from target entities enhanced by boot auditing facility"() {
when: 'Initial versions'
MetadataResolver mr = new LocalDynamicMetadataResolver(name: 'resolver')
EntityDescriptor ed = new EntityDescriptor(serviceProviderName: 'descriptor')
mr = EnversTestsSupport.doInExplicitTransaction(txMgr) {
metadataResolverRepository.save(mr)
}
ed = EnversTestsSupport.doInExplicitTransaction(txMgr) {
entityDescriptorRepository.save(ed)
}
def mrVersions = metadataResolverVersionService.findVersionsForMetadataResolver(mr.resourceId)
def edVersions = entityDescriptorVersionService.findVersionsForEntityDescriptor(ed.resourceId)

then:
mrVersions[0].creator == mr.createdBy
mrVersions[0].date == mr.createdDateAsZonedDateTime()
edVersions[0].creator == ed.createdBy
edVersions[0].date == ed.createdDateAsZonedDateTime()

when: 'new version due to update'
mr.name = 'UPDATED'
ed.serviceProviderName = 'UPDATED'
mr = EnversTestsSupport.doInExplicitTransaction(txMgr) {
metadataResolverRepository.save(mr)
}
ed = EnversTestsSupport.doInExplicitTransaction(txMgr) {
entityDescriptorRepository.save(ed)
}
mrVersions = metadataResolverVersionService.findVersionsForMetadataResolver(mr.resourceId)
edVersions = entityDescriptorVersionService.findVersionsForEntityDescriptor(ed.resourceId)

then:
mrVersions[1].creator == mr.modifiedBy
mrVersions[1].date == mr.modifiedDateAsZonedDateTime()
edVersions[1].creator == ed.modifiedBy
edVersions[1].date == ed.modifiedDateAsZonedDateTime()
}

def "test current version correct logic"() {
when: 'Initial versions'
MetadataResolver mr = new DynamicHttpMetadataResolver(name: 'resolver')
EntityDescriptor ed = new EntityDescriptor(serviceProviderName: 'descriptor')
mr = EnversTestsSupport.doInExplicitTransaction(txMgr) {
metadataResolverRepository.save(mr)
}
ed = EnversTestsSupport.doInExplicitTransaction(txMgr) {
entityDescriptorRepository.save(ed)
}
def mrVersions = metadataResolverVersionService.findVersionsForMetadataResolver(mr.resourceId)
def edVersions = entityDescriptorVersionService.findVersionsForEntityDescriptor(ed.resourceId)
def mrV1 = metadataResolverVersionService.findSpecificVersionOfMetadataResolver(mr.resourceId, mrVersions[0].id)
def edV1 = entityDescriptorVersionService.findSpecificVersionOfEntityDescriptor(ed.resourceId, edVersions[0].id)

then:
mrV1.isCurrent()
edV1.isCurrent()

when: 'new version due to update'
mr.name = 'UPDATED'
ed.serviceProviderName = 'UPDATED'
mr = EnversTestsSupport.doInExplicitTransaction(txMgr) {
metadataResolverRepository.save(mr)
}
ed = EnversTestsSupport.doInExplicitTransaction(txMgr) {
entityDescriptorRepository.save(ed)
}
mrVersions = metadataResolverVersionService.findVersionsForMetadataResolver(mr.resourceId)
edVersions = entityDescriptorVersionService.findVersionsForEntityDescriptor(ed.resourceId)
mrV1 = metadataResolverVersionService.findSpecificVersionOfMetadataResolver(mr.resourceId, mrVersions[0].id)
edV1 = entityDescriptorVersionService.findSpecificVersionOfEntityDescriptor(ed.resourceId, edVersions[0].id)
def mrV2 = metadataResolverVersionService.findSpecificVersionOfMetadataResolver(mr.resourceId, mrVersions[1].id)
def edV2 = entityDescriptorVersionService.findSpecificVersionOfEntityDescriptor(ed.resourceId, edVersions[1].id)

then:
!mrV1.isCurrent()
!edV1.isCurrent()
mrV2.isCurrent()
edV2.isCurrent()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class EntitiesVersioningConfiguration {

@Bean
public EntityDescriptorVersionService entityDescriptorVersionService(EntityDescriptorService entityDescriptorService) {
return new EnversEntityDescriptorVersionService(entityManager, entityDescriptorService);
return new EnversEntityDescriptorVersionService(enversVersionServiceSupport(), entityDescriptorService);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package edu.internet2.tier.shibboleth.admin.ui.domain;

import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
Expand All @@ -16,13 +18,19 @@
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;


@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@EqualsAndHashCode
@EqualsAndHashCode(exclude = {"current"})
@Audited
public abstract class AbstractAuditable implements Auditable {

Expand All @@ -48,6 +56,9 @@ public abstract class AbstractAuditable implements Auditable {
@LastModifiedBy
private String modifiedBy;

@Transient
@JsonProperty
private boolean current;

@Override
public Long getAudId() {
Expand Down Expand Up @@ -94,4 +105,28 @@ public String getModifiedBy() {
public void setModifiedBy(String modifiedBy) {
this.modifiedBy = modifiedBy;
}

public ZonedDateTime createdDateAsZonedDateTime() {
return toZonedDateTime(this.createdDate);
}

public ZonedDateTime modifiedDateAsZonedDateTime() {
return toZonedDateTime(this.modifiedDate);
}

public boolean isCurrent() {
return this.current;
}

public void markAsCurrent() {
this.current = true;
}

private static ZonedDateTime toZonedDateTime(LocalDateTime localDateTime) {
return localDateTime
.atZone(ZoneId.systemDefault())
.toInstant()
.atOffset(ZoneOffset.UTC)
.toZonedDateTime();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package edu.internet2.tier.shibboleth.admin.ui.domain.frontend;

import com.fasterxml.jackson.annotation.JsonProperty;

import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.time.LocalDateTime;
Expand Down Expand Up @@ -64,6 +66,9 @@ public EntityDescriptorRepresentation(String id,

private String createdBy;

@JsonProperty
private boolean current;

public String getId() {
return id;
}
Expand Down Expand Up @@ -112,6 +117,7 @@ public void setMdui(MduiRepresentation mdui) {
this.mdui = mdui;
}


public ServiceProviderSsoDescriptorRepresentation getServiceProviderSsoDescriptor() {
return this.getServiceProviderSsoDescriptor(false);
}
Expand Down Expand Up @@ -213,4 +219,12 @@ public String getCreatedBy() {
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}

public boolean isCurrent() {
return current;
}

public void setCurrent(boolean current) {
this.current = current;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package edu.internet2.tier.shibboleth.admin.ui.envers;

import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractAuditable;
import edu.internet2.tier.shibboleth.admin.ui.domain.versioning.Version;
import org.hibernate.envers.AuditReaderFactory;
import org.hibernate.envers.query.AuditEntity;
Expand Down Expand Up @@ -31,14 +32,10 @@ public List<Version> findVersionsForPersistentEntity(String resourceId, Class<?>
.getResultList();

Object listOfVersions = revs.stream()
.map(it -> ((Object[]) it)[1])
.map(it -> {
return new Version(((PrincipalAwareRevisionEntity) it).idAsString(),
((PrincipalAwareRevisionEntity) it).getPrincipalUserName(),
((PrincipalAwareRevisionEntity) it).getRevisionDate()
.toInstant()
.atOffset(ZoneOffset.UTC)
.toZonedDateTime());
return new Version(((PrincipalAwareRevisionEntity) ((Object[]) it)[1]).idAsString(),
((AbstractAuditable) ((Object[]) it)[0]).getModifiedBy(),
((AbstractAuditable) ((Object[]) it)[0]).modifiedDateAsZonedDateTime());
})
.sorted(comparing(Version::getDate))
.collect(toList());
Expand All @@ -48,14 +45,30 @@ public List<Version> findVersionsForPersistentEntity(String resourceId, Class<?>

public Object findSpecificVersionOfPersistentEntity(String resourceId, String versionId, Class<?> entityClass) {
try {
return AuditReaderFactory.get(entityManager).createQuery()
AbstractAuditable abstractAuditable =
(AbstractAuditable) AuditReaderFactory.get(entityManager).createQuery()
.forEntitiesAtRevision(entityClass, Integer.valueOf(versionId))
.add(AuditEntity.property("resourceId").eq(resourceId))
.add(AuditEntity.revisionNumber().eq(Integer.valueOf(versionId)))
.getSingleResult();
}
catch (NoResultException e) {
if(isCurrentRevision(resourceId, versionId, entityClass)) {
abstractAuditable.markAsCurrent();
}
return abstractAuditable;
} catch (NoResultException e) {
return null;
}
}

private boolean isCurrentRevision(String resourceId, String versionId, Class<?> entityClass) {
Number revision = (Number) AuditReaderFactory
.get(entityManager)
.createQuery()
.forRevisionsOfEntity(entityClass, false, false)
.addProjection(AuditEntity.revisionNumber().max())
.add(AuditEntity.property("resourceId").eq(resourceId))
.getSingleResult();

return Integer.valueOf(versionId) == revision.intValue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import lombok.Getter;
import lombok.Setter;
import org.hibernate.envers.DefaultRevisionEntity;
import org.hibernate.envers.DefaultTrackingModifiedEntitiesRevisionEntity;
import org.hibernate.envers.RevisionEntity;

Expand Down
Loading

0 comments on commit a564b53

Please sign in to comment.