Skip to content

Commit

Permalink
SHIBUI-742 Resolved merge conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
rmathis committed Aug 8, 2018
2 parents 19ea8cc + 1da1d75 commit f1fe130
Show file tree
Hide file tree
Showing 18 changed files with 318 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class JPAMetadataResolverServiceImpl implements MetadataResolverService {
@Autowired
private OpenSamlObjects openSamlObjects

@Autowired
private MetadataResolversPositionOrderContainerService resolversPositionOrderContainerService

// TODO: enhance
@Override
void reloadFilters(String metadataResolverName) {
Expand Down Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -162,4 +165,14 @@ public void addInterceptors(InterceptorRegistry registry) {
}
};
}

@Bean
public MetadataResolversPositionOrderContainerService
metadataResolversPositionOrderContainerService(MetadataResolversPositionOrderContainerRepository
positionOrderContainerRepository,
MetadataResolverRepository resolverRepository) {

return new DefaultMetadataResolversPositionOrderContainerService(positionOrderContainerRepository, resolverRepository);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -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()));
Expand All @@ -55,7 +60,7 @@ public ResponseEntity<?> unableToParseJson(Exception ex) {
@GetMapping("/MetadataResolvers")
@Transactional(readOnly = true)
public ResponseEntity<?> getAll() {
Iterable<MetadataResolver> resolvers = resolverRepository.findAll();
List<MetadataResolver> resolvers = positionOrderContainerService.getAllMetadataResolversInDefinedOrderOrUnordered();
resolvers.forEach(MetadataResolver::updateVersion);
return ResponseEntity.ok(resolvers);
}
Expand Down Expand Up @@ -99,6 +104,7 @@ public ResponseEntity<?> create(@RequestBody MetadataResolver newResolver) {

newResolver.convertFiltersFromTransientRepresentationIfNecessary();
MetadataResolver persistedResolver = resolverRepository.save(newResolver);
positionOrderContainerService.appendPositionOrderForNew(persistedResolver);
persistedResolver.updateVersion();

persistedResolver.convertFiltersIntoTransientRepresentationIfNecessary();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package edu.internet2.tier.shibboleth.admin.ui.controller;


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.GetMapping;
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 {

@Autowired
MetadataResolversPositionOrderContainerService positionOrderContainerService;

@PostMapping
public ResponseEntity<?> createOrUpdate(@RequestBody MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer) {
positionOrderContainerService.addOrUpdatePositionOrderContainer(metadataResolversPositionOrderContainer);
return ResponseEntity.noContent().build();
}

@GetMapping
public ResponseEntity<?> getPositionOrderContainer() {
return ResponseEntity.ok(positionOrderContainerService.retrieveExistingOrEmpty());
}
}
Original file line number Diff line number Diff line change
@@ -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 {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package edu.internet2.tier.shibboleth.admin.ui.domain.resolvers;

import com.fasterxml.jackson.annotation.JsonIgnore;
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.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
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 {

@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"))
@Column(name="METADATA_RESOLVER_RESOURCE_ID")
@OrderColumn
private List<String> resourceIds = new ArrayList<>();
}
Original file line number Diff line number Diff line change
@@ -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<MetadataResolversPositionOrderContainer, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
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 org.springframework.transaction.annotation.Transactional;

import java.util.Iterator;
import java.util.List;
import java.util.Optional;

import static com.google.common.collect.FluentIterable.from;
import static java.util.stream.Collectors.toList;


/**
* Default implementation of {@link MetadataResolversPositionOrderContainer}.
*
* @author Dmitriy Kopylenko
*/
public class DefaultMetadataResolversPositionOrderContainerService implements MetadataResolversPositionOrderContainerService {

private MetadataResolversPositionOrderContainerRepository positionOrderContainerRepository;

private MetadataResolverRepository metadataResolverRepository;

public DefaultMetadataResolversPositionOrderContainerService(MetadataResolversPositionOrderContainerRepository positionOrderRepository,
MetadataResolverRepository metadataResolverRepository) {
this.positionOrderContainerRepository = positionOrderRepository;
this.metadataResolverRepository = metadataResolverRepository;
}

@Override
@Transactional
public void addOrUpdatePositionOrderContainer(MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer) {
MetadataResolversPositionOrderContainer existingPositionOrder = getPositionOrderContainerIfExists().orElse(null);
if (existingPositionOrder != null) {
existingPositionOrder.setResourceIds(metadataResolversPositionOrderContainer.getResourceIds());
positionOrderContainerRepository.save(existingPositionOrder);
return;
}
positionOrderContainerRepository.save(metadataResolversPositionOrderContainer);
}

@Override
@Transactional(readOnly = true)
public List<MetadataResolver> getAllMetadataResolversInDefinedOrderOrUnordered() {
Optional<MetadataResolversPositionOrderContainer> orderContainer = getPositionOrderContainerIfExists();
if(orderContainer.isPresent()) {
return orderContainer.get().getResourceIds()
.stream()
.map(metadataResolverRepository::findByResourceId)
.collect(toList());
}

return from(metadataResolverRepository.findAll()).toList();
}

@Override
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<MetadataResolversPositionOrderContainer> getPositionOrderContainerIfExists() {
Iterator<MetadataResolversPositionOrderContainer> iter = positionOrderContainerRepository.findAll().iterator();
return iter.hasNext() ? Optional.of(iter.next()) : Optional.empty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
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.List;

/**
* Service interface for manipulation of instances of {@link MetadataResolversPositionOrderContainer} and
* to abstract away MetadataResolvers ordering logic.
*
* @author Dmitriy Kopylenko
*/
public interface MetadataResolversPositionOrderContainerService {

MetadataResolversPositionOrderContainer retrieveExistingOrEmpty();

void addOrUpdatePositionOrderContainer(MetadataResolversPositionOrderContainer metadataResolversPositionOrderContainer);

List<MetadataResolver> getAllMetadataResolversInDefinedOrderOrUnordered();

void appendPositionOrderForNew(MetadataResolver metadataResolver);
}
Original file line number Diff line number Diff line change
@@ -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'

}
}
2 changes: 1 addition & 1 deletion ui/src/app/metadata/filter/effect/filter.effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export class FilterEffects {
)
);

@Effect({dispatch: false})
@Effect({ dispatch: false })
cancelChanges$ = this.actions$.pipe(
ofType<CancelCreateFilter>(FilterActionTypes.CANCEL_CREATE_FILTER),
combineLatest(this.store.select(fromProvider.getSelectedProviderId).pipe(skipWhile(id => !id))),
Expand Down
2 changes: 1 addition & 1 deletion ui/src/app/metadata/provider/action/collection.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class LoadProviderError implements Action {
export class SelectProviderRequest implements Action {
readonly type = ProviderCollectionActionTypes.SELECT_PROVIDER_REQUEST;

constructor(public payload: any) { }
constructor(public payload: string) { }
}

export class SelectProviderSuccess implements Action {
Expand Down
Loading

0 comments on commit f1fe130

Please sign in to comment.