Skip to content
Snippets Groups Projects
Commit 67f7c78a authored by Jan Zickermann's avatar Jan Zickermann
Browse files

OZG-4815 OZG-4832 Add links from root controller to `/api/config`

parent 82662756
Branches
Tags
No related merge requests found
......@@ -38,6 +38,10 @@
<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>
<!-- Dev -->
<dependency>
......
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 +16,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() {
......
/*
* 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
public 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()
);
}
}
spring:
data:
rest:
basePath: /api
\ No newline at end of file
basePath: /api/config
\ No newline at end of file
......@@ -53,7 +53,7 @@ class ApiRootITCase {
void shouldBetSetToApi() {
var basePath = restProperties.getBasePath();
assertEquals("/api", basePath);
assertEquals("/api/config", basePath);
}
@Test
......
......@@ -14,6 +14,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 +31,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();
}
......
/*
* 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.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);
}
@Nested
class TestLinks {
@DisplayName("should have href to Spring Data REST base path")
@Test
void shouldHaveConfigBaseLink() {
var root = RootTestFactory.create();
assertEquals(Optional.of(Link.of(BASE_PATH, REL_CONFIGURATION)), modelAssembler.toModel(root).getLink(REL_CONFIGURATION));
}
@DisplayName("should have href to self")
@Test
void shouldHaveSelfLink() {
var root = RootTestFactory.create();
assertEquals(Optional.of(Link.of(RootController.PATH)), modelAssembler.toModel(root).getLink(IanaLinkRelations.SELF));
}
}
}
\ No newline at end of file
......@@ -11,4 +11,15 @@ public class RootTestFactory {
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);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment