From 017746cfc310f0766ada3da2979d316e8482c971 Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Wed, 25 Jul 2018 10:42:12 -0400 Subject: [PATCH] SHIBUI-645: Implement ordering SPI --- .../JPAMetadataResolverServiceImpl.groovy | 10 +++- .../CoreShibUiConfiguration.java | 13 +++++ ...esolversPositionOrderContainerService.java | 42 +++++++++++++-- ...esolversPositionOrderContainerService.java | 12 +++-- ...sPositionOrderContainerServiceTests.groovy | 53 +++++++++++++++++++ 5 files changed, 121 insertions(+), 9 deletions(-) create mode 100644 backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolversPositionOrderContainerServiceTests.groovy diff --git a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy index b60c9b0c8..f63dbad31 100644 --- a/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy +++ b/backend/src/main/groovy/edu/internet2/tier/shibboleth/admin/ui/service/JPAMetadataResolverServiceImpl.groovy @@ -43,6 +43,9 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { @Autowired private OpenSamlObjects openSamlObjects + @Autowired + private MetadataResolversPositionOrderContainerService resolversPositionOrderContainerService + // TODO: enhance @Override void reloadFilters(String metadataResolverName) { @@ -98,8 +101,11 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService { 'xsi:type': 'ChainingMetadataProvider', 'xsi:schemaLocation': 'urn:mace:shibboleth:2.0:metadata http://shibboleth.net/schema/idp/shibboleth-metadata.xsd urn:mace:shibboleth:2.0:resource http://shibboleth.net/schema/idp/shibboleth-resource.xsd urn:mace:shibboleth:2.0:security http://shibboleth.net/schema/idp/shibboleth-security.xsd urn:oasis:names:tc:SAML:2.0:metadata http://docs.oasis-open.org/security/saml/v2.0/saml-schema-metadata-2.0.xsd urn:oasis:names:tc:SAML:2.0:assertion http://docs.oasis-open.org/security/saml/v2.0/saml-schema-assertion-2.0.xsd' ) { - metadataResolverRepository.findAll().each { edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver mr -> - //TODO: We cannot/do not currently have the code to marshall the internal incommon chaining resolver + + + resolversPositionOrderContainerService.allMetadataResolversInDefinedOrderOrUnordered.each { + edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver mr -> + //TODO: We do not currently marshall the internal incommon chaining resolver (with BaseMetadataResolver type) if ((mr.type != 'BaseMetadataResolver') && (mr.enabled)) { constructXmlNodeForResolver(mr, delegate) { MetadataFilter( diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java index ca7be77ea..c630752f8 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/CoreShibUiConfiguration.java @@ -1,8 +1,11 @@ package edu.internet2.tier.shibboleth.admin.ui.configuration; import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityIdsSearchResultRepresentation; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolversPositionOrderContainer; import edu.internet2.tier.shibboleth.admin.ui.opensaml.OpenSamlObjects; 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.MetadataResolversPositionOrderContainerRepository; import edu.internet2.tier.shibboleth.admin.ui.scheduled.EntityDescriptorFilesScheduledTasks; import edu.internet2.tier.shibboleth.admin.ui.service.*; import edu.internet2.tier.shibboleth.admin.util.AttributeUtility; @@ -162,4 +165,14 @@ public void addInterceptors(InterceptorRegistry registry) { } }; } + + @Bean + public MetadataResolversPositionOrderContainerService + metadataResolversPositionOrderContainerService(MetadataResolversPositionOrderContainerRepository + positionOrderContainerRepository, + MetadataResolverRepository resolverRepository) { + + return new DefaultMetadataResolversPositionOrderContainerService(positionOrderContainerRepository, resolverRepository); + + } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DefaultMetadataResolversPositionOrderContainerService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DefaultMetadataResolversPositionOrderContainerService.java index bfbe70e0d..7e1e63396 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DefaultMetadataResolversPositionOrderContainerService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DefaultMetadataResolversPositionOrderContainerService.java @@ -1,18 +1,54 @@ package edu.internet2.tier.shibboleth.admin.ui.service; +import com.google.common.collect.Lists; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver; import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolversPositionOrderContainer; +import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository; +import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolversPositionOrderContainerRepository; +import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; +import static java.util.stream.Collectors.toList; + + public class DefaultMetadataResolversPositionOrderContainerService implements MetadataResolversPositionOrderContainerService { - @Override - public Optional getPositionOrderContainerIfExists() { - return Optional.empty(); + private MetadataResolversPositionOrderContainerRepository positionOrderContainerRepository; + + private MetadataResolverRepository metadataResolverRepository; + + public DefaultMetadataResolversPositionOrderContainerService(MetadataResolversPositionOrderContainerRepository positionOrderRepository, + MetadataResolverRepository metadataResolverRepository) { + this.positionOrderContainerRepository = positionOrderRepository; + this.metadataResolverRepository = metadataResolverRepository; } @Override + @Transactional public void persistPositionOrderContainer(MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer) { + positionOrderContainerRepository.save(metadataResolversPositionOrderContainer); + } + + @Override + @Transactional(readOnly = true) + public List getAllMetadataResolversInDefinedOrderOrUnordered() { + Optional orderContainer = getPositionOrderContainerIfExists(); + if(orderContainer.isPresent()) { + return orderContainer.get().getResourceIds() + .stream() + .map(metadataResolverRepository::findByResourceId) + .collect(toList()); + } + + return Lists.newArrayList(metadataResolverRepository.findAll()); + } + private Optional getPositionOrderContainerIfExists() { + return positionOrderContainerRepository.findAll().iterator().hasNext() + ? Optional.of(positionOrderContainerRepository.findAll().iterator().next()) + : Optional.empty(); } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolversPositionOrderContainerService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolversPositionOrderContainerService.java index 52ffaeba1..d3e3da40f 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolversPositionOrderContainerService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolversPositionOrderContainerService.java @@ -1,17 +1,21 @@ package edu.internet2.tier.shibboleth.admin.ui.service; +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver; import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolversPositionOrderContainer; -import java.util.Optional; +import java.util.List; /** - * Service interface for manipulation of instances of {@link MetadataResolversPositionOrderContainer}. + * Service interface for manipulation of instances of {@link MetadataResolversPositionOrderContainer} and + * encapsulate MetadataResolvers ordering logic. * * @author Dmitriy Kopylenko */ public interface MetadataResolversPositionOrderContainerService { - Optional getPositionOrderContainerIfExists(); - void persistPositionOrderContainer(MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer); + + List getAllMetadataResolversInDefinedOrderOrUnordered(); + + } diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolversPositionOrderContainerServiceTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolversPositionOrderContainerServiceTests.groovy new file mode 100644 index 000000000..de4af7e8e --- /dev/null +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolversPositionOrderContainerServiceTests.groovy @@ -0,0 +1,53 @@ +package edu.internet2.tier.shibboleth.admin.ui.service + +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolver +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolversPositionOrderContainer +import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository +import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolversPositionOrderContainerRepository +import spock.lang.Specification +import spock.lang.Subject + +/** + * @author Dmitriy Kopylenko + */ +class MetadataResolversPositionOrderContainerServiceTests extends Specification { + + def "no order container has been provided and saved, so using unordered persisted resolvers"() { + given: + def resolverRepo = Mock(MetadataResolverRepository) + resolverRepo.findAll() >> [new MetadataResolver(resourceId: 'second'), new MetadataResolver(resourceId: 'first')] + def positionOrderRepo = Mock(MetadataResolversPositionOrderContainerRepository) + positionOrderRepo.findAll() >> [] + @Subject + def positionContainerSvc = new DefaultMetadataResolversPositionOrderContainerService(positionOrderRepo, resolverRepo) + + when: + def unorderedResolvers = positionContainerSvc.getAllMetadataResolversInDefinedOrderOrUnordered() + + then: + unorderedResolvers[0].resourceId == 'second' + unorderedResolvers[1].resourceId == 'first' + + } + + def "an order container has been provided and saved, so using resolvers with order defined in that position order container"() { + given: + def resolverRepo = Mock(MetadataResolverRepository) + resolverRepo.findAll() >> [new MetadataResolver(resourceId: 'second'), new MetadataResolver(resourceId: 'first')] + resolverRepo.findByResourceId('first') >> new MetadataResolver(resourceId: 'first') + resolverRepo.findByResourceId('second') >> new MetadataResolver(resourceId: 'second') + def positionOrderRepo = Mock(MetadataResolversPositionOrderContainerRepository) + positionOrderRepo.findAll() >> [new MetadataResolversPositionOrderContainer(resourceIds: ['first', 'second'])] + positionOrderRepo.findAll() >> [] + @Subject + def positionContainerSvc = new DefaultMetadataResolversPositionOrderContainerService(positionOrderRepo, resolverRepo) + + when: + def orderedResolvers = positionContainerSvc.getAllMetadataResolversInDefinedOrderOrUnordered() + + then: + orderedResolvers[0].resourceId == 'first' + orderedResolvers[1].resourceId == 'second' + + } +}