diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceController.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceController.java index 34cb629b69da077fa29ba9fa5f939286f2349f09..a0ccfcd416ac66767589bc373197b2238d4e99c5 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceController.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceController.java @@ -12,6 +12,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import de.ozgcloud.alfa.common.errorhandling.ResourceNotFoundException; +import de.ozgcloud.common.errorhandling.TechnicalException; import jakarta.validation.constraints.NotBlank; import lombok.RequiredArgsConstructor; @@ -32,10 +33,15 @@ public class OzgcloudResourceController { if (resourceLink.isEmpty()) { throw new ResourceNotFoundException(OzgcloudResource.class, uri); } - return assembler.toModel(new OzgcloudResourceMapping(uri, resourceLink.get())); + return assembler.toModel(new OzgcloudResourceURIResolveResult(uri, resourceLink.get())); } private Optional<Link> resolveUri(String uri) { - return resolvers.stream().map(resolver -> resolver.resolve(uri)).filter(Optional::isPresent).map(Optional::get).findFirst(); + return resolvers.stream() + .map(resolver -> resolver.resolve(uri)) + .flatMap(Optional::stream) + .reduce((r1, r2) -> { + throw new TechnicalException("Multiple resolvers accepted uri " + uri); + }); } } diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssembler.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssembler.java index 7d828ec372a6ad6df80d7f7fa1ff8838724afaca..e3e83cf3a97ba6615974c72667fb32b976b6a733 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssembler.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssembler.java @@ -11,11 +11,11 @@ import lombok.RequiredArgsConstructor; @Component @RequiredArgsConstructor -class OzgcloudResourceModelAssembler implements RepresentationModelAssembler<OzgcloudResourceMapping, EntityModel<OzgcloudResource>> { +class OzgcloudResourceModelAssembler implements RepresentationModelAssembler<OzgcloudResourceURIResolveResult, EntityModel<OzgcloudResource>> { @Override - public EntityModel<OzgcloudResource> toModel(OzgcloudResourceMapping resourceMapping) { - return EntityModel.of(new OzgcloudResource()).add(getSelfLink(resourceMapping.getResourceURI())).add(resourceMapping.getResourceLink()); + public EntityModel<OzgcloudResource> toModel(OzgcloudResourceURIResolveResult uriResolveResult) { + return EntityModel.of(new OzgcloudResource()).add(getSelfLink(uriResolveResult.getResourceURI())).add(uriResolveResult.getResourceLink()); } private Link getSelfLink(String uri) { diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceProcessor.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessor.java similarity index 85% rename from alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceProcessor.java rename to alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessor.java index f7767df8c319f62308c4b10983bb376f764910c5..ebe46beb467ae69720dafe31da6121fcd4b4a956 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceProcessor.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessor.java @@ -9,7 +9,7 @@ import org.springframework.stereotype.Component; import de.ozgcloud.alfa.Root; @Component -class OzgcloudResourceProcessor implements RepresentationModelProcessor<EntityModel<Root>> { +class OzgcloudResourceRootProcessor implements RepresentationModelProcessor<EntityModel<Root>> { static final String REL_RESOURCE = "resource"; diff --git a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceMapping.java b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResult.java similarity index 83% rename from alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceMapping.java rename to alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResult.java index a5fa7275db45c5065c4b6e0bf722760171bb7d66..edcbd9ef072905e7a30930396e1afa0d68a90aa3 100644 --- a/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceMapping.java +++ b/alfa-service/src/main/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResult.java @@ -9,7 +9,7 @@ import lombok.ToString; @Builder @Getter @ToString -public class OzgcloudResourceMapping { +public class OzgcloudResourceURIResolveResult { private final String resourceURI; private final Link resourceLink; } diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceProcessorITCase.java b/alfa-service/src/test/java/de/ozgcloud/alfa/RootControllerITCase.java similarity index 79% rename from alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceProcessorITCase.java rename to alfa-service/src/test/java/de/ozgcloud/alfa/RootControllerITCase.java index 5997d4de6cd657d3252315eed8d3d72737036190..c4bc47bb1aba700a268c32f282fb569ecb3f909e 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceProcessorITCase.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/RootControllerITCase.java @@ -1,4 +1,4 @@ -package de.ozgcloud.alfa.resource; +package de.ozgcloud.alfa; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @@ -14,6 +14,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; 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.alfa.common.user.CurrentUserService; import de.ozgcloud.alfa.common.user.UserProfileTestFactory; @@ -21,7 +22,7 @@ import de.ozgcloud.alfa.common.user.UserProfileTestFactory; @AutoConfigureMockMvc @SpringBootTest @WithMockUser -class OzgcloudResourceProcessorITCase { +class RootControllerITCase { @MockBean private CurrentUserService currentUserService; @@ -39,9 +40,13 @@ class OzgcloudResourceProcessorITCase { @Test void shouldAddResourceLink() throws Exception { - var response = mockMvc.perform(get("/api")); + var response = doRequest(); - response.andExpect(jsonPath("$._links.resource.href").value(StringEndsWith.endsWith(OzgcloudResourceController.PATH + "?uri={uri}"))); + response.andExpect(jsonPath("$._links.resource.href").value(StringEndsWith.endsWith("/api/resources?uri={uri}"))); } } + + private ResultActions doRequest() throws Exception { + return mockMvc.perform(get(RootController.PATH)).andExpect(status().isOk()); + } } diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerITCase.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerITCase.java index 6b25d598161219e51faf0ce4af73145ad5cc72ad..a545d2ee05325037544e883b529b7c39d4d9c991 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerITCase.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerITCase.java @@ -40,14 +40,14 @@ class OzgcloudResourceControllerITCase { } @Test - void shouldReturnVorgangUrl() throws Exception { + void shouldHaveVorgangLink() throws Exception { var response = doRequest("ozgcloud://test.de/vorgangs/" + VORGANG_ID); response.andExpect(jsonPath("$._links.vorgang.href").value(StringEndsWith.endsWith("/api/vorgangs/" + VORGANG_ID))); } @Test - void shouldEncodeUriInSelfRel() throws Exception { + void shouldHaveSelfLink() throws Exception { var uri = "ozgcloud://test.de/vorgangs/" + VORGANG_ID; var encodedUri = URLEncoder.encode(uri, StandardCharsets.UTF_8); diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerTest.java index dc1fb742282166b03c5c1b051f604201360940cc..9ea5e3d62933188bc4a839a69b7b3cb4d2c63cb1 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceControllerTest.java @@ -18,6 +18,7 @@ import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.RepresentationModel; import de.ozgcloud.alfa.common.errorhandling.ResourceNotFoundException; +import de.ozgcloud.common.errorhandling.TechnicalException; import lombok.SneakyThrows; class OzgcloudResourceControllerTest { @@ -45,20 +46,22 @@ class OzgcloudResourceControllerTest { @Nested class OnUriCouldBeResolved { - private final ArgumentMatcher<OzgcloudResourceMapping> HAS_MATCHING_RESOURCE_URI = mapping -> mapping.getResourceURI().equals(OzgcloudResourceMappingTestFactory.RESOURCE_URI); - private final ArgumentMatcher<OzgcloudResourceMapping> HAS_MATCHING_RESOURCE_LINK = mapping -> mapping.getResourceLink().equals(OzgcloudResourceMappingTestFactory.RESOURCE_LINK); + private final ArgumentMatcher<OzgcloudResourceURIResolveResult> HAS_MATCHING_RESOURCE_URI = mapping -> mapping.getResourceURI().equals( + OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI); + private final ArgumentMatcher<OzgcloudResourceURIResolveResult> HAS_MATCHING_RESOURCE_LINK = mapping -> mapping.getResourceLink().equals( + OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK); @BeforeEach void init() { - when(resourceBResolver.resolve(OzgcloudResourceMappingTestFactory.RESOURCE_URI)).thenReturn(Optional.of( - OzgcloudResourceMappingTestFactory.RESOURCE_LINK)); + when(resourceBResolver.resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI)).thenReturn(Optional.of( + OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK)); } @Test void shouldCallResolver() { callController(); - verify(resourceBResolver).resolve(OzgcloudResourceMappingTestFactory.RESOURCE_URI); + verify(resourceBResolver).resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI); } @Test @@ -92,8 +95,8 @@ class OzgcloudResourceControllerTest { @BeforeEach void init() { - when(resourceAResolver.resolve(OzgcloudResourceMappingTestFactory.RESOURCE_URI)).thenReturn(Optional.empty()); - when(resourceBResolver.resolve(OzgcloudResourceMappingTestFactory.RESOURCE_URI)).thenReturn(Optional.empty()); + when(resourceAResolver.resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI)).thenReturn(Optional.empty()); + when(resourceBResolver.resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI)).thenReturn(Optional.empty()); } @Test @@ -102,9 +105,26 @@ class OzgcloudResourceControllerTest { } } + @Nested + class OnMultipleResolveResults { + + @BeforeEach + void init() { + when(resourceAResolver.resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI)).thenReturn(Optional.of( + OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK)); + when(resourceBResolver.resolve(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI)).thenReturn(Optional.of( + OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK)); + } + + @Test + void shouldThrowTechnicalException() { + assertThatThrownBy(TestGetOzgcloudResource.this::callController).isInstanceOf(TechnicalException.class); + } + } + @SneakyThrows private RepresentationModel<EntityModel<OzgcloudResource>> callController() { - return controller.getOzgcloudResource(OzgcloudResourceMappingTestFactory.RESOURCE_URI); + return controller.getOzgcloudResource(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_URI); } } } diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceMappingTestFactory.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceMappingTestFactory.java deleted file mode 100644 index 0115dba262580a11081e5d1cb11ad86b3d283e4e..0000000000000000000000000000000000000000 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceMappingTestFactory.java +++ /dev/null @@ -1,19 +0,0 @@ -package de.ozgcloud.alfa.resource; - -import org.springframework.hateoas.Link; - -import com.thedeanda.lorem.LoremIpsum; - -class OzgcloudResourceMappingTestFactory { - - public static final String RESOURCE_URI = String.format("%s://%s.%s/%s", (Object[]) LoremIpsum.getInstance().getWords(4).split("\\s")); - public static final Link RESOURCE_LINK = Link.of(LoremIpsum.getInstance().getUrl()).withRel(LoremIpsum.getInstance().getWords(1)); - - public static OzgcloudResourceMapping create() { - return createBuilder().build(); - } - - public static OzgcloudResourceMapping.OzgcloudResourceMappingBuilder createBuilder() { - return OzgcloudResourceMapping.builder().resourceURI(RESOURCE_URI).resourceLink(RESOURCE_LINK); - } -} diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssemblerTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssemblerTest.java index bccc844a48030536ef4f7c3637509da6e82878ca..ed144040a39978e418d2248ca496007c4c4f05ac 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssemblerTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceModelAssemblerTest.java @@ -3,15 +3,12 @@ package de.ozgcloud.alfa.resource; import static de.ozgcloud.alfa.resource.OzgcloudResourceController.*; import static org.assertj.core.api.Assertions.*; -import java.net.URI; - import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.springframework.hateoas.EntityModel; import org.springframework.hateoas.IanaLinkRelations; - -import lombok.SneakyThrows; +import org.springframework.hateoas.Link; class OzgcloudResourceModelAssemblerTest { @@ -21,59 +18,26 @@ class OzgcloudResourceModelAssemblerTest { @Nested class TestToModel { - private final OzgcloudResourceMapping resourceMapping = OzgcloudResourceMappingTestFactory.create(); - - @Nested - class TestSelfLink { - - @Test - void shouldExist() { - var model = callAssembler(); - - assertThat(model.getLink(IanaLinkRelations.SELF_VALUE)).isPresent(); - } - - @Test - void shouldContainControllerPath() { - var uri = getSelfURI(callAssembler()); + private final OzgcloudResourceURIResolveResult uriResolveResult = OzgcloudResourceURIResolveResultTestFactory.create(); - assertThat(uri).extracting(URI::getPath).isEqualTo(OzgcloudResourceController.PATH); - } + @Test + void shouldHaveSelfLink() { + var model = callAssembler(); - @Test - void shouldContainResourceUri() { - var uri = getSelfURI(callAssembler()); - - assertThat(uri).extracting(URI::getQuery).isEqualTo(PARAM_URI + "=" + OzgcloudResourceMappingTestFactory.RESOURCE_URI); - } - - @SneakyThrows - private URI getSelfURI(EntityModel<OzgcloudResource> model) { - return new URI(model.getLink(IanaLinkRelations.SELF_VALUE).orElseThrow().getHref()); - } + assertThat(model.getLink(IanaLinkRelations.SELF_VALUE)).isPresent().get().extracting(Link::getHref) + .isEqualTo(OzgcloudResourceController.PATH + "?" + PARAM_URI + "=" + OzgcloudResourceURIResolveResultTestFactory.ENCODED_RESOURCE_URI); } - @Nested - class TestResourceLink { - - @Test - void shouldExist() { - var model = callAssembler(); - - assertThat(model.hasLink(OzgcloudResourceMappingTestFactory.RESOURCE_LINK.getRel())).isTrue(); - } - - @Test - void shouldEqualToLinkFromMapping() { - var model = callAssembler(); + @Test + void shouldHaveResourceLink() { + var model = callAssembler(); - assertThat(model.getLink(OzgcloudResourceMappingTestFactory.RESOURCE_LINK.getRel())).get().isEqualTo( - OzgcloudResourceMappingTestFactory.RESOURCE_LINK); - } + assertThat(model.getLink(OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK.getRel())).isPresent().get().isEqualTo( + OzgcloudResourceURIResolveResultTestFactory.RESOURCE_LINK); } private EntityModel<OzgcloudResource> callAssembler() { - return assembler.toModel(resourceMapping); + return assembler.toModel(uriResolveResult); } } } diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceProcessorTest.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessorTest.java similarity index 73% rename from alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceProcessorTest.java rename to alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessorTest.java index 3ede66be1d63319c9cfec6054a1f040c57b9aa9e..71d60de1e746dd5f801b5d0a4f87b0d93493bcc7 100644 --- a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceProcessorTest.java +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceRootProcessorTest.java @@ -10,9 +10,9 @@ import org.springframework.hateoas.Link; import de.ozgcloud.alfa.Root; import de.ozgcloud.alfa.RootTestFactory; -class OzgcloudResourceProcessorTest { +class OzgcloudResourceRootProcessorTest { - private final OzgcloudResourceProcessor processor = new OzgcloudResourceProcessor(); + private final OzgcloudResourceRootProcessor processor = new OzgcloudResourceRootProcessor(); @Nested class TestProcess { @@ -30,7 +30,7 @@ class OzgcloudResourceProcessorTest { void shouldAddResourceLink() { processor.process(model); - assertThat(model.getLink(OzgcloudResourceProcessor.REL_RESOURCE)).isPresent().get().extracting(Link::getHref) + assertThat(model.getLink(OzgcloudResourceRootProcessor.REL_RESOURCE)).isPresent().get().extracting(Link::getHref) .isEqualTo(OzgcloudResourceController.PATH + "?uri={uri}"); } } diff --git a/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResultTestFactory.java b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResultTestFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..dd0ea565f584133ece1265c2c2a9782135a65a74 --- /dev/null +++ b/alfa-service/src/test/java/de/ozgcloud/alfa/resource/OzgcloudResourceURIResolveResultTestFactory.java @@ -0,0 +1,23 @@ +package de.ozgcloud.alfa.resource; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +import org.springframework.hateoas.Link; + +import com.thedeanda.lorem.LoremIpsum; + +class OzgcloudResourceURIResolveResultTestFactory { + + public static final String RESOURCE_URI = String.format("%s://%s.%s/%s", (Object[]) LoremIpsum.getInstance().getWords(4).split("\\s")); + public static final String ENCODED_RESOURCE_URI = URLEncoder.encode(RESOURCE_URI, StandardCharsets.UTF_8); + public static final Link RESOURCE_LINK = Link.of(LoremIpsum.getInstance().getUrl()).withRel(LoremIpsum.getInstance().getWords(1)); + + public static OzgcloudResourceURIResolveResult create() { + return createBuilder().build(); + } + + public static OzgcloudResourceURIResolveResult.OzgcloudResourceURIResolveResultBuilder createBuilder() { + return OzgcloudResourceURIResolveResult.builder().resourceURI(RESOURCE_URI).resourceLink(RESOURCE_LINK); + } +}