Skip to content

Commit

Permalink
Merge pull request #375 from groldan/bug/webui_homepage_links_upgrade
Browse files Browse the repository at this point in the history
Fix home page service links for GWC
  • Loading branch information
groldan authored Nov 25, 2023
2 parents b647b29 + 5766563 commit 94a5010
Show file tree
Hide file tree
Showing 5 changed files with 201 additions and 87 deletions.
2 changes: 1 addition & 1 deletion config
Submodule config updated 1 files
+1 −1 geoserver.yml
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ services:
rabbitmq:
image: rabbitmq:3.11-management
user: ${GS_USER}
restart: always
#restart: always
volumes:
- rabbitmq_data:/var/lib/rabbitmq
networks:
Expand Down
16 changes: 8 additions & 8 deletions src/apps/geoserver/webui/src/main/resources/bootstrap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,16 @@ geoserver:
file-browser.hide-file-system: true
# These are all default values, here just for reference. You can omit them and add only the ones to disable or further configure
security.enabled: true
wfs.enabled: true
wms.enabled: true
wcs.enabled: true
wps.enabled: false # not working yet
wfs.enabled: ${webui.wfs.enabled:true}
wms.enabled: ${webui.wms.enabled:true}
wcs.enabled: ${webui.wcs.enabled:true}
wps.enabled: ${webui.wps.enabled:true}
gwc:
enabled: true
enabled: ${gwc.enabled:true}
capabilities:
tms: true
wmts: true
wmsc: true
tms: ${gwc.services.tms:true}
wmts: ${gwc.services.wmts:true}
wmsc: ${gwc.services.wms:false}
extensions:
importer.enabled: true
demos:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
package org.geoserver.cloud.autoconfigure.web.gwc;

import lombok.extern.slf4j.Slf4j;

import org.geoserver.catalog.PublishedInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.cloud.autoconfigure.gwc.GoServerWebUIConfigurationProperties;
import org.geoserver.cloud.autoconfigure.gwc.GoServerWebUIConfigurationProperties.CapabilitiesConfig;
import org.geoserver.config.GeoServer;
import org.geoserver.config.ServiceInfo;
import org.geoserver.gwc.GWC;
import org.geoserver.gwc.config.GWCConfig;
import org.geoserver.gwc.web.GWCServiceDescriptionProvider;
import org.geoserver.gwc.wmts.WMTSInfo;
import org.geoserver.web.ServiceDescription;
import org.geoserver.web.ServiceDescriptionProvider;
import org.geoserver.web.ServiceLinkDescription;
import org.geotools.util.Version;

import java.util.ArrayList;
import java.util.List;

/**
* GeoServer-Cloud replacement of {@link GWCServiceDescriptionProvider}
* <p>
* Doesn't check for the availability of the GWC service beans in the
* application context, as they're not present in the web-ui service. E.g.:
*
* <pre>
* {@code if (gwcConfig.isTMSEnabled())...}
* </pre>
*
* instead of
*
* <pre>
* {@code if (gwcConfig.isTMSEnabled() && null != app.getBean("gwcServiceTMS"))...
* }
*/
@Slf4j(topic = "org.geoserver.cloud.autoconfigure.web.gwc")
class CloudGWCServiceDescriptionProvider extends ServiceDescriptionProvider {

/** Service type to cross-link between service description and service link description. */
public static final String SERVICE_TYPE = "WMTS";

private final GWC gwc;
private final GeoServer geoserver;

/**
* whether gwc services are available at all (i.e. deployed), regardless of its enabled config
* state in {@link GWCConfig}
*/
private GoServerWebUIConfigurationProperties staticConfig;

public CloudGWCServiceDescriptionProvider(
GWC gwc, GeoServer gs, GoServerWebUIConfigurationProperties staticConfig) {
this.gwc = gwc;
this.geoserver = gs;
this.staticConfig = staticConfig;

CapabilitiesConfig caps = staticConfig.getCapabilities();
if (caps == null) {
caps = new CapabilitiesConfig();
staticConfig.setCapabilities(caps);
}
logEnabled(caps.isTms(), GoServerWebUIConfigurationProperties.CAPABILITIES_TMS);
logEnabled(caps.isWmts(), GoServerWebUIConfigurationProperties.CAPABILITIES_WMTS);
logEnabled(caps.isWmsc(), GoServerWebUIConfigurationProperties.CAPABILITIES_WMSC);
}

private void logEnabled(boolean value, String key) {
log.info("{} {}", key, value ? "enabled" : "disabled");
}

/**
* Lookup WMTSInfo using workspaceInfo / layerInfo context.
*
* @param workspaceInfo Workspace, or null for global.
* @param layerInfo Layer, LayerGroup, or null for any
* @return WMTSInfo if available for workspace, or global WMTSInfo.
*/
protected WMTSInfo info(WorkspaceInfo workspaceInfo, PublishedInfo layerInfo) {
WMTSInfo info = null;
if (workspaceInfo != null) {
info = geoserver.getService(workspaceInfo, WMTSInfo.class);
}
if (info == null) {
info = geoserver.getService(WMTSInfo.class);
}
return info;
}

/** GWC-bases services don't have layer-specific enabling... */
@Override
protected boolean isAvailable(String serviceType, ServiceInfo service, PublishedInfo layer) {
return service.isEnabled() && (layer == null ? true : layer.isEnabled());
}

@Override
public List<ServiceDescription> getServices(WorkspaceInfo workspace, PublishedInfo layer) {

WMTSInfo info = info(workspace, layer);

if (workspace != null || geoserver.getGlobal().isGlobalServices()) {
return List.of(description(SERVICE_TYPE, info, workspace, layer));
}
return List.of();
}

private String basePath(WorkspaceInfo workspace, PublishedInfo layer) {

String basePath = "/gwc/service";
if (workspace != null) {
basePath = "/" + workspace.getName() + basePath;
}
if (layer != null) {
basePath = "/" + layer.getName() + basePath;
}
return ".." + basePath;
}

private String createLinkWMSC(WorkspaceInfo workspace, PublishedInfo layer) {
return basePath(workspace, layer)
+ "/wms?service=WMS&version=1.1.1&request=GetCapabilities&tiled=true";
}

private String createLinkWMTS(WorkspaceInfo workspace, PublishedInfo layer) {
return basePath(workspace, layer)
+ "/wmts?service=WMTS&version=1.1.1&request=GetCapabilities";
}

private String createLinkTMS(WorkspaceInfo workspace, PublishedInfo layer) {
return basePath(workspace, layer) + "/tms/1.0.0";
}

@Override
public List<ServiceLinkDescription> getServiceLinks(
WorkspaceInfo workspaceInfo, PublishedInfo layerInfo) {

if (workspaceInfo == null && !geoserver.getGlobal().isGlobalServices()) {
return List.of();
}

WMTSInfo wmtsInfo = info(workspaceInfo, layerInfo);
CapabilitiesConfig caps = staticConfig.getCapabilities();

final GWCConfig gwcConfig = gwc.getConfig();

String workspace = workspaceInfo != null ? workspaceInfo.getName() : null;
String layer = layerInfo != null ? layerInfo.getName() : null;

List<ServiceLinkDescription> links = new ArrayList<>();

boolean wmtsDeployed = caps.isWmts();
boolean wmscDeployed = caps.isWmsc();
boolean tmsDeployed = caps.isTms();

if (wmtsDeployed && wmtsInfo.isEnabled()) {
Version version = new Version("1.1.1");
String link = createLinkWMTS(workspaceInfo, layerInfo);
String protocol = "WMTS";
links.add(serviceLink(workspace, layer, version, protocol, link));
}

if (wmscDeployed && gwcConfig.isWMSCEnabled()) {
Version version = new Version("1.1.1");
String protocol = "WMS-C";
String link = createLinkWMSC(workspaceInfo, layerInfo);
links.add(serviceLink(workspace, layer, version, protocol, link));
}

if (tmsDeployed && gwcConfig.isTMSEnabled()) {
Version version = new Version("1.0.0");
String link = createLinkTMS(workspaceInfo, layerInfo);
String protocol = "TMS";
links.add(serviceLink(workspace, layer, version, protocol, link));
}

return links;
}

private ServiceLinkDescription serviceLink(
String workspaceName, String layerName, Version version, String protocol, String link) {
return new ServiceLinkDescription(
SERVICE_TYPE, version, link, workspaceName, layerName, protocol);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,18 @@
*/
package org.geoserver.cloud.autoconfigure.web.gwc;

import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import org.apache.wicket.Component;
import org.geoserver.cloud.autoconfigure.gwc.ConditionalOnGeoServerWebUIEnabled;
import org.geoserver.cloud.autoconfigure.gwc.GoServerWebUIConfigurationProperties;
import org.geoserver.cloud.autoconfigure.gwc.GoServerWebUIConfigurationProperties.CapabilitiesConfig;
import org.geoserver.cloud.config.factory.FilteringXmlBeanDefinitionReader;
import org.geoserver.config.GeoServer;
import org.geoserver.gwc.GWC;
import org.geoserver.gwc.config.GWCConfig;
import org.geoserver.gwc.wmts.WMTSInfo;
import org.geoserver.web.CapabilitiesHomePageLinkProvider;
import org.geoserver.web.CapabilitiesHomePagePanel;
import org.geoserver.web.CapabilitiesHomePagePanel.CapsInfo;
import org.geotools.util.Version;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;

/**
Expand Down Expand Up @@ -61,74 +48,15 @@ public class GeoServerWebUIAutoConfiguration {
* Disable disk-quota by brute force for now. We need to resolve how and where to store the
* configuration and database.
*/
static final String EXCLUDED_BEANS = "diskQuotaMenuPage|GWCCapabilitiesHomePageProvider";
static final String EXCLUDED_BEANS = "diskQuotaMenuPage|wmtsServiceDescriptor";

public @PostConstruct void log() {
log.info("{} enabled", GoServerWebUIConfigurationProperties.ENABLED);
}

private void logEnabled(boolean value, String key) {
log.info("{} {}", key, value ? "enabled" : "disabled");
}

@Bean(name = "GWCCapabilitiesHomePageProvider")
CloudGwcCapabilitiesHomePageProvider cloudGwcCapabilitiesHomePageProvider(
GoServerWebUIConfigurationProperties props, GeoServer geoServer) {

CapabilitiesConfig caps = props.getCapabilities();
if (caps == null) {
caps = new CapabilitiesConfig();
props.setCapabilities(caps);
}
logEnabled(caps.isTms(), GoServerWebUIConfigurationProperties.CAPABILITIES_TMS);
logEnabled(caps.isWmts(), GoServerWebUIConfigurationProperties.CAPABILITIES_WMTS);
logEnabled(caps.isWmsc(), GoServerWebUIConfigurationProperties.CAPABILITIES_WMSC);

return new CloudGwcCapabilitiesHomePageProvider(props, geoServer);
}

/**
* Replacement of {@link GWCCapabilitiesHomePageProvider} not requiring the actual GWC services
* being exposed, since this is supposed to run on gs-web, and the capabilities won't be served
* by the web-ui microservice, but by gwc-service
*
* @since 1.0
*/
@RequiredArgsConstructor
static class CloudGwcCapabilitiesHomePageProvider implements CapabilitiesHomePageLinkProvider {

private final @NonNull GoServerWebUIConfigurationProperties staticConfig;
private final @NonNull GeoServer geoServer;

@Override
public Component getCapabilitiesComponent(String id) {
List<CapsInfo> getCapsUIContribs = new ArrayList<>();

final GWCConfig liveConfig = GWC.get().getConfig();
final CapabilitiesConfig staticCapabilitiesConfig = staticConfig.getCapabilities();

if (staticCapabilitiesConfig.isWmsc() && liveConfig.isWMSCEnabled()) {
getCapsUIContribs.add(
newCaps(
"WMS-C",
"1.1.1",
"../gwc/service/wms?request=GetCapabilities&version=1.1.1&tiled=true"));
}
WMTSInfo tmsInfo = geoServer.getService(WMTSInfo.class);
if (staticCapabilitiesConfig.isTms() && tmsInfo != null && tmsInfo.isEnabled()) {
getCapsUIContribs.add(
newCaps("WMTS", "1.0.0", "../gwc/service/wmts?REQUEST=GetCapabilities"));
}

if (staticCapabilitiesConfig.isTms() && liveConfig.isTMSEnabled()) {
getCapsUIContribs.add(newCaps("TMS", "1.0.0", "../gwc/service/tms/1.0.0"));
}

return new CapabilitiesHomePagePanel(id, getCapsUIContribs);
}

private CapsInfo newCaps(String name, String version, String uri) {
return new CapsInfo(name, new Version(version), uri);
}
@Bean
CloudGWCServiceDescriptionProvider cloudGWCServiceDescriptionProvider(
GWC gwc, GeoServer gs, GoServerWebUIConfigurationProperties staticConfig) {
return new CloudGWCServiceDescriptionProvider(gwc, gs, staticConfig);
}
}

0 comments on commit 94a5010

Please sign in to comment.