diff --git a/src/apps/geoserver/gwc/pom.xml b/src/apps/geoserver/gwc/pom.xml index 53eca065a..50b25f864 100644 --- a/src/apps/geoserver/gwc/pom.xml +++ b/src/apps/geoserver/gwc/pom.xml @@ -49,6 +49,19 @@ spring-boot-starter-test test + + org.geoserver.cloud.catalog + gs-cloud-catalog-plugin + ${project.version} + test-jar + test + + + * + * + + + diff --git a/src/apps/geoserver/gwc/src/test/java/org/geoserver/cloud/gwc/app/GeoWebCacheApplicationTest.java b/src/apps/geoserver/gwc/src/test/java/org/geoserver/cloud/gwc/app/GeoWebCacheApplicationTest.java index 870631ea3..9f7fcd5f1 100644 --- a/src/apps/geoserver/gwc/src/test/java/org/geoserver/cloud/gwc/app/GeoWebCacheApplicationTest.java +++ b/src/apps/geoserver/gwc/src/test/java/org/geoserver/cloud/gwc/app/GeoWebCacheApplicationTest.java @@ -11,17 +11,28 @@ import com.google.gson.JsonElement; import com.google.gson.JsonParser; +import org.geoserver.catalog.Catalog; +import org.geoserver.catalog.CatalogTestData; +import org.geoserver.config.GeoServer; +import org.geoserver.gwc.controller.GwcUrlHandlerMapping; import org.json.simple.parser.ParseException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.context.ApplicationContext; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; + +import java.io.File; @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @ActiveProfiles("test") @@ -29,11 +40,35 @@ class GeoWebCacheApplicationTest { @Autowired private TestRestTemplate restTemplate; + @Autowired private Catalog catalog; + @Autowired private GeoServer geoServer; + + @Qualifier("rawCatalog") + @Autowired + Catalog rawCatalog; + + @Autowired private ApplicationContext context; + + @TempDir static File tmpDir; + + @DynamicPropertySource + static void registerPgProperties(DynamicPropertyRegistry registry) { + registry.add("geoserver.backend.data-directory.location", tmpDir::getAbsolutePath); + registry.add("geoserver.backend.data-directory.enabled", () -> true); + registry.add("spring.cloud.config.enabled", () -> false); + registry.add("spring.cloud.config.discovery.enabled", () -> false); + registry.add("spring.cloud.discovery.enabled", () -> false); + registry.add("spring.cloud.bus.enabled", () -> false); + registry.add("eureka.client.enabled", () -> false); + } + @BeforeEach void before() { restTemplate = restTemplate.withBasicAuth("admin", "geoserver"); String rootUri = restTemplate.getRootUri(); assertThat(rootUri).isNotEmpty(); + CatalogTestData data = + CatalogTestData.initialized(() -> rawCatalog, () -> geoServer).initialize(); } @Test @@ -54,6 +89,26 @@ void testRESTPathExtensionContentNegotiation() { testGetRequestContentType("/gwc/rest/layers.xml", APPLICATION_XML); } + @Test + void testGwcUrlHandlerMappingArePresentInTheClasspathAndLocalWorkspaceUrlsAreHandled() { + assertThat(context.isTypeMatch("gwcDemoUrlHandlerMapping", GwcUrlHandlerMapping.class)) + .as("expected a bean gwcDemoUrlHandlerMapping of type GwcUrlHandlerMapping") + .isTrue(); + assertThat(context.isTypeMatch("gwcRestWebUrlHandlerMapping", GwcUrlHandlerMapping.class)) + .as("expected a bean gwcRestWebUrlHandlerMapping of type GwcUrlHandlerMapping") + .isTrue(); + + ResponseEntity response = + restTemplate.getForEntity("/wsName/gwc/demo/layer1", String.class); + + assertThat(response.getStatusCode()) + .as( + String.format( + "expected a HTTP return code 200, got %s", + response.getStatusCode())) + .isEqualTo(HttpStatus.OK); + } + protected ResponseEntity testGetRequestContentType(String uri, MediaType expected) { ResponseEntity response = restTemplate.getForEntity(uri, String.class); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); diff --git a/src/gwc/autoconfigure/src/main/java/org/geoserver/cloud/autoconfigure/web/gwc/GeoWebCacheUIAutoConfiguration.java b/src/gwc/autoconfigure/src/main/java/org/geoserver/cloud/autoconfigure/web/gwc/GeoWebCacheUIAutoConfiguration.java index 39f5aee81..e266181dd 100644 --- a/src/gwc/autoconfigure/src/main/java/org/geoserver/cloud/autoconfigure/web/gwc/GeoWebCacheUIAutoConfiguration.java +++ b/src/gwc/autoconfigure/src/main/java/org/geoserver/cloud/autoconfigure/web/gwc/GeoWebCacheUIAutoConfiguration.java @@ -6,15 +6,18 @@ import lombok.extern.slf4j.Slf4j; -import org.geoserver.cloud.autoconfigure.gwc.ConditionalOnGeoWebCacheRestConfigEnabled; +import org.geoserver.catalog.Catalog; import org.geoserver.cloud.autoconfigure.gwc.ConditionalOnWebUIEnabled; import org.geoserver.cloud.gwc.config.core.GeoWebCacheConfigurationProperties; +import org.geoserver.gwc.controller.GwcUrlHandlerMapping; import org.geowebcache.GeoWebCacheDispatcher; import org.geowebcache.rest.controller.ByteStreamController; import org.gwc.web.rest.GeoWebCacheController; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations; import org.springframework.context.annotation.Bean; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import javax.annotation.PostConstruct; @@ -32,13 +35,51 @@ GeoWebCacheController gwcController(GeoWebCacheDispatcher gwcDispatcher) { return new GeoWebCacheController(gwcDispatcher); } - /** - * Provide a handler for static web resources if missing, for example, because {@link - * ConditionalOnGeoWebCacheRestConfigEnabled} is disabled - */ + /** ConditionalOnGeoWebCacheRestConfigEnabled} is disabled */ @Bean @ConditionalOnMissingBean(ByteStreamController.class) ByteStreamController byteStreamController() { return new ByteStreamController(); } + + /** + * GS's src/web/gwc/src/main/java/applicationContext.xml + * + * + * + * + * + * + * + */ + @Bean + WebMvcRegistrations gwcDemoUrlHandlerMapping(Catalog catalog) { + GwcUrlHandlerMapping handler = new GwcUrlHandlerMapping(catalog, "/gwc/demo"); + handler.setAlwaysUseFullPath(true); + handler.setOrder(10); + + return new WebMvcRegistrations() { + @Override + public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { + return handler; + } + }; + } + + @Bean + WebMvcRegistrations gwcRestWebUrlHandlerMapping(Catalog catalog) { + GwcUrlHandlerMapping handler = new GwcUrlHandlerMapping(catalog, "/gwc/rest/web"); + handler.setAlwaysUseFullPath(true); + handler.setOrder(10); + + return new WebMvcRegistrations() { + @Override + public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { + return handler; + } + }; + } } diff --git a/src/gwc/autoconfigure/src/test/java/org/geoserver/cloud/autoconfigure/gwc/web/gwc/GeoWebCacheUIAutoConfigurationTest.java b/src/gwc/autoconfigure/src/test/java/org/geoserver/cloud/autoconfigure/gwc/web/gwc/GeoWebCacheUIAutoConfigurationTest.java new file mode 100644 index 000000000..273bc1f05 --- /dev/null +++ b/src/gwc/autoconfigure/src/test/java/org/geoserver/cloud/autoconfigure/gwc/web/gwc/GeoWebCacheUIAutoConfigurationTest.java @@ -0,0 +1,38 @@ +package org.geoserver.cloud.autoconfigure.gwc.web.gwc; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.geoserver.cloud.autoconfigure.gwc.GeoWebCacheContextRunner; +import org.geoserver.cloud.autoconfigure.web.gwc.GeoWebCacheUIAutoConfiguration; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; + +import java.io.File; + +public class GeoWebCacheUIAutoConfigurationTest { + + WebApplicationContextRunner runner; + + @TempDir File tmpDir; + + @BeforeEach + void setUp() throws Exception { + runner = + GeoWebCacheContextRunner.newMinimalGeoWebCacheContextRunner(tmpDir) + .withPropertyValues("gwc.web-ui=true") + .withConfiguration( + AutoConfigurations.of(GeoWebCacheUIAutoConfiguration.class)); + } + + @Test + void beansForLocalWorkspacePathsHandlingArePresent() { + runner.run( + context -> { + assertNotNull(context.getBean("gwcDemoUrlHandlerMapping")); + assertNotNull(context.getBean("gwcRestWebUrlHandlerMapping")); + }); + } +} diff --git a/src/gwc/services/src/main/java/org/gwc/web/rest/GeoWebCacheController.java b/src/gwc/services/src/main/java/org/gwc/web/rest/GeoWebCacheController.java index 021920b80..5b8cc0400 100644 --- a/src/gwc/services/src/main/java/org/gwc/web/rest/GeoWebCacheController.java +++ b/src/gwc/services/src/main/java/org/gwc/web/rest/GeoWebCacheController.java @@ -25,19 +25,13 @@ *

Copied from {@link GeoServerGWCDispatcherController} */ @Controller -@RequestMapping("/gwc") +@RequestMapping(path = {"/gwc", "/{namespace}/gwc"}) @RequiredArgsConstructor public class GeoWebCacheController { private final @NonNull GeoWebCacheDispatcher gwcDispatcher; - @GetMapping( - path = { - "", - "/home", - "/demo/**", - "/proxy/**", - }) + @GetMapping(path = {"", "/home", "/demo/**", "/proxy/**"}) public void handleGet(HttpServletRequest request, HttpServletResponse response) throws Exception { gwcDispatcher.handleRequest(request, response);