Skip to content
Snippets Groups Projects
Commit 96d2073e authored by OZGCloud's avatar OZGCloud
Browse files

Merge remote-tracking branch 'origin/master' into OZG-5058-mongock-setup

parents b0c50b18 1a0b8ffb
Branches
Tags
No related merge requests found
Showing
with 173 additions and 32 deletions
......@@ -48,7 +48,7 @@ pipeline {
}
configFileProvider([configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) {
sh "mvn -s $MAVEN_SETTINGS clean install -Dmaven.wagon.http.retryHandler.count=3 -DelasticTests.disabled=true -Dbuild.number=$BUILD_NUMBER"
sh 'mvn -s $MAVEN_SETTINGS clean install -Dmaven.wagon.http.retryHandler.count=3 -DelasticTests.disabled=true -Dbuild.number=$BUILD_NUMBER'
}
}
}
......@@ -116,7 +116,7 @@ pipeline {
configFileProvider([configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) {
withCredentials([usernamePassword(credentialsId: 'jenkins-nexus-login', usernameVariable: 'USER', passwordVariable: 'PASSWORD')]) {
sh 'mvn -s $MAVEN_SETTINGS spring-boot:build-image -DskipTests -Dmaven.wagon.http.retryHandler.count=3 $BUILD_PROFILE -Ddocker.publishRegistry.username=${USER} -Ddocker.publishRegistry.password=${PASSWORD}'
sh 'mvn -s $MAVEN_SETTINGS spring-boot:build-image -DskipTests -Dmaven.wagon.http.retryHandler.count=3 $BUILD_PROFILE -Ddocker.publishRegistry.username=${USER} -Ddocker.publishRegistry.password=${PASSWORD} -Dbuild.number=$BUILD_NUMBER'
}
}
}
......
......@@ -28,13 +28,11 @@ import org.springframework.hateoas.server.RepresentationModelAssembler;
import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
import org.springframework.stereotype.Component;
import io.micrometer.common.lang.NonNullApi;
import lombok.RequiredArgsConstructor;
@Component
@RequiredArgsConstructor
@NonNullApi
class RootModelAssembler implements RepresentationModelAssembler<Root, EntityModel<Root>> {
public class RootModelAssembler implements RepresentationModelAssembler<Root, EntityModel<Root>> {
static final String REL_CONFIGURATION = "configuration";
private final RepositoryRestProperties restProperties;
......@@ -46,7 +44,6 @@ class RootModelAssembler implements RepresentationModelAssembler<Root, EntityMod
return EntityModel.of(
root,
Link.of(configLink.toUriString(), REL_CONFIGURATION),
rootLink.withSelfRel()
);
rootLink.withSelfRel());
}
}
......@@ -19,7 +19,7 @@
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
package de.ozgcloud.admin.errorhandling;
package de.ozgcloud.admin.common.errorhandling;
import java.util.Map;
......@@ -36,7 +36,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExcep
import de.ozgcloud.common.errorhandling.TechnicalException;
@RestControllerAdvice
public class AdminExceptionHandler extends ResponseEntityExceptionHandler {
public class ExceptionController extends ResponseEntityExceptionHandler {
static final Map<Class<? extends Exception>, HttpStatus> STATUS_BY_EXCEPTION = Map.of(
RuntimeException.class, HttpStatus.INTERNAL_SERVER_ERROR,
......
......@@ -19,7 +19,7 @@
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
package de.ozgcloud.admin.errorhandling;
package de.ozgcloud.admin.common.errorhandling;
import java.io.Serial;
import java.util.UUID;
......
......@@ -5,7 +5,7 @@ import lombok.Getter;
@Getter
@Builder
public class FrontendEnvironment {
public class Environment {
private boolean production;
private String remoteHost;
private String authServer;
......
......@@ -9,10 +9,10 @@ import org.springframework.web.bind.annotation.RestController;
import de.ozgcloud.admin.RootController;
import lombok.RequiredArgsConstructor;
@RestController
@RestController("ozgCloudEnvironmentController")
@RequiredArgsConstructor
@RequestMapping(FrontendEnvironmentController.PATH)
public class FrontendEnvironmentController {
@RequestMapping(EnvironmentController.PATH)
public class EnvironmentController {
static final String PATH = "/api/environment"; // NOSONAR
......@@ -21,8 +21,8 @@ public class FrontendEnvironmentController {
private final OAuth2Properties oAuthProperties;
@GetMapping
public FrontendEnvironment getEnvironment() {
return FrontendEnvironment.builder()
public Environment getEnvironment() {
return Environment.builder()
.production(environmentProperties.isProduction())
.remoteHost(linkTo(RootController.class).toUri().toString())
.authServer(oAuthProperties.getAuthServerUrl())
......
package de.ozgcloud.admin.common.errorhandling;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import java.util.Set;
import java.util.stream.Stream;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.constraints.NotEmpty;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import de.ozgcloud.admin.RootController;
import de.ozgcloud.admin.RootModelAssembler;
import de.ozgcloud.common.test.ITCase;
import lombok.Builder;
import lombok.Getter;
import lombok.SneakyThrows;
@ITCase
@AutoConfigureMockMvc
@WithMockUser
class ExceptionControllerITCase {
@Autowired
private MockMvc mockMvc;
@MockBean
private RootModelAssembler modelAssembler;
@Nested
class TestExceptions {
@ParameterizedTest
@MethodSource("exceptionAndExpectedStatus")
@SneakyThrows
void shouldHandleExceptionWithStatus(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) {
when(modelAssembler.toModel(any())).thenThrow(TestErrorController.EXCEPTION_PRODUCER.get(exceptionClass).produceException());
var result = performGet();
result.andExpect(status().is(expectedStatus.value()));
}
@ParameterizedTest
@MethodSource("exceptionAndExpectedStatus")
@SneakyThrows
void shouldRespondWithStatusInBody(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) {
when(modelAssembler.toModel(any())).thenThrow(exceptionClass);
var result = performGet();
result.andExpect(jsonPath("$.status").value(expectedStatus.value()));
}
private static Stream<Arguments> exceptionAndExpectedStatus() {
return ExceptionController.STATUS_BY_EXCEPTION.entrySet().stream().map(kv -> Arguments.of(kv.getKey(), kv.getValue()));
}
}
@Nested
class TestConstraintViolationException {
@Test
@SneakyThrows
void shouldHaveValidationMessage() {
when(modelAssembler.toModel(any())).thenAnswer((a) -> {
throw new ConstraintViolationException(getConstraintViolations());
});
var result = performGet();
result.andExpect(jsonPath("$.detail").value("string: Empty field"));
}
private Set<ConstraintViolation<ValidatedClass>> getConstraintViolations() {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
return validator.validate(ValidatedClass.builder().build());
}
@Getter
@Builder
private static class ValidatedClass {
@NotEmpty(message = "Empty field")
private String string;
}
}
@SneakyThrows
private ResultActions performGet() {
return mockMvc.perform(get(RootController.PATH));
}
}
......@@ -19,9 +19,9 @@
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
package de.ozgcloud.admin.errorhandling;
package de.ozgcloud.admin.common.errorhandling;
import static de.ozgcloud.admin.errorhandling.AdminExceptionHandler.*;
import static de.ozgcloud.admin.common.errorhandling.ExceptionController.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
......@@ -41,7 +41,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import lombok.SneakyThrows;
class AdminExceptionHandlerITCase {
class ExceptionControllerTest {
private MockMvc mockMvc;
......@@ -49,7 +49,7 @@ class AdminExceptionHandlerITCase {
void setup() {
mockMvc = MockMvcBuilders
.standaloneSetup(new TestErrorController())
.setControllerAdvice(new AdminExceptionHandler()).build();
.setControllerAdvice(new ExceptionController()).build();
}
@DisplayName("Error handler")
......@@ -74,13 +74,49 @@ class AdminExceptionHandlerITCase {
result.andExpect(jsonPath("$.status").value(expectedStatus.value()));
}
@ParameterizedTest
@MethodSource("exceptionAndExpectedStatus")
@SneakyThrows
void shouldRespondWithTitler(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) {
var result = doPerformWithError(exceptionClass);
result.andExpect(jsonPath("$.title").exists());
}
@ParameterizedTest
@MethodSource("exceptionAndExpectedStatus")
@SneakyThrows
void shouldRespondWithDetail(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) {
var result = doPerformWithError(exceptionClass);
result.andExpect(jsonPath("$.detail").exists());
}
@ParameterizedTest
@MethodSource("exceptionAndExpectedStatus")
@SneakyThrows
void shouldRespondWithInstance(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) {
var result = doPerformWithError(exceptionClass);
result.andExpect(jsonPath("$.instance").exists());
}
@ParameterizedTest
@MethodSource("exceptionAndExpectedStatus")
@SneakyThrows
void shouldRespondWithType(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) {
var result = doPerformWithError(exceptionClass);
result.andExpect(jsonPath("$.type").exists());
}
private static Stream<Arguments> exceptionAndExpectedStatus() {
return STATUS_BY_EXCEPTION.entrySet().stream().map(kv -> Arguments.of(kv.getKey(), kv.getValue()));
}
@SneakyThrows
private ResultActions doPerformWithError(Class<? extends Exception> exceptionClass) {
return mockMvc.perform(get("/test-error").param("errorClassName", exceptionClass.getName()));
return mockMvc.perform(get("/api/test-error").param("errorClassName", exceptionClass.getName()));
}
}
......
......@@ -19,7 +19,7 @@
* Die sprachspezifischen Genehmigungen und Beschränkungen
* unter der Lizenz sind dem Lizenztext zu entnehmen.
*/
package de.ozgcloud.admin.errorhandling;
package de.ozgcloud.admin.common.errorhandling;
import java.util.Collections;
import java.util.Map;
......@@ -34,11 +34,9 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import de.ozgcloud.common.errorhandling.TechnicalException;
import io.micrometer.common.lang.NonNullApi;
@RestController
@RequestMapping("/test-error")
@NonNullApi
@RequestMapping("/api/test-error")
class TestErrorController {
@FunctionalInterface
......@@ -54,13 +52,12 @@ class TestErrorController {
ConstraintViolationException.class, () -> new ConstraintViolationException(ERROR_MESSAGE, Collections.emptySet()),
ResourceNotFoundException.class, () -> new ResourceNotFoundException(ERROR_MESSAGE),
FunctionalException.class, () -> new FunctionalException(() -> ERROR_MESSAGE),
TechnicalException.class, () -> new TechnicalException(ERROR_MESSAGE)
);
TechnicalException.class, () -> new TechnicalException(ERROR_MESSAGE));
@GetMapping
String throwException(@RequestParam String errorClassName) throws Exception {
throw EXCEPTION_PRODUCER.get(
Class.forName(errorClassName)
).produceException();
Class.forName(errorClassName)).produceException();
}
}
......@@ -22,11 +22,11 @@ import de.ozgcloud.admin.RootController;
import lombok.SneakyThrows;
@ExtendWith(MockitoExtension.class)
class FrontendEnvironmentControllerTest {
class EnvironmentControllerTest {
@Spy
@InjectMocks
private FrontendEnvironmentController controller;
private EnvironmentController controller;
@Mock
private ProductionProperties environmentProperties;
......@@ -120,7 +120,7 @@ class FrontendEnvironmentControllerTest {
@SneakyThrows
private ResultActions doRequest() {
return mockMvc.perform(get(FrontendEnvironmentController.PATH));
return mockMvc.perform(get(EnvironmentController.PATH));
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment