diff --git a/pom.xml b/pom.xml index 8b07c04fd106d9f2924c3335f1a4205d506de890..188d026ab25c2fab2e4eacd4676c98a2a38a666e 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> @@ -34,6 +35,19 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-rest</artifactId> + </dependency> + <dependency> + <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> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> @@ -62,6 +76,21 @@ <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-testcontainers</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.testcontainers</groupId> + <artifactId>mongodb</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.testcontainers</groupId> + <artifactId>junit-jupiter</artifactId> + <scope>test</scope> + </dependency> </dependencies> <profiles> <profile> diff --git a/src/main/java/de/ozgcloud/admin/AdministrationApplication.java b/src/main/java/de/ozgcloud/admin/AdministrationApplication.java index 36c0f359fa7ffdd7c83f9f2d41c3c751c9cd15bf..c9535837fdbb37dcb5a4344bff54816679d33223 100644 --- a/src/main/java/de/ozgcloud/admin/AdministrationApplication.java +++ b/src/main/java/de/ozgcloud/admin/AdministrationApplication.java @@ -1,9 +1,34 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ 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/Root.java b/src/main/java/de/ozgcloud/admin/Root.java index b5658c3ff6a812571e2dcb10e2ba4fcc6e524740..8fc3d5966abd999afa09d17b2c555cb4cc0b409d 100644 --- a/src/main/java/de/ozgcloud/admin/Root.java +++ b/src/main/java/de/ozgcloud/admin/Root.java @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ package de.ozgcloud.admin; import java.time.Instant; diff --git a/src/main/java/de/ozgcloud/admin/RootController.java b/src/main/java/de/ozgcloud/admin/RootController.java index bf17388b3274c557be524e5dc1d48e8dc347a7b2..578050bbeb47253470a8d01df8fcb183a4101eae 100644 --- a/src/main/java/de/ozgcloud/admin/RootController.java +++ b/src/main/java/de/ozgcloud/admin/RootController.java @@ -1,6 +1,28 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ package de.ozgcloud.admin; import org.springframework.boot.info.BuildProperties; +import org.springframework.hateoas.EntityModel; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -15,9 +37,11 @@ public class RootController { private final BuildProperties buildProperties; + private final RootModelAssembler modelAssembler; + @GetMapping - public Root getRoot() { - return buildRoot(); + public EntityModel<Root> getRoot() { + return modelAssembler.toModel(buildRoot()); } private Root buildRoot() { diff --git a/src/main/java/de/ozgcloud/admin/RootModelAssembler.java b/src/main/java/de/ozgcloud/admin/RootModelAssembler.java new file mode 100644 index 0000000000000000000000000000000000000000..ed5c7576e72f09266c4690181fc681c64578a011 --- /dev/null +++ b/src/main/java/de/ozgcloud/admin/RootModelAssembler.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.admin; + +import org.springframework.boot.autoconfigure.data.rest.RepositoryRestProperties; +import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.Link; +import org.springframework.hateoas.server.RepresentationModelAssembler; +import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder; +import org.springframework.stereotype.Component; + +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +class RootModelAssembler implements RepresentationModelAssembler<Root, EntityModel<Root>> { + static final String REL_CONFIGURATION = "configuration"; + + private final RepositoryRestProperties restProperties; + + @Override + public EntityModel<Root> toModel(Root root) { + var rootLink = WebMvcLinkBuilder.linkTo(RootController.class); + var configLink = rootLink.toUriComponentsBuilder().replacePath(restProperties.getBasePath()); + return EntityModel.of( + root, + Link.of(configLink.toUriString(), REL_CONFIGURATION), + rootLink.withSelfRel() + ); + } +} diff --git a/src/main/java/de/ozgcloud/admin/configurationparameter/ConfigurationParameter.java b/src/main/java/de/ozgcloud/admin/configurationparameter/ConfigurationParameter.java new file mode 100644 index 0000000000000000000000000000000000000000..1d60c480d267c4eb0a762fe9f617efc8e8a3b84a --- /dev/null +++ b/src/main/java/de/ozgcloud/admin/configurationparameter/ConfigurationParameter.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.admin.configurationparameter; + +import org.springframework.data.annotation.Id; +import org.springframework.data.mongodb.core.mapping.Document; + +import lombok.Builder; + +@Builder +@Document +public record ConfigurationParameter( + @Id + String id +) { +} diff --git a/src/main/java/de/ozgcloud/admin/configurationparameter/ConfigurationParameterConstants.java b/src/main/java/de/ozgcloud/admin/configurationparameter/ConfigurationParameterConstants.java new file mode 100644 index 0000000000000000000000000000000000000000..bf9f82e2aa776369d825982461f3a83c3786f912 --- /dev/null +++ b/src/main/java/de/ozgcloud/admin/configurationparameter/ConfigurationParameterConstants.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.admin.configurationparameter; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +class ConfigurationParameterConstants { + + static final String REL = "params"; + + static final String PATH = "param"; +} diff --git a/src/main/java/de/ozgcloud/admin/configurationparameter/ConfigurationParameterRepository.java b/src/main/java/de/ozgcloud/admin/configurationparameter/ConfigurationParameterRepository.java new file mode 100644 index 0000000000000000000000000000000000000000..1915e55dba201369f9b696d363e824e9a19967b6 --- /dev/null +++ b/src/main/java/de/ozgcloud/admin/configurationparameter/ConfigurationParameterRepository.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.admin.configurationparameter; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.data.rest.core.annotation.RepositoryRestResource; + +@RepositoryRestResource( + collectionResourceRel = ConfigurationParameterConstants.REL, + path = ConfigurationParameterConstants.PATH +) +public interface ConfigurationParameterRepository extends MongoRepository<ConfigurationParameter, String> { + +} 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.properties b/src/main/resources/application.properties deleted file mode 100644 index 8b137891791fe96927ad78e64b0aad7bded08bdc..0000000000000000000000000000000000000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c80bcec75a6c5b2c6f0824b0dd7579b84d8e716f --- /dev/null +++ b/src/main/resources/application.yaml @@ -0,0 +1,8 @@ +spring: + data: + rest: + basePath: /api/configuration + cloud: + config: + server: + prefix: /configserver \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/admin/AdministrationApplicationTest.java b/src/test/java/de/ozgcloud/admin/AdministrationApplicationTest.java index ae71e12d72f6210d5afa910fd074a9ecff35654f..7d88d4237191cb0b07aaad9235443c689c1efe59 100644 --- a/src/test/java/de/ozgcloud/admin/AdministrationApplicationTest.java +++ b/src/test/java/de/ozgcloud/admin/AdministrationApplicationTest.java @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ package de.ozgcloud.admin; import org.junit.jupiter.api.Test; diff --git a/src/test/java/de/ozgcloud/admin/ApiRootITCase.java b/src/test/java/de/ozgcloud/admin/ApiRootITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..7b5a46262cbd9ecba82d72546ea0b089b1bcf867 --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/ApiRootITCase.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.admin; + +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.data.rest.RepositoryRestProperties; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; + +import de.ozgcloud.common.test.ITCase; +import lombok.SneakyThrows; + +@ITCase +@AutoConfigureMockMvc +class ApiRootITCase { + + @Autowired + private RepositoryRestProperties restProperties; + + @Autowired + private MockMvc mockMvc; + + @Nested + class TestRootEndpoint { + + @Test + void shouldBetSetToApi() { + var basePath = restProperties.getBasePath(); + + assertEquals("/api/configuration", basePath); + } + + @Test + @SneakyThrows + void shouldHaveStatusOk() { + var result = doPerform(); + + result.andExpect(status().isOk()); + } + + @Test + @SneakyThrows + void shouldHaveContentType() { + var result = doPerform(); + + result.andExpect(content().contentType("application/hal+json")); + } + + @Test + @SneakyThrows + void shouldHaveStandardProfileLink() { + var result = doPerform(); + + result.andExpect(jsonPath("$._links.profile.href").value("http://localhost" + restProperties.getBasePath() + "/profile")); + } + + @SneakyThrows + private ResultActions doPerform() { + return mockMvc.perform(get(restProperties.getBasePath())); + } + } + +} \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/admin/RootControllerTest.java b/src/test/java/de/ozgcloud/admin/RootControllerTest.java index f2e35aae3631b6179a8c2941c3524296fcfa6b8e..59fc03dfd22dfa7eb76f0b52da32ad583d64692c 100644 --- a/src/test/java/de/ozgcloud/admin/RootControllerTest.java +++ b/src/test/java/de/ozgcloud/admin/RootControllerTest.java @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ package de.ozgcloud.admin; import static org.mockito.Mockito.*; @@ -14,6 +35,7 @@ import org.mockito.Mock; import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.boot.info.BuildProperties; +import org.springframework.hateoas.EntityModel; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; import org.springframework.test.web.servlet.setup.MockMvcBuilders; @@ -30,10 +52,14 @@ class RootControllerTest { @Mock private BuildProperties buildProperties; + @Mock + private RootModelAssembler modelAssembler; + private MockMvc mockMvc; @BeforeEach void mock() { + when(modelAssembler.toModel(any())).thenAnswer(a -> EntityModel.of(a.getArgument(0))); mockMvc = MockMvcBuilders.standaloneSetup(rootController).build(); } @@ -41,6 +67,14 @@ class RootControllerTest { @Nested class TestInfo { + @Test + @SneakyThrows + void shouldCallModelAssembler() { + doRequest(); + + verify(modelAssembler).toModel(any()); + } + @Test @SneakyThrows void shouldHaveJavaVersion() { diff --git a/src/test/java/de/ozgcloud/admin/RootModelAssemblerTest.java b/src/test/java/de/ozgcloud/admin/RootModelAssemblerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..6510e8f1187d204a062143130590313f075771d0 --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/RootModelAssemblerTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.admin; + +import static de.ozgcloud.admin.RootModelAssembler.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Optional; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +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.Mock; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.boot.autoconfigure.data.rest.RepositoryRestProperties; +import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.IanaLinkRelations; +import org.springframework.hateoas.Link; + +@ExtendWith(MockitoExtension.class) +class RootModelAssemblerTest { + + private static final String BASE_PATH = "/api/base"; + @Spy + @InjectMocks + private RootModelAssembler modelAssembler; + + @Mock + private RepositoryRestProperties restProperties; + + @BeforeEach + void mockBasePath() { + when(restProperties.getBasePath()).thenReturn(BASE_PATH); + } + + @DisplayName("Entity Model") + @Nested + class TestEntityModel { + + @Test + void shouldHaveHrefToBasePath() { + var configurationLink = toModel().getLink(REL_CONFIGURATION); + + assertEquals(Optional.of(Link.of(BASE_PATH, REL_CONFIGURATION)), configurationLink); + } + + @Test + void shouldHaveHrefToSelf() { + var selfLink = toModel().getLink(IanaLinkRelations.SELF); + + assertEquals(Optional.of(Link.of(RootController.PATH)), selfLink); + } + + private EntityModel<Root> toModel() { + return modelAssembler.toModel(RootTestFactory.create()); + } + + } + +} \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/admin/RootTestFactory.java b/src/test/java/de/ozgcloud/admin/RootTestFactory.java index e0879c7530926dbbe52514acab93f2bf3cf63820..e4a77201b527061485a7dcf7d567dfa161f73f7b 100644 --- a/src/test/java/de/ozgcloud/admin/RootTestFactory.java +++ b/src/test/java/de/ozgcloud/admin/RootTestFactory.java @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ package de.ozgcloud.admin; import java.time.Instant; @@ -10,5 +31,16 @@ public class RootTestFactory { public static final String JAVA_VERSION = "1"; public static final String BUILD_VERSION = "2"; public static final String BUILD_NUMBER = "3"; - + + public static Root create() { + return createBuilder().build(); + } + + public static Root.RootBuilder createBuilder() { + return Root.builder() + .buildTime(BUILD_TIME) + .javaVersion(JAVA_VERSION) + .buildVersion(BUILD_VERSION) + .buildNumber(BUILD_NUMBER); + } } diff --git a/src/test/java/de/ozgcloud/admin/configurationparameter/ConfigurationParameterITCase.java b/src/test/java/de/ozgcloud/admin/configurationparameter/ConfigurationParameterITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..8de0ff41575b38f74c113db52f966bb741d6193c --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/configurationparameter/ConfigurationParameterITCase.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.admin.configurationparameter; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +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.boot.autoconfigure.data.rest.RepositoryRestProperties; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.http.HttpStatus; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; + +import de.ozgcloud.common.test.DataITCase; +import lombok.SneakyThrows; + +@DataITCase +@AutoConfigureMockMvc +class ConfigurationParameterITCase { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private MongoOperations mongoOperations; + + @Autowired + private RepositoryRestProperties restProperties; + + @Nested + class TestRestRepo { + + @BeforeEach + void init() { + mongoOperations.dropCollection(ConfigurationParameter.class); + mongoOperations.save(ConfigurationParameterTestFactory.create()); + } + + @Test + @SneakyThrows + void shouldHaveStatusOkForExisting() { + var result = doPerform(ConfigurationParameterTestFactory.ID); + + result.andExpect(status().isOk()); + } + + @Test + @SneakyThrows + void shouldHaveStatusNotFoundForNonExisting() { + var result = doPerform("unknown"); + + result.andExpect(status().is(HttpStatus.NOT_FOUND.value())); + } + + @SneakyThrows + private ResultActions doPerform(String id) { + return mockMvc.perform(get(String.join("/", restProperties.getBasePath(), ConfigurationParameterConstants.PATH, id))); + } + } + +} \ No newline at end of file diff --git a/src/test/java/de/ozgcloud/admin/configurationparameter/ConfigurationParameterTestFactory.java b/src/test/java/de/ozgcloud/admin/configurationparameter/ConfigurationParameterTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..843b45af4333290bbd3cc4cfdb3732a22eecc03f --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/configurationparameter/ConfigurationParameterTestFactory.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.admin.configurationparameter; + +import java.util.UUID; + +public class ConfigurationParameterTestFactory { + public static final String ID = UUID.randomUUID().toString(); + + public static ConfigurationParameter create() { + return createBuilder().build(); + } + + public static ConfigurationParameter.ConfigurationParameterBuilder createBuilder() { + return ConfigurationParameter.builder().id(ID); + } +} 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); + } +} diff --git a/src/test/resources/META-INF/spring/org.mockito.junit.jupiter.MockitoExtension b/src/test/resources/META-INF/spring/org.mockito.junit.jupiter.MockitoExtension new file mode 100644 index 0000000000000000000000000000000000000000..79b126e6cdb86bec1f4f08c205de8961bde1934a --- /dev/null +++ b/src/test/resources/META-INF/spring/org.mockito.junit.jupiter.MockitoExtension @@ -0,0 +1 @@ +org.mockito.junit.jupiter.MockitoExtension \ No newline at end of file diff --git a/src/test/resources/junit-platform.properties b/src/test/resources/junit-platform.properties new file mode 100644 index 0000000000000000000000000000000000000000..b059a65dc46792ea5494de02f888ab2ad08cd420 --- /dev/null +++ b/src/test/resources/junit-platform.properties @@ -0,0 +1 @@ +junit.jupiter.extensions.autodetection.enabled=true \ No newline at end of file