diff --git a/judge-d-server/src/main/java/dev/hltech/dredd/domain/ServiceVersion.java b/judge-d-server/src/main/java/dev/hltech/dredd/domain/ServiceVersion.java index 74510ec0..b903f19d 100644 --- a/judge-d-server/src/main/java/dev/hltech/dredd/domain/ServiceVersion.java +++ b/judge-d-server/src/main/java/dev/hltech/dredd/domain/ServiceVersion.java @@ -9,6 +9,7 @@ import javax.persistence.Access; import javax.persistence.AccessType; import javax.persistence.Embeddable; +import javax.persistence.MappedSuperclass; import java.io.Serializable; @@ -20,6 +21,7 @@ @AllArgsConstructor @NoArgsConstructor(access = PROTECTED) @Access(AccessType.FIELD) +@MappedSuperclass public class ServiceVersion implements Serializable { private String name; diff --git a/judge-d-server/src/main/java/dev/hltech/dredd/domain/environment/EnvironmentAggregate.java b/judge-d-server/src/main/java/dev/hltech/dredd/domain/environment/EnvironmentAggregate.java index 76c00f77..3710e41c 100644 --- a/judge-d-server/src/main/java/dev/hltech/dredd/domain/environment/EnvironmentAggregate.java +++ b/judge-d-server/src/main/java/dev/hltech/dredd/domain/environment/EnvironmentAggregate.java @@ -1,13 +1,14 @@ package dev.hltech.dredd.domain.environment; -import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import dev.hltech.dredd.domain.ServiceVersion; import javax.persistence.*; import java.util.Set; +import static com.google.common.collect.HashMultimap.create; import static com.google.common.collect.Sets.newHashSet; +import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toSet; @Entity @@ -15,33 +16,64 @@ @Access(AccessType.FIELD) public class EnvironmentAggregate { + public static final String DEFAULT_NAMESPACE = "default"; + @Id private String name; - @ElementCollection(fetch = FetchType.EAGER) + @ElementCollection(fetch = FetchType.EAGER, targetClass = SpaceServiceVersion.class ) @JoinTable(name = "service_versions", joinColumns = { @JoinColumn(name = "environment_name", referencedColumnName = "name"), }) - private Set serviceVersions; + private Set serviceVersions = newHashSet(); protected EnvironmentAggregate() { } - private EnvironmentAggregate(String name, Set serviceVersions) { + protected EnvironmentAggregate(String name, Set< ServiceVersion> deatulSpaceServiceVersions) { this.name = name; - this.serviceVersions = serviceVersions; + this.serviceVersions.addAll( + deatulSpaceServiceVersions + .stream() + .map(sv -> new SpaceServiceVersion(DEFAULT_NAMESPACE, sv.getName(), sv.getVersion())) + .collect(toList()) + ); + } + + private EnvironmentAggregate(String name, Multimap serviceVersions) { + this.name = name; + this.serviceVersions.addAll( + serviceVersions.entries() + .stream() + .map(e -> new SpaceServiceVersion(e.getKey(), e.getValue().getName(), e.getValue().getVersion())) + .collect(toList()) + ); } public String getName() { return this.name; } + public Set getSpaceNames() { + return serviceVersions.stream().map(SpaceServiceVersion::getSpace).collect(toSet()); + } + + public Set getServices(String space) { + return serviceVersions + .stream() + .filter(ssv -> ssv.getSpace().equals(space)) + .map(ssv -> new ServiceVersion(ssv.getName(), ssv.getVersion())) + .collect(toSet()); + } + public Set getAllServices() { - return this.serviceVersions; + return serviceVersions.stream() + .map(ssv -> new ServiceVersion(ssv.getName(), ssv.getVersion())) + .collect(toSet()); } public static EnvironmentAggregate empty(String environmentName) { - return new EnvironmentAggregate(environmentName, newHashSet()); + return new EnvironmentAggregate(environmentName, create()); } public static EnvironmentAggregateBuilder builder(String name) { @@ -51,23 +83,26 @@ public static EnvironmentAggregateBuilder builder(String name) { public static class EnvironmentAggregateBuilder { private String name; - private Multimap serviceVersions = HashMultimap.create(); + private Multimap serviceVersions = create(); private EnvironmentAggregateBuilder(String name) { this.name = name; } - public void withServiceVersion(String name, String version) { - this.serviceVersions.put(name, version); + public EnvironmentAggregateBuilder withServiceVersion(String name, String version) { + this.serviceVersions.put(DEFAULT_NAMESPACE, new ServiceVersion(name, version)); + return this; + } + + public EnvironmentAggregateBuilder withServiceVersions(String space, Set serviceVersions) { + this.serviceVersions.putAll(space, serviceVersions); + return this; } public EnvironmentAggregate build() { return new EnvironmentAggregate( this.name, - this.serviceVersions.entries() - .stream() - .map(e -> new ServiceVersion(e.getKey(), e.getValue())) - .collect(toSet()) + this.serviceVersions ); } diff --git a/judge-d-server/src/main/java/dev/hltech/dredd/domain/environment/JPAEnvironmentRepository.java b/judge-d-server/src/main/java/dev/hltech/dredd/domain/environment/JPAEnvironmentRepository.java index 2c20675a..0fafd4ad 100644 --- a/judge-d-server/src/main/java/dev/hltech/dredd/domain/environment/JPAEnvironmentRepository.java +++ b/judge-d-server/src/main/java/dev/hltech/dredd/domain/environment/JPAEnvironmentRepository.java @@ -17,7 +17,7 @@ public JPAEnvironmentRepository(SpringDataEnvironmentRepository springDataEnviro @Override public EnvironmentAggregate persist(EnvironmentAggregate environment) { - return springDataEnvironmentRepository.save(environment); + return springDataEnvironmentRepository.saveAndFlush(environment); } @Override diff --git a/judge-d-server/src/main/java/dev/hltech/dredd/domain/environment/SpaceServiceVersion.java b/judge-d-server/src/main/java/dev/hltech/dredd/domain/environment/SpaceServiceVersion.java new file mode 100644 index 00000000..929adbfd --- /dev/null +++ b/judge-d-server/src/main/java/dev/hltech/dredd/domain/environment/SpaceServiceVersion.java @@ -0,0 +1,29 @@ +package dev.hltech.dredd.domain.environment; + +import dev.hltech.dredd.domain.ServiceVersion; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.Access; +import javax.persistence.AccessType; +import javax.persistence.Embeddable; + +import static com.google.common.base.Preconditions.checkNotNull; +import static lombok.AccessLevel.PROTECTED; + +@Embeddable +@Getter +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor(access = PROTECTED) +@Access(AccessType.FIELD) +public class SpaceServiceVersion extends ServiceVersion { + + private String space; + + public SpaceServiceVersion(String space, String name, String version) { + super(name, version); + this.space = checkNotNull(space, "space name cannot be null"); + } + +} diff --git a/judge-d-server/src/main/java/dev/hltech/dredd/interfaces/rest/environment/EnvironmentController.java b/judge-d-server/src/main/java/dev/hltech/dredd/interfaces/rest/environment/EnvironmentController.java index 08a9c930..d825508a 100644 --- a/judge-d-server/src/main/java/dev/hltech/dredd/interfaces/rest/environment/EnvironmentController.java +++ b/judge-d-server/src/main/java/dev/hltech/dredd/interfaces/rest/environment/EnvironmentController.java @@ -1,6 +1,9 @@ package dev.hltech.dredd.interfaces.rest.environment; +import com.google.common.collect.ImmutableSet; +import dev.hltech.dredd.domain.ServiceVersion; import dev.hltech.dredd.domain.environment.EnvironmentAggregate; +import dev.hltech.dredd.domain.environment.EnvironmentAggregate.EnvironmentAggregateBuilder; import dev.hltech.dredd.domain.environment.EnvironmentRepository; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; @@ -12,7 +15,10 @@ import java.util.List; import java.util.Set; +import static com.google.common.base.MoreObjects.firstNonNull; +import static dev.hltech.dredd.domain.environment.EnvironmentAggregate.DEFAULT_NAMESPACE; import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toSet; @RestController public class EnvironmentController { @@ -50,9 +56,25 @@ public List getEnvironment(@PathVariable("name") String name) { @ApiResponses(value = { @ApiResponse(code = 200, message = "Success"), @ApiResponse(code = 500, message = "Failure")}) - public void overwriteEnvironment(@PathVariable("name") String name, @RequestBody List services) { - EnvironmentAggregate.EnvironmentAggregateBuilder builder = EnvironmentAggregate.builder(name); - services.stream().forEach(sf -> builder.withServiceVersion(sf.getName(), sf.getVersion())); + public void overwriteEnvironment( + @PathVariable("name") String name, + @RequestHeader(value = "X-JUDGE-D-AGENT-SPACE", defaultValue = DEFAULT_NAMESPACE, required = false) String agentSpace, + @RequestBody Set services + ) { + agentSpace = firstNonNull(agentSpace, DEFAULT_NAMESPACE); + EnvironmentAggregate environment = environmentRepository.get(name); + Set supportedSpaces = ImmutableSet.builder().addAll(environment.getSpaceNames()).add(agentSpace).build(); + EnvironmentAggregateBuilder builder = EnvironmentAggregate.builder(name); + for (String space : supportedSpaces) { + if (agentSpace.equals(space)) { + Set collect = services.stream().map(sf -> new ServiceVersion(sf.getName(), sf.getVersion())).collect(toSet()); + + builder.withServiceVersions(agentSpace, collect); + } else { + builder.withServiceVersions(space, environment.getServices(space)); + } + } + environmentRepository.persist(builder.build()); } } diff --git a/judge-d-server/src/main/java/dev/hltech/dredd/interfaces/rest/environment/ServiceForm.java b/judge-d-server/src/main/java/dev/hltech/dredd/interfaces/rest/environment/ServiceForm.java index 8a6fbb5a..3cd808f9 100644 --- a/judge-d-server/src/main/java/dev/hltech/dredd/interfaces/rest/environment/ServiceForm.java +++ b/judge-d-server/src/main/java/dev/hltech/dredd/interfaces/rest/environment/ServiceForm.java @@ -1,8 +1,12 @@ package dev.hltech.dredd.interfaces.rest.environment; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; @Data +@AllArgsConstructor +@NoArgsConstructor public class ServiceForm { private String name; diff --git a/judge-d-server/src/main/java/dev/hltech/dredd/interfaces/rest/interrelationship/InterrelationshipController.java b/judge-d-server/src/main/java/dev/hltech/dredd/interfaces/rest/interrelationship/InterrelationshipController.java index 760247f1..63f4fa64 100644 --- a/judge-d-server/src/main/java/dev/hltech/dredd/interfaces/rest/interrelationship/InterrelationshipController.java +++ b/judge-d-server/src/main/java/dev/hltech/dredd/interfaces/rest/interrelationship/InterrelationshipController.java @@ -2,6 +2,7 @@ import dev.hltech.dredd.domain.contracts.ServiceContracts; import dev.hltech.dredd.domain.contracts.ServiceContractsRepository; +import dev.hltech.dredd.domain.environment.EnvironmentAggregate; import dev.hltech.dredd.domain.environment.EnvironmentRepository; import dev.hltech.dredd.domain.ServiceVersion; import dev.hltech.dredd.interfaces.rest.contracts.ContractsMapper; diff --git a/judge-d-server/src/main/resources/db/changelog/db.changelog-0.4.xml b/judge-d-server/src/main/resources/db/changelog/db.changelog-0.4.xml new file mode 100644 index 00000000..825e88d6 --- /dev/null +++ b/judge-d-server/src/main/resources/db/changelog/db.changelog-0.4.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + diff --git a/judge-d-server/src/main/resources/db/changelog/db.changelog-master.xml b/judge-d-server/src/main/resources/db/changelog/db.changelog-master.xml index 782bfedc..164acd11 100644 --- a/judge-d-server/src/main/resources/db/changelog/db.changelog-master.xml +++ b/judge-d-server/src/main/resources/db/changelog/db.changelog-master.xml @@ -10,5 +10,6 @@ + diff --git a/judge-d-server/src/test/groovy/dev/hltech/dredd/domain/environment/EnvironmentAggregateUT.groovy b/judge-d-server/src/test/groovy/dev/hltech/dredd/domain/environment/EnvironmentAggregateUT.groovy new file mode 100644 index 00000000..450d89c6 --- /dev/null +++ b/judge-d-server/src/test/groovy/dev/hltech/dredd/domain/environment/EnvironmentAggregateUT.groovy @@ -0,0 +1,28 @@ +package dev.hltech.dredd.domain.environment + +import com.google.common.collect.ImmutableMultimap +import dev.hltech.dredd.domain.ServiceVersion +import spock.lang.Specification + +import static dev.hltech.dredd.domain.environment.EnvironmentAggregate.DEFAULT_NAMESPACE + +class EnvironmentAggregateUT extends Specification { + + def 'should return services by space'() { + given: + def aggregate = new EnvironmentAggregate( + 'env', + ImmutableMultimap. builder() + .put(DEFAULT_NAMESPACE, new ServiceVersion("s1", "s1")) + .put("space1", new ServiceVersion("s2", "s2")) + .build() + ) + when: + def defaultSpaceServiceVersions = aggregate.getServices(DEFAULT_NAMESPACE); + def space1ServiceVersions = aggregate.getServices("space1"); + then: + defaultSpaceServiceVersions == [new ServiceVersion("s1", "s1")] as Set + space1ServiceVersions == [new ServiceVersion("s2", "s2")] as Set + + } +} diff --git a/judge-d-server/src/test/groovy/dev/hltech/dredd/domain/environment/JPAEnvironmentRepositoryIT.groovy b/judge-d-server/src/test/groovy/dev/hltech/dredd/domain/environment/JPAEnvironmentRepositoryIT.groovy index 0fb28542..de354525 100644 --- a/judge-d-server/src/test/groovy/dev/hltech/dredd/domain/environment/JPAEnvironmentRepositoryIT.groovy +++ b/judge-d-server/src/test/groovy/dev/hltech/dredd/domain/environment/JPAEnvironmentRepositoryIT.groovy @@ -6,6 +6,7 @@ import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.ActiveProfiles import spock.lang.Specification +import static dev.hltech.dredd.domain.environment.EnvironmentAggregate.builder import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT @@ -65,4 +66,19 @@ class JPAEnvironmentRepositoryIT extends Specification { then: names.contains(environment1.name) } + + def 'should retrieve service versions of all spaces'(){ + given: + def environment1 = builder(randomAlphabetic(10)) + .withServiceVersion("s1", "v1") + .withServiceVersions("space", [new ServiceVersion("s2", "v2")] as Set) + .build(); + when: + repository.persist(environment1); + then: + repository.get(environment1.name).with { + name == environment1.name + allServices.size() == 2 + } + } } diff --git a/judge-d-server/src/test/groovy/dev/hltech/dredd/interfaces/rest/environment/EnvironmentControllerUT.groovy b/judge-d-server/src/test/groovy/dev/hltech/dredd/interfaces/rest/environment/EnvironmentControllerUT.groovy index 7f9cd21c..395949d5 100644 --- a/judge-d-server/src/test/groovy/dev/hltech/dredd/interfaces/rest/environment/EnvironmentControllerUT.groovy +++ b/judge-d-server/src/test/groovy/dev/hltech/dredd/interfaces/rest/environment/EnvironmentControllerUT.groovy @@ -47,4 +47,36 @@ class EnvironmentControllerUT extends Specification { services == [new ServiceDto(serviceVersion.name, serviceVersion.version)] as List } + def 'should return two services given agents from two different spaces saved before'(){ + given: + def sv1 = new ServiceForm("service1", "version1") + def sv2 = new ServiceForm("service2", "version2") + + environmentController.overwriteEnvironment("env", null, [sv1] as Set); + environmentController.overwriteEnvironment("env", "space", [sv2] as Set); + when: + def environment = environmentController.getEnvironment("env") + then: + environment.size() == 2 + + } + + def 'should override dfault space only given additional non-empty space exists and both are overwriten'(){ + given: + def sv1 = new ServiceForm("service1", "version1") + def sv2 = new ServiceForm("service2", "version2") + def sv3 = new ServiceForm("service3", "version3") + + environmentController.overwriteEnvironment("env", null, [sv1] as Set); + environmentController.overwriteEnvironment("env", null, [sv2] as Set); + environmentController.overwriteEnvironment("env", "space", [sv3] as Set); + when: + def environment = environmentController.getEnvironment("env") + then: + environment.size() == 2 + environment.contains(new ServiceDto("service2", "version2")) + environment.contains(new ServiceDto("service3", "version3")) + + } + } diff --git a/judge-d-server/src/test/groovy/dev/hltech/dredd/interfaces/rest/interrelationship/InterrelationshipControllerUT.groovy b/judge-d-server/src/test/groovy/dev/hltech/dredd/interfaces/rest/interrelationship/InterrelationshipControllerUT.groovy index 2df977a3..7744a7c8 100644 --- a/judge-d-server/src/test/groovy/dev/hltech/dredd/interfaces/rest/interrelationship/InterrelationshipControllerUT.groovy +++ b/judge-d-server/src/test/groovy/dev/hltech/dredd/interfaces/rest/interrelationship/InterrelationshipControllerUT.groovy @@ -24,9 +24,10 @@ class InterrelationshipControllerUT extends Specification { def "should return 200 when getting interrelationship for any environment"() { given: def env = 'SIT' - def services = [new ServiceVersion('1', '1'), new ServiceVersion('2', '2')] + def services = [new ServiceVersion('1', '1'), new ServiceVersion('2', '2')] as Set + def environment = new EnvironmentAggregate(env, services) - 1 * environmentRepository.get(env) >> new EnvironmentAggregate('name': env, 'serviceVersions': services) + 1 * environmentRepository.get(env) >> environment 1 * serviceContractsRepository.findOne(new ServiceVersion('1', '1')) >> Optional.of(createServiceContracts('1', '1')) 1 * serviceContractsRepository.findOne(new ServiceVersion('2', '2')) >> Optional.of(createServiceContracts('2', '2'))