Skip to content

Commit

Permalink
Extracted domain representation of Environment
Browse files Browse the repository at this point in the history
  • Loading branch information
Felipe444 committed Sep 4, 2020
1 parent cd9512d commit 6e86700
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 79 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.hltech.judged.server.domain.environment;
package com.hltech.judged.server.domain;

import com.hltech.judged.server.domain.ServiceVersion;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,109 +1,79 @@
package com.hltech.judged.server.domain.environment;

import com.google.common.collect.Multimap;
import com.google.common.collect.SetMultimap;
import com.hltech.judged.server.domain.ServiceVersion;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

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
@Table(name = "environments")
@Access(AccessType.FIELD)
public class Environment {

public static final String DEFAULT_NAMESPACE = "default";

@Id
private String name;
private final String name;
private final SetMultimap<String, ServiceVersion> serviceVersions;

@ElementCollection(fetch = FetchType.EAGER, targetClass = SpaceServiceVersion.class )
@JoinTable(name = "service_versions", joinColumns = {
@JoinColumn(name = "environment_name", referencedColumnName = "name"),
})
private final Set<SpaceServiceVersion> serviceVersions = newHashSet();

protected Environment() {
}

protected Environment(String name, Set< ServiceVersion> deatulSpaceServiceVersions) {
public Environment(String name, SetMultimap<String, ServiceVersion> serviceVersions) {
this.name = name;
this.serviceVersions.addAll(
deatulSpaceServiceVersions
.stream()
.map(sv -> new SpaceServiceVersion(DEFAULT_NAMESPACE, sv.getName(), sv.getVersion()))
.collect(toList())
);
this.serviceVersions = serviceVersions;
}

private Environment(String name, Multimap<String, ServiceVersion> serviceVersions) {
public Environment(String name, Set<ServiceVersion> serviceVersions) {
this.name = name;
this.serviceVersions.addAll(
serviceVersions.entries()
.stream()
.map(e -> new SpaceServiceVersion(e.getKey(), e.getValue().getName(), e.getValue().getVersion()))
.collect(toList())
);
this.serviceVersions = create();
this.serviceVersions.putAll(DEFAULT_NAMESPACE, serviceVersions);
}

public String getName() {
return this.name;
}

public Set<String> getSpaceNames() {
return serviceVersions.stream().map(SpaceServiceVersion::getSpace).collect(toSet());
return serviceVersions.keySet();
}

public Set<ServiceVersion> getServices(String space) {
return serviceVersions
.stream()
.filter(ssv -> ssv.getSpace().equals(space))
.map(ssv -> new ServiceVersion(ssv.getName(), ssv.getVersion()))
.collect(toSet());
return serviceVersions.get(space);
}

public Set<ServiceVersion> getAllServices() {
return serviceVersions.stream()
.map(ssv -> new ServiceVersion(ssv.getName(), ssv.getVersion()))
.collect(toSet());
return serviceVersions.values().stream()
.collect(Collectors.toUnmodifiableSet());
}

public static Environment empty(String environmentName) {
return new Environment(environmentName, create());
return new Environment(environmentName, new HashSet<>());
}

public static EnvironmentAggregateBuilder builder(String name) {
return new EnvironmentAggregateBuilder(name);
public static EnvironmentBuilder builder(String name) {
return new EnvironmentBuilder(name);
}

public static class EnvironmentAggregateBuilder {
public static class EnvironmentBuilder {

private final String name;
private final Multimap<String, ServiceVersion> serviceVersions = create();
// <space, serviceVersion>
private final SetMultimap<String, ServiceVersion> serviceVersions = create();

private EnvironmentAggregateBuilder(String name) {
private EnvironmentBuilder(String name) {
this.name = name;
}

public EnvironmentAggregateBuilder withServiceVersion(String name, String version) {
this.serviceVersions.put(DEFAULT_NAMESPACE, new ServiceVersion(name, version));
public EnvironmentBuilder withServiceVersion(String space, ServiceVersion serviceVersion) {
this.serviceVersions.put(space, serviceVersion);
return this;
}

public EnvironmentAggregateBuilder withServiceVersions(String space, Set<ServiceVersion> serviceVersions) {
public EnvironmentBuilder withServiceVersions(String space, Set<ServiceVersion> serviceVersions) {
this.serviceVersions.putAll(space, serviceVersions);
return this;
}

public Environment build() {
return new Environment(
this.name,
this.serviceVersions
);
return new Environment(this.name, this.serviceVersions);
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.hltech.judged.server.infrastructure.persistence.environment;

import com.hltech.judged.server.domain.SpaceServiceVersion;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Table;
import java.util.Set;

@Entity
@Table(name = "environments")
@Access(AccessType.FIELD)
@Getter
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class EnvironmentTuple {

public static final String DEFAULT_NAMESPACE = "default";

@Id
private String name;

@ElementCollection(fetch = FetchType.EAGER, targetClass = SpaceServiceVersion.class)
@JoinTable(name = "service_versions", joinColumns = {
@JoinColumn(name = "environment_name", referencedColumnName = "name"),
})
private Set<SpaceServiceVersion> spaceServiceVersions;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.hltech.judged.server.infrastructure.persistence.environment;

import com.hltech.judged.server.domain.ServiceVersion;
import com.hltech.judged.server.domain.SpaceServiceVersion;
import com.hltech.judged.server.domain.environment.Environment;
import com.hltech.judged.server.domain.environment.EnvironmentRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.Set;
import java.util.stream.Collectors;

@Repository
@RequiredArgsConstructor
Expand All @@ -15,7 +18,8 @@ public class JPAEnvironmentRepository implements EnvironmentRepository {

@Override
public Environment persist(Environment environment) {
return springDataEnvironmentRepository.saveAndFlush(environment);
EnvironmentTuple environmentTuple = toEnvironmentTuple(environment);
return toEnvironment(springDataEnvironmentRepository.saveAndFlush(environmentTuple));
}

@Override
Expand All @@ -25,6 +29,32 @@ public Set<String> getNames() {

@Override
public Environment get(String name) {
return springDataEnvironmentRepository.findById(name).orElse(Environment.empty(name));
return springDataEnvironmentRepository.findById(name)
.map(this::toEnvironment)
.orElse(Environment.empty(name));
}

private EnvironmentTuple toEnvironmentTuple(Environment environment) {
return new EnvironmentTuple(environment.getName(), getSpaceServiceVersions(environment));
}

private Set<SpaceServiceVersion> getSpaceServiceVersions(Environment environment) {
return environment.getSpaceNames().stream()
.flatMap(space -> environment.getServices(space).stream()
.map(serviceVersion -> new SpaceServiceVersion(space, serviceVersion.getName(), serviceVersion.getVersion())))
.collect(Collectors.toUnmodifiableSet());
}

private Environment toEnvironment(EnvironmentTuple environmentTuple) {
Environment.EnvironmentBuilder environmentBuilder = Environment.builder(environmentTuple.getName());

environmentTuple.getSpaceServiceVersions().forEach(spaceServiceVersion ->
environmentBuilder.withServiceVersion(
spaceServiceVersion.getSpace(),
new ServiceVersion(spaceServiceVersion.getName(), spaceServiceVersion.getVersion())
)
);

return environmentBuilder.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package com.hltech.judged.server.infrastructure.persistence.environment;

import com.hltech.judged.server.domain.environment.Environment;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.Set;

interface SpringDataEnvironmentRepository extends JpaRepository<Environment, String> {
interface SpringDataEnvironmentRepository extends JpaRepository<EnvironmentTuple, String> {

@Query("SELECT e.name FROM Environment e")
@Query("SELECT e.name FROM EnvironmentTuple e")
Set<String> getNames();

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.google.common.collect.ImmutableSet;
import com.hltech.judged.server.domain.ServiceVersion;
import com.hltech.judged.server.domain.environment.Environment;
import com.hltech.judged.server.domain.environment.Environment.EnvironmentAggregateBuilder;
import com.hltech.judged.server.domain.environment.Environment.EnvironmentBuilder;
import com.hltech.judged.server.domain.environment.EnvironmentRepository;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
Expand Down Expand Up @@ -66,13 +66,19 @@ public void overwriteEnvironment(
) {
agentSpace = firstNonNull(agentSpace, DEFAULT_NAMESPACE);
Environment environment = environmentRepository.get(name);
Set<String> supportedSpaces = ImmutableSet.<String>builder().addAll(environment.getSpaceNames()).add(agentSpace).build();
EnvironmentAggregateBuilder builder = Environment.builder(name);
Set<String> supportedSpaces = ImmutableSet.<String>builder()
.addAll(environment.getSpaceNames())
.add(agentSpace)
.build();

EnvironmentBuilder builder = Environment.builder(name);
for (String space : supportedSpaces) {
if (agentSpace.equals(space)) {
Set<ServiceVersion> collect = services.stream().map(sf -> new ServiceVersion(sf.getName(), sf.getVersion())).collect(toSet());
Set<ServiceVersion> serviceVersions = services.stream()
.map(sf -> new ServiceVersion(sf.getName(), sf.getVersion()))
.collect(toSet());

builder.withServiceVersions(agentSpace, collect);
builder.withServiceVersions(agentSpace, serviceVersions);
} else {
builder.withServiceVersions(space, environment.getServices(space));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.hltech.judged.server.domain.environment

import com.google.common.collect.ImmutableMultimap
import com.google.common.collect.ImmutableSetMultimap
import com.hltech.judged.server.domain.ServiceVersion
import spock.lang.Specification

Expand All @@ -12,7 +12,7 @@ class EnvironmentUT extends Specification {
given:
def aggregate = new Environment(
'env',
ImmutableMultimap.<String, ServiceVersion> builder()
ImmutableSetMultimap.<String, ServiceVersion> builder()
.put(DEFAULT_NAMESPACE, new ServiceVersion("s1", "s1"))
.put("space1", new ServiceVersion("s2", "s2"))
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class JPAEnvironmentRepositoryIT extends Specification {
and:
def environment = new Environment('environmentName', serviceVersion)
when:
def persisted = repository.persist(environment)
repository.persist(environment)
then:
repository.get(environment.name).with {
name == environment.name
Expand Down Expand Up @@ -70,11 +70,11 @@ class JPAEnvironmentRepositoryIT extends Specification {
def 'should retrieve service versions of all spaces'(){
given:
def environment1 = Environment.builder(randomAlphabetic(10))
.withServiceVersion("s1", "v1")
.withServiceVersion("space2", new ServiceVersion("s1", "v1"))
.withServiceVersions("space", [new ServiceVersion("s2", "v2")] as Set)
.build();
when:
repository.persist(environment1);
repository.persist(environment1)
then:
repository.get(environment1.name).with {
name == environment1.name
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package com.hltech.judged.server.interfaces.rest.environment

import com.hltech.judged.server.domain.ServiceVersion
import com.hltech.judged.server.domain.environment.Environment
import com.hltech.judged.server.domain.environment.InMemoryEnvironmentRepository
import spock.lang.Specification

import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic

class EnvironmentControllerUT extends Specification {

def environmentRepository = new com.hltech.judged.server.domain.environment.InMemoryEnvironmentRepository()
def environmentRepository = new InMemoryEnvironmentRepository()
def environmentController = new EnvironmentController(environmentRepository)

def 'should return names of created environments'() {
Expand All @@ -31,7 +33,7 @@ class EnvironmentControllerUT extends Specification {
}

def 'should return list of services from and evironment given it was saved before'() {
def serviceVersion = new com.hltech.judged.server.domain.ServiceVersion("service", "version")
def serviceVersion = new ServiceVersion("service", "version")
given:
def environment = new Environment(
randomAlphabetic(10),
Expand All @@ -49,8 +51,8 @@ class EnvironmentControllerUT extends Specification {
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);
environmentController.overwriteEnvironment("env", null, [sv1] as Set)
environmentController.overwriteEnvironment("env", "space", [sv2] as Set)
when:
def environment = environmentController.getEnvironment("env")
then:
Expand All @@ -64,9 +66,9 @@ class EnvironmentControllerUT extends Specification {
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);
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:
Expand Down

0 comments on commit 6e86700

Please sign in to comment.