diff --git a/pom.xml b/pom.xml index 54fd4499067e093ab5cb2c63781e84b544b4cf7d..62e2687c39b41812950672f5bb68afa3d577128d 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,8 @@ <properties> <imageName>docker.ozg-sh.de/administration</imageName> - <build.number>SET_BY_JENKINS</build.number> + <build.number>SET_BY_JENKINS</build.number> + <spring-cloud-config-server.version>4.1.0</spring-cloud-config-server.version> </properties> <dependencies> @@ -42,6 +43,11 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-hateoas</artifactId> </dependency> + <dependency> + <groupId>org.springframework.cloud</groupId> + <artifactId>spring-cloud-config-server</artifactId> + <version>${spring-cloud-config-server.version}</version> + </dependency> <!-- Dev --> <dependency> diff --git a/src/main/java/de/ozgcloud/admin/AdministrationApplication.java b/src/main/java/de/ozgcloud/admin/AdministrationApplication.java index e4c069c9e4b910389861e9693d3af0fe1edf20dc..c9535837fdbb37dcb5a4344bff54816679d33223 100644 --- a/src/main/java/de/ozgcloud/admin/AdministrationApplication.java +++ b/src/main/java/de/ozgcloud/admin/AdministrationApplication.java @@ -23,8 +23,12 @@ package de.ozgcloud.admin; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.config.server.EnableConfigServer; +import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; @SpringBootApplication +@EnableConfigServer +@EnableMongoRepositories public class AdministrationApplication { public static void main(String[] args) { diff --git a/src/main/java/de/ozgcloud/admin/environment/AdminEnvironmentRepository.java b/src/main/java/de/ozgcloud/admin/environment/AdminEnvironmentRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..a3ece1fe341021ef0a4d8515f65fe278e239cada --- /dev/null +++ b/src/main/java/de/ozgcloud/admin/environment/AdminEnvironmentRepository.java @@ -0,0 +1,34 @@ +package de.ozgcloud.admin.environment; + +import java.util.List; + +import org.springframework.cloud.config.environment.Environment; +import org.springframework.cloud.config.environment.PropertySource; +import org.springframework.cloud.config.server.environment.EnvironmentRepository; +import org.springframework.stereotype.Component; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Component +public class AdminEnvironmentRepository implements EnvironmentRepository { + + private final PropertyRepository propertyRepository; + + @Override + public Environment findOne(String application, String profile, String label) { + List<ConfigurationProperties> properties = propertyRepository.findAllByApplication(application); + return buildEnvironment(application, properties); + } + + Environment buildEnvironment(String application, List<ConfigurationProperties> properties) { + var environment = new Environment(application); + environment.addAll(properties.stream().map(this::createPropertySource).toList()); + return environment; + } + + PropertySource createPropertySource(ConfigurationProperties configurationProperties) { + return new PropertySource(null, configurationProperties.getSource()); + } + +} diff --git a/src/main/java/de/ozgcloud/admin/environment/ConfigurationProperties.java b/src/main/java/de/ozgcloud/admin/environment/ConfigurationProperties.java new file mode 100644 index 0000000000000000000000000000000000000000..927bd6123950466d576d138384736864002b7ed3 --- /dev/null +++ b/src/main/java/de/ozgcloud/admin/environment/ConfigurationProperties.java @@ -0,0 +1,20 @@ +package de.ozgcloud.admin.environment; + +import java.util.Map; + +import org.springframework.data.mongodb.core.mapping.Document; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Builder +@Document(ConfigurationProperties.COLLECTION_NAME) +public class ConfigurationProperties { + public static final String COLLECTION_NAME = "configuration_properties"; + private String application; + private String profile; + private Map<String, Object> source; +} diff --git a/src/main/java/de/ozgcloud/admin/environment/PropertyRepository.java b/src/main/java/de/ozgcloud/admin/environment/PropertyRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..379650c42fe3fe7b7adb4614f6af8294bf4ac533 --- /dev/null +++ b/src/main/java/de/ozgcloud/admin/environment/PropertyRepository.java @@ -0,0 +1,11 @@ +package de.ozgcloud.admin.environment; + +import java.util.List; + +import org.springframework.data.mongodb.repository.MongoRepository; + +interface PropertyRepository extends MongoRepository<ConfigurationProperties, String> { + + List<ConfigurationProperties> findAllByApplication(String application); + +} \ No newline at end of file diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml new file mode 100644 index 0000000000000000000000000000000000000000..37180f0075c969aa9de081717e5f0415fe3c268b --- /dev/null +++ b/src/main/resources/application-local.yml @@ -0,0 +1,4 @@ +spring: + data: + mongodb: + uri: mongodb://localhost/config-db \ No newline at end of file diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index dec38c48acab29be561437ff4b9e9ff956dd0eb2..c80bcec75a6c5b2c6f0824b0dd7579b84d8e716f 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1,4 +1,8 @@ spring: data: rest: - basePath: /api/configuration \ No newline at end of file + basePath: /api/configuration + cloud: + config: + server: + prefix: /configserver \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/admin/environment/AdminEnvironmentITCase.java b/src/test/java/de/ozgcloud/admin/environment/AdminEnvironmentITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..c3bd63463ab3744a135c1ec8463c1bb6a2bc9a30 --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/environment/AdminEnvironmentITCase.java @@ -0,0 +1,28 @@ + +package de.ozgcloud.admin.environment; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.test.web.servlet.MockMvc; + +import de.ozgcloud.common.test.DataITCase; +import lombok.SneakyThrows; + +@DataITCase +@AutoConfigureMockMvc +class AdminEnvironmentITCase { + @Autowired + private MockMvc mockMvc; + + @Test + @SneakyThrows + void shouldHaveHttpEndpoint() { + var result = mockMvc.perform(get("/configserver/example/path")); + + result.andExpect(status().isOk()); + } +} \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/admin/environment/AdminEnvironmentRepositoryITCase.java b/src/test/java/de/ozgcloud/admin/environment/AdminEnvironmentRepositoryITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..ac99022005cb8de1d1c00749bcfa48d7571cdea0 --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/environment/AdminEnvironmentRepositoryITCase.java @@ -0,0 +1,83 @@ +package de.ozgcloud.admin.environment; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.config.environment.Environment; +import org.springframework.cloud.config.server.environment.EnvironmentRepository; + +import de.ozgcloud.common.test.DataITCase; + +@DataITCase +class AdminEnvironmentRepositoryITCase { + + @Autowired + private EnvironmentRepository repository; + @Autowired + private PropertyRepository propertyRepository; + + private ConfigurationProperties configurationProperties = ConfigurationPropertiesTestFactory.create(); + + @AfterEach + void clearData() { + propertyRepository.deleteAll(); + } + + @Nested + class TestFindOne { + @BeforeEach + void initDb() { + saveMongoSource(configurationProperties); + } + + @Test + void shouldFindEnvironmentWithOneCorrectPropertySource() { + + var environment = findOneEnvironment(); + + assertThat(environment.getPropertySources()).hasSize(1); + } + + @Test + void shouldFindEnvironmentWithTwoCorrectPropertySources() { + var configurationProperties2 = ConfigurationPropertiesTestFactory.createBuilder().profile("other").build(); + saveMongoSource(configurationProperties2); + + var environment = findOneEnvironment(); + + assertThat(environment.getPropertySources()).hasSize(2); + } + + private void saveMongoSource(ConfigurationProperties configurationProperties) { + propertyRepository.save(configurationProperties); + } + + @Test + void shouldFindEnvironmentWithoutPropertySources() { + + var environment = repository.findOne("FalseAppName", ConfigurationPropertiesTestFactory.PROFILE, null); + + assertThat(environment.getPropertySources()).isEmpty(); + + } + + @Test + void shouldFindCorrectEnvironment() { + + var environment = findOneEnvironment(); + + assertThat(environment.getPropertySources().getLast().getSource()).isEqualTo(ConfigurationPropertiesTestFactory.PROPERTIES); + } + + private Environment findOneEnvironment() { + return repository.findOne(ConfigurationPropertiesTestFactory.APPNAME, ConfigurationPropertiesTestFactory.PROFILE, + null); + } + + } + +} diff --git a/src/test/java/de/ozgcloud/admin/environment/AdminEnvironmentRepositoryTest.java b/src/test/java/de/ozgcloud/admin/environment/AdminEnvironmentRepositoryTest.java new file mode 100644 index 0000000000000000000000000000000000000000..bb88c14e15be793e14a00ceb190ff29eb2cb1219 --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/environment/AdminEnvironmentRepositoryTest.java @@ -0,0 +1,70 @@ +package de.ozgcloud.admin.environment; + +import static org.assertj.core.api.Assertions.*; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +public class AdminEnvironmentRepositoryTest { + + @InjectMocks + private AdminEnvironmentRepository repository; + + private ConfigurationProperties configurationProperties = ConfigurationPropertiesTestFactory.create(); + + @Nested + class TestBuildEnvironment { + @Test + void shouldHaveCorrectAppName() { + + var environment = repository.buildEnvironment(ConfigurationPropertiesTestFactory.APPNAME, new ArrayList<ConfigurationProperties>()); + + assertThat(environment.getName()).isEqualTo(ConfigurationPropertiesTestFactory.APPNAME); + } + + @Test + void shouldHaveCorrectNumberOfPropertySources() { + + var environment = repository.buildEnvironment(ConfigurationPropertiesTestFactory.APPNAME, + List.of(configurationProperties, configurationProperties)); + + assertThat(environment.getPropertySources()).hasSize(2); + } + + @Test + void shouldHandleEmptyConfigurationList() { + + var environment = repository.buildEnvironment(ConfigurationPropertiesTestFactory.APPNAME, new ArrayList<ConfigurationProperties>()); + + assertThat(environment.getPropertySources()).isEmpty(); + + } + } + + @Nested + class TestCreatePropertySource { + @Test + void shouldHaveCorrectSource() { + + var propertySource = repository.createPropertySource(configurationProperties); + + assertThat(propertySource.getSource()).isEqualTo(configurationProperties.getSource()); + } + + @Test + void shouldHaveCorrectName() { + + var propertySource = repository.createPropertySource(configurationProperties); + + assertThat(propertySource.getName()).isNull(); + } + } + +} diff --git a/src/test/java/de/ozgcloud/admin/environment/ConfigurationPropertiesTestFactory.java b/src/test/java/de/ozgcloud/admin/environment/ConfigurationPropertiesTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..2195b9a83c4ccef3e462976de31f0aabd6bfecb9 --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/environment/ConfigurationPropertiesTestFactory.java @@ -0,0 +1,22 @@ +package de.ozgcloud.admin.environment; + +import java.util.Map; + +public class ConfigurationPropertiesTestFactory { + public static final String APPNAME = "testapp"; + public static final String PROFILE = "testprofile"; + public static final String PROPERTY1 = "property1"; + public static final String VALUE1 = "value1"; + public static Map<String, Object> PROPERTIES = Map.of(PROPERTY1, VALUE1); + + public static ConfigurationProperties create() { + return createBuilder().build(); + } + + public static ConfigurationProperties.ConfigurationPropertiesBuilder createBuilder() { + return ConfigurationProperties.builder() + .application(APPNAME) + .profile(PROFILE) + .source(PROPERTIES); + } +}