From b59210971fcaba732408f16edabd75263ca665be Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Tue, 24 Jul 2018 12:03:43 -0400 Subject: [PATCH 01/12] WIP1 --- .../resolvers/MetadataResolversOrderContainer.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversOrderContainer.java diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversOrderContainer.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversOrderContainer.java new file mode 100644 index 000000000..5b5d0d87f --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversOrderContainer.java @@ -0,0 +1,14 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers; + +/** + * This is a persistent entity abstraction encapsulating a collection of metadata resolver ids + * for the purpose of maintaining an order of all persistent metadata resolvers which becomes significant during + * generation of XML metadata for the resolvers. + * + * Maintaining this separate entity enables UI layer for example to explicitly manipulate ordering e.g. use REST + * API to reorder resolvers, etc. + * + * @author Dmitriy + */ +public class MetadataResolversOrderContainer { +} From ed1a7ea6da17ec48617930b555c0b229394d00b2 Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Tue, 24 Jul 2018 15:48:45 -0400 Subject: [PATCH 02/12] SHIBUI-645: WIP --- ...tadataResolversPositionOrderContainer.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversPositionOrderContainer.java diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversPositionOrderContainer.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversPositionOrderContainer.java new file mode 100644 index 000000000..63d62881a --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversPositionOrderContainer.java @@ -0,0 +1,42 @@ +package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers; + +import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractAuditable; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.OrderColumn; +import java.util.ArrayList; +import java.util.List; + +/** + * This is a persistent entity abstraction encapsulating a collection of metadata resolver ids + * for the purpose of maintaining an order of all persistent metadata resolvers which becomes significant during + * generation of XML metadata for the resolvers. + * + * Maintaining this separate entity enables UI layer for example to explicitly manipulate ordering e.g. use REST + * API to reorder resolvers, etc. + * + * @author Dmitriy Kopylenko + */ +@Entity +@EqualsAndHashCode +@NoArgsConstructor +@Getter +@Setter +@ToString +public class MetadataResolversPositionOrderContainer extends AbstractAuditable { + + @ElementCollection + @CollectionTable(name="METADATA_RESOLVER_POSITION_ORDER", joinColumns=@JoinColumn(name="METADATA_RESOLVER_POSITION_ORDER_CONTAINER_ID")) + @Column(name="METADATA_RESOLVER_RESOURCE_ID") + @OrderColumn + private List resourceIds = new ArrayList<>(); +} From 9a9a50648075692d23303fba5e1a39b03e7f8a3e Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Tue, 24 Jul 2018 15:48:56 -0400 Subject: [PATCH 03/12] SHIBUI-645: WIP --- ...olversPositionOrderContainerRepository.java | 13 +++++++++++++ ...ResolversPositionOrderContainerService.java | 18 ++++++++++++++++++ ...ResolversPositionOrderContainerService.java | 17 +++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/MetadataResolversPositionOrderContainerRepository.java create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DefaultMetadataResolversPositionOrderContainerService.java create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolversPositionOrderContainerService.java diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/MetadataResolversPositionOrderContainerRepository.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/MetadataResolversPositionOrderContainerRepository.java new file mode 100644 index 000000000..6afe35ded --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/repository/MetadataResolversPositionOrderContainerRepository.java @@ -0,0 +1,13 @@ +package edu.internet2.tier.shibboleth.admin.ui.repository; + +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolversPositionOrderContainer; +import org.springframework.data.repository.CrudRepository; + +/** + * Spring Data Repository API for persistence operations on instances of {@link MetadataResolversPositionOrderContainer}. + * + * @author Dmitriy Kopylenko + */ +public interface MetadataResolversPositionOrderContainerRepository + extends CrudRepository { +} 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 new file mode 100644 index 000000000..bfbe70e0d --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/DefaultMetadataResolversPositionOrderContainerService.java @@ -0,0 +1,18 @@ +package edu.internet2.tier.shibboleth.admin.ui.service; + +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolversPositionOrderContainer; + +import java.util.Optional; + +public class DefaultMetadataResolversPositionOrderContainerService implements MetadataResolversPositionOrderContainerService { + + @Override + public Optional getPositionOrderContainerIfExists() { + return Optional.empty(); + } + + @Override + public void persistPositionOrderContainer(MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer) { + + } +} 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 new file mode 100644 index 000000000..52ffaeba1 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/MetadataResolversPositionOrderContainerService.java @@ -0,0 +1,17 @@ +package edu.internet2.tier.shibboleth.admin.ui.service; + +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolversPositionOrderContainer; + +import java.util.Optional; + +/** + * Service interface for manipulation of instances of {@link MetadataResolversPositionOrderContainer}. + * + * @author Dmitriy Kopylenko + */ +public interface MetadataResolversPositionOrderContainerService { + + Optional getPositionOrderContainerIfExists(); + + void persistPositionOrderContainer(MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer); +} From 017746cfc310f0766ada3da2979d316e8482c971 Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Wed, 25 Jul 2018 10:42:12 -0400 Subject: [PATCH 04/12] 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' + + } +} From 0e8b039a119279fed87539508a2afee2027ec52a Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Wed, 25 Jul 2018 10:44:15 -0400 Subject: [PATCH 05/12] Polishing --- .../DefaultMetadataResolversPositionOrderContainerService.java | 1 - 1 file changed, 1 deletion(-) 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 7e1e63396..efeb8fc69 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 @@ -7,7 +7,6 @@ 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; From 69e63dd0153e08980e15a5ebb8be7cc32b754c7f Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Wed, 25 Jul 2018 10:45:21 -0400 Subject: [PATCH 06/12] Polishing --- .../resolvers/MetadataResolversPositionOrderContainer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversPositionOrderContainer.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversPositionOrderContainer.java index 63d62881a..7e17b78ec 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversPositionOrderContainer.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversPositionOrderContainer.java @@ -27,7 +27,7 @@ * @author Dmitriy Kopylenko */ @Entity -@EqualsAndHashCode +@EqualsAndHashCode(callSuper = true) @NoArgsConstructor @Getter @Setter From e7418982a52a865a576c70ac026af1dc61fc475b Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Wed, 25 Jul 2018 10:48:21 -0400 Subject: [PATCH 07/12] Polishing --- .../MetadataResolversPositionOrderContainerService.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 d3e3da40f..0cf833559 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 @@ -7,7 +7,7 @@ /** * Service interface for manipulation of instances of {@link MetadataResolversPositionOrderContainer} and - * encapsulate MetadataResolvers ordering logic. + * to abstract away MetadataResolvers ordering logic. * * @author Dmitriy Kopylenko */ @@ -16,6 +16,4 @@ public interface MetadataResolversPositionOrderContainerService { void persistPositionOrderContainer(MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer); List getAllMetadataResolversInDefinedOrderOrUnordered(); - - } From 9518c7d62289ee17bfd997e63ffd631d9e7ad711 Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Wed, 25 Jul 2018 10:56:50 -0400 Subject: [PATCH 08/12] SHIBUI-645: use immutable list --- ...DefaultMetadataResolversPositionOrderContainerService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 efeb8fc69..57fd8756c 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,6 +1,5 @@ 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; @@ -10,6 +9,7 @@ import java.util.List; import java.util.Optional; +import static com.google.common.collect.FluentIterable.from; import static java.util.stream.Collectors.toList; @@ -42,7 +42,7 @@ public List getAllMetadataResolversInDefinedOrderOrUnordered() .collect(toList()); } - return Lists.newArrayList(metadataResolverRepository.findAll()); + return from(metadataResolverRepository.findAll()).toList(); } private Optional getPositionOrderContainerIfExists() { From b61cd31e0ac23a34146f813722360837a73e7932 Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Wed, 25 Jul 2018 16:05:28 -0400 Subject: [PATCH 09/12] SHIBUI-645: Implement REST API WIP --- ...adataResolversPositionOrderController.java | 22 +++++++++++++++++++ ...esolversPositionOrderContainerService.java | 13 ++++++++++- ...esolversPositionOrderContainerService.java | 2 +- 3 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java new file mode 100644 index 000000000..51680e753 --- /dev/null +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java @@ -0,0 +1,22 @@ +package edu.internet2.tier.shibboleth.admin.ui.controller; + + +import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolversPositionOrderContainer; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author Dmitriy Kopylenko + */ +@RestController +@RequestMapping("/api/MetadataResolversPositionOrder") +public class MetadataResolversPositionOrderController { + + @PostMapping + public ResponseEntity createOrUpdate(@RequestBody MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer) { + return ResponseEntity.ok().build(); + } +} 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 57fd8756c..4da7c4031 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 @@ -13,6 +13,11 @@ import static java.util.stream.Collectors.toList; +/** + * Default implementation of {@link MetadataResolversPositionOrderContainer}. + * + * @author Dmitriy Kopylenko + */ public class DefaultMetadataResolversPositionOrderContainerService implements MetadataResolversPositionOrderContainerService { private MetadataResolversPositionOrderContainerRepository positionOrderContainerRepository; @@ -27,7 +32,13 @@ public DefaultMetadataResolversPositionOrderContainerService(MetadataResolversPo @Override @Transactional - public void persistPositionOrderContainer(MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer) { + public void addOrUpdatePositionOrderContainer(MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer) { + MetadataResolversPositionOrderContainer existingPositionOrder = positionOrderContainerRepository.findAll().iterator().next(); + if (existingPositionOrder != null) { + existingPositionOrder.setResourceIds(metadataResolversPositionOrderContainer.getResourceIds()); + positionOrderContainerRepository.save(existingPositionOrder); + return; + } positionOrderContainerRepository.save(metadataResolversPositionOrderContainer); } 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 0cf833559..1fc06ee81 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 @@ -13,7 +13,7 @@ */ public interface MetadataResolversPositionOrderContainerService { - void persistPositionOrderContainer(MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer); + void addOrUpdatePositionOrderContainer(MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer); List getAllMetadataResolversInDefinedOrderOrUnordered(); } From 975061f80aad851175779412981007e24ff4a692 Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Wed, 25 Jul 2018 16:48:40 -0400 Subject: [PATCH 10/12] SHIBUI-645: WIP --- .../admin/ui/controller/MetadataResolversController.java | 7 ++++++- .../MetadataResolversPositionOrderController.java | 8 +++++++- ...ultMetadataResolversPositionOrderContainerService.java | 8 ++++---- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java index 9705ddacc..c6b648e8c 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java @@ -5,6 +5,7 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolverValidationService; import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolverRepository; import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolverService; +import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolversPositionOrderContainerService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -30,6 +31,7 @@ import java.io.IOException; import java.io.StringWriter; import java.net.URI; +import java.util.List; import static edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolverValidator.ValidationResult; @@ -47,6 +49,9 @@ public class MetadataResolversController { @Autowired MetadataResolverService metadataResolverService; + @Autowired + MetadataResolversPositionOrderContainerService positionOrderContainerService; + @ExceptionHandler({InvalidTypeIdException.class, IOException.class, HttpMessageNotReadableException.class}) public ResponseEntity unableToParseJson(Exception ex) { return ResponseEntity.badRequest().body(new ErrorResponse(HttpStatus.BAD_REQUEST.toString(), ex.getMessage())); @@ -55,7 +60,7 @@ public ResponseEntity unableToParseJson(Exception ex) { @GetMapping("/MetadataResolvers") @Transactional(readOnly = true) public ResponseEntity getAll() { - Iterable resolvers = resolverRepository.findAll(); + List resolvers = positionOrderContainerService.getAllMetadataResolversInDefinedOrderOrUnordered(); resolvers.forEach(MetadataResolver::updateVersion); return ResponseEntity.ok(resolvers); } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java index 51680e753..ed3344e1c 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java @@ -2,6 +2,8 @@ import edu.internet2.tier.shibboleth.admin.ui.domain.resolvers.MetadataResolversPositionOrderContainer; +import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolversPositionOrderContainerService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -15,8 +17,12 @@ @RequestMapping("/api/MetadataResolversPositionOrder") public class MetadataResolversPositionOrderController { + @Autowired + MetadataResolversPositionOrderContainerService positionOrderContainerService; + @PostMapping public ResponseEntity createOrUpdate(@RequestBody MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer) { - return ResponseEntity.ok().build(); + this.positionOrderContainerService.addOrUpdatePositionOrderContainer(metadataResolversPositionOrderContainer); + return ResponseEntity.noContent().build(); } } 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 4da7c4031..37b6b7c09 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 @@ -6,6 +6,7 @@ import edu.internet2.tier.shibboleth.admin.ui.repository.MetadataResolversPositionOrderContainerRepository; import org.springframework.transaction.annotation.Transactional; +import java.util.Iterator; import java.util.List; import java.util.Optional; @@ -33,7 +34,7 @@ public DefaultMetadataResolversPositionOrderContainerService(MetadataResolversPo @Override @Transactional public void addOrUpdatePositionOrderContainer(MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer) { - MetadataResolversPositionOrderContainer existingPositionOrder = positionOrderContainerRepository.findAll().iterator().next(); + MetadataResolversPositionOrderContainer existingPositionOrder = getPositionOrderContainerIfExists().orElse(null); if (existingPositionOrder != null) { existingPositionOrder.setResourceIds(metadataResolversPositionOrderContainer.getResourceIds()); positionOrderContainerRepository.save(existingPositionOrder); @@ -57,8 +58,7 @@ public List getAllMetadataResolversInDefinedOrderOrUnordered() } private Optional getPositionOrderContainerIfExists() { - return positionOrderContainerRepository.findAll().iterator().hasNext() - ? Optional.of(positionOrderContainerRepository.findAll().iterator().next()) - : Optional.empty(); + Iterator iter = positionOrderContainerRepository.findAll().iterator(); + return iter.hasNext() ? Optional.of(iter.next()) : Optional.empty(); } } From bbbf4ca8f596b9ea5d6a6a3ff4171b2c7a3f1718 Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Fri, 27 Jul 2018 11:10:44 -0400 Subject: [PATCH 11/12] SHIBUI-645: Controller implementation --- .../MetadataResolversPositionOrderController.java | 8 +++++++- .../MetadataResolversPositionOrderContainer.java | 14 +++++++++++--- ...dataResolversPositionOrderContainerService.java | 5 +++++ ...dataResolversPositionOrderContainerService.java | 2 ++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java index ed3344e1c..ab78e4a52 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversPositionOrderController.java @@ -5,6 +5,7 @@ import edu.internet2.tier.shibboleth.admin.ui.service.MetadataResolversPositionOrderContainerService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -22,7 +23,12 @@ public class MetadataResolversPositionOrderController { @PostMapping public ResponseEntity createOrUpdate(@RequestBody MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer) { - this.positionOrderContainerService.addOrUpdatePositionOrderContainer(metadataResolversPositionOrderContainer); + positionOrderContainerService.addOrUpdatePositionOrderContainer(metadataResolversPositionOrderContainer); return ResponseEntity.noContent().build(); } + + @GetMapping + public ResponseEntity getPositionOrderContainer() { + return ResponseEntity.ok(positionOrderContainerService.retrieveExistingOrEmpty()); + } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversPositionOrderContainer.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversPositionOrderContainer.java index 7e17b78ec..883069531 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversPositionOrderContainer.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/domain/resolvers/MetadataResolversPositionOrderContainer.java @@ -1,6 +1,6 @@ package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers; -import edu.internet2.tier.shibboleth.admin.ui.domain.AbstractAuditable; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; @@ -11,6 +11,9 @@ import javax.persistence.Column; import javax.persistence.ElementCollection; import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OrderColumn; import java.util.ArrayList; @@ -27,12 +30,17 @@ * @author Dmitriy Kopylenko */ @Entity -@EqualsAndHashCode(callSuper = true) +@EqualsAndHashCode @NoArgsConstructor @Getter @Setter @ToString -public class MetadataResolversPositionOrderContainer extends AbstractAuditable { +public class MetadataResolversPositionOrderContainer { + + @Id + @GeneratedValue(strategy = GenerationType.SEQUENCE) + @JsonIgnore + protected Long id; @ElementCollection @CollectionTable(name="METADATA_RESOLVER_POSITION_ORDER", joinColumns=@JoinColumn(name="METADATA_RESOLVER_POSITION_ORDER_CONTAINER_ID")) 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 37b6b7c09..07128f5d0 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 @@ -57,6 +57,11 @@ public List getAllMetadataResolversInDefinedOrderOrUnordered() return from(metadataResolverRepository.findAll()).toList(); } + @Override + public MetadataResolversPositionOrderContainer retrieveExistingOrEmpty() { + return getPositionOrderContainerIfExists().orElseGet(MetadataResolversPositionOrderContainer::new); + } + private Optional getPositionOrderContainerIfExists() { Iterator iter = positionOrderContainerRepository.findAll().iterator(); return iter.hasNext() ? Optional.of(iter.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 1fc06ee81..3b67f6018 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 @@ -13,6 +13,8 @@ */ public interface MetadataResolversPositionOrderContainerService { + MetadataResolversPositionOrderContainer retrieveExistingOrEmpty(); + void addOrUpdatePositionOrderContainer(MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer); List getAllMetadataResolversInDefinedOrderOrUnordered(); From a55b424af99db8319c41fa381dbff552ccb332bc Mon Sep 17 00:00:00 2001 From: Dmitriy Kopylenko Date: Fri, 27 Jul 2018 15:44:37 -0400 Subject: [PATCH 12/12] SHIBUI-645: handle default position order when persisting new metadata resolvers --- .../admin/ui/controller/MetadataResolversController.java | 1 + ...ultMetadataResolversPositionOrderContainerService.java | 8 ++++++++ .../MetadataResolversPositionOrderContainerService.java | 2 ++ 3 files changed, 11 insertions(+) diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java index c6b648e8c..2b1ddc6b5 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/controller/MetadataResolversController.java @@ -104,6 +104,7 @@ public ResponseEntity create(@RequestBody MetadataResolver newResolver) { newResolver.convertFiltersFromTransientRepresentationIfNecessary(); MetadataResolver persistedResolver = resolverRepository.save(newResolver); + positionOrderContainerService.appendPositionOrderForNew(persistedResolver); persistedResolver.updateVersion(); persistedResolver.convertFiltersIntoTransientRepresentationIfNecessary(); 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 07128f5d0..76ac86cea 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 @@ -62,6 +62,14 @@ public MetadataResolversPositionOrderContainer retrieveExistingOrEmpty() { return getPositionOrderContainerIfExists().orElseGet(MetadataResolversPositionOrderContainer::new); } + @Override + @Transactional + public void appendPositionOrderForNew(MetadataResolver metadataResolver) { + MetadataResolversPositionOrderContainer positionOrderContainer = retrieveExistingOrEmpty(); + positionOrderContainer.getResourceIds().add(metadataResolver.getResourceId()); + positionOrderContainerRepository.save(positionOrderContainer); + } + private Optional getPositionOrderContainerIfExists() { Iterator iter = positionOrderContainerRepository.findAll().iterator(); return iter.hasNext() ? Optional.of(iter.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 3b67f6018..7de6490af 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 @@ -18,4 +18,6 @@ public interface MetadataResolversPositionOrderContainerService { void addOrUpdatePositionOrderContainer(MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer); List getAllMetadataResolversInDefinedOrderOrUnordered(); + + void appendPositionOrderForNew(MetadataResolver metadataResolver); }