Skip to content

Commit

Permalink
Configure GWC lock provider with the cluster-aware geoserver lock pro…
Browse files Browse the repository at this point in the history
…vider
  • Loading branch information
groldan committed Oct 16, 2024
1 parent 7e0b185 commit 745eba1
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,15 @@
import org.geoserver.cloud.gwc.repository.CloudDefaultStorageFinder;
import org.geoserver.cloud.gwc.repository.CloudGwcXmlConfiguration;
import org.geoserver.cloud.gwc.repository.CloudXMLResourceProvider;
import org.geoserver.gwc.ConfigurableLockProvider;
import org.geoserver.gwc.GWC;
import org.geoserver.gwc.GeoServerLockProvider;
import org.geoserver.gwc.config.AbstractGwcInitializer;
import org.geoserver.gwc.config.DefaultGwcInitializer;
import org.geoserver.gwc.config.GWCConfig;
import org.geoserver.gwc.config.GWCConfigPersister;
import org.geoserver.platform.GeoServerExtensionsHelper;
import org.geowebcache.locks.LockProvider;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
Expand Down Expand Up @@ -65,6 +72,35 @@ void defaultCacheDirectoryIsAFile(@TempDir File tmpDir) throws IOException {
assertContextLoadFails(BeanInitializationException.class, "is not a directory");
}

@Test
void lockProviderDelegatesStoGeoSeverLockProvider() {
runner.run(
context -> {
GeoServerExtensionsHelper.init(context);
assertThat(context)
.hasNotFailed()
.hasBean(AbstractGwcInitializer.GWC_LOCK_PROVIDER_BEAN_NAME)
.getBean(AbstractGwcInitializer.GWC_LOCK_PROVIDER_BEAN_NAME)
.isInstanceOf(GeoServerLockProvider.class);

GWCConfigPersister persister = context.getBean(GWCConfigPersister.class);
GWCConfig config = persister.getConfig();
assertThat(config.getLockProviderName())
.isEqualTo(AbstractGwcInitializer.GWC_LOCK_PROVIDER_BEAN_NAME);

GWC gwc = GWC.get();

LockProvider lockProvider = gwc.getLockProvider();
assertThat(lockProvider).isInstanceOf(ConfigurableLockProvider.class);
GeoServerLockProvider expected =
context.getBean(
AbstractGwcInitializer.GWC_LOCK_PROVIDER_BEAN_NAME,
GeoServerLockProvider.class);
assertThat(((ConfigurableLockProvider) lockProvider).getDelegate())
.isSameAs(expected);
});
}

@Test
void contextLoads() {
runner.run(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@
import org.geoserver.cloud.gwc.repository.CloudDefaultStorageFinder;
import org.geoserver.cloud.gwc.repository.CloudGwcXmlConfiguration;
import org.geoserver.cloud.gwc.repository.CloudXMLResourceProvider;
import org.geoserver.gwc.GeoServerLockProvider;
import org.geoserver.gwc.config.AbstractGwcInitializer;
import org.geoserver.platform.resource.Resource;
import org.geoserver.platform.resource.ResourceStore;
import org.geoserver.platform.resource.Resources;
import org.geowebcache.config.ConfigurationResourceProvider;
import org.geowebcache.config.XMLConfiguration;
import org.geowebcache.config.XMLFileResourceProvider;
import org.geowebcache.locks.LockProvider;
import org.geowebcache.storage.DefaultStorageFinder;
import org.geowebcache.util.ApplicationContextProvider;
import org.springframework.beans.FatalBeanException;
Expand Down Expand Up @@ -61,6 +64,17 @@
@Slf4j(topic = "org.geoserver.cloud.gwc.config.core")
public class GeoWebCacheCoreConfiguration {

/**
* @return a {@link GeoServerLockProvider} delegating the the {@link ResourceStore}, whose
* {@link ResourceStore#getLockProvider()} is known to be cluster-capable
*/
@Bean(name = AbstractGwcInitializer.GWC_LOCK_PROVIDER_BEAN_NAME)
LockProvider gwcLockProvider(@Qualifier("resourceStoreImpl") ResourceStore resourceStore) {
var provider = new GeoServerLockProvider();
provider.setDelegate(resourceStore);
return provider;
}

@Bean
SetRequestPathInfoFilter setRequestPathInfoFilter() {
return new SetRequestPathInfoFilter();
Expand Down Expand Up @@ -283,9 +297,12 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
* </ul>
*/
protected ServletRequest adaptRequest(HttpServletRequest request) {
// full request URI (e.g. '/geoserver/cloud/{workspace}/gwc/service/tms/1.0.0', where
// '/geoserver/cloud' is the context path as given by the gateway's base uri, and
// '/{workspace}/gwc' the suffix after which comes the pathInfo '/service/tms/1.0.0')
// full request URI (e.g. '/geoserver/cloud/{workspace}/gwc/service/tms/1.0.0',
// where
// '/geoserver/cloud' is the context path as given by the gateway's base uri,
// and
// '/{workspace}/gwc' the suffix after which comes the pathInfo
// '/service/tms/1.0.0')
final String requestURI = request.getRequestURI();

final String gwc = "/gwc";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
import org.geoserver.config.GeoServer;
import org.geoserver.config.GeoServerReinitializer;
import org.geoserver.gwc.ConfigurableBlobStore;
import org.geoserver.gwc.GWC;
import org.geoserver.gwc.layer.GeoServerTileLayer;
import org.geoserver.gwc.layer.TileLayerCatalog;
import org.geoserver.platform.resource.Resource;
import org.geoserver.platform.resource.Resources;
import org.geowebcache.layer.TileLayer;
import org.geowebcache.locks.LockProvider;
import org.geowebcache.storage.blobstore.memory.CacheConfiguration;
import org.geowebcache.storage.blobstore.memory.CacheProvider;
import org.geowebcache.storage.blobstore.memory.guava.GuavaCacheProvider;
Expand Down Expand Up @@ -58,10 +60,18 @@
@RequiredArgsConstructor
public abstract class AbstractGwcInitializer implements GeoServerReinitializer, InitializingBean {

/**
* {@link GWC#saveConfig(GWCConfig)} will lookup for the {@link LockProvider} named after {@link
* GWCConfig#getLockProviderName()}. We need it to be a cluster-aware lock provider. This is the
* bean name to be registered by the configuration, and we'll set it to {@link
* GWCConfig#setLockProviderName(String)} during initialization.
*/
public static final String GWC_LOCK_PROVIDER_BEAN_NAME = "gwcClusteringLockProvider";

protected final @NonNull GWCConfigPersister configPersister;
protected final @NonNull ConfigurableBlobStore blobStore;
protected final @NonNull GeoServerTileLayerConfiguration geoseverTileLayers;
protected final @NonNull GeoServerConfigurationLock configLock;
protected final @NonNull GeoServerConfigurationLock globalConfigLock;

protected abstract Logger logger();

Expand Down Expand Up @@ -93,23 +103,45 @@ public void initialize(final GeoServer geoServer) throws Exception {
* #initialize(org.geoserver.config.GeoServer) super.initialize(GeoServer)}
*/
private void initializeGeoServerIntegrationConfigFile() throws IOException {
if (configFileExists()) {
return;
globalConfigLock.lock(LockType.WRITE);
try {
if (configFileExists()) {
updateLockProviderName();
} else {
logger().info(
"Initializing GeoServer specific GWC configuration {}",
configPersister.findConfigFile());
GWCConfig defaults = new GWCConfig();
defaults.setVersion("1.1.0");
defaults.setLockProviderName(GWC_LOCK_PROVIDER_BEAN_NAME);
configPersister.save(defaults);
}
} finally {
globalConfigLock.unlock();
}
final boolean lockAcquired = configLock.tryLock(LockType.WRITE);
if (lockAcquired) {
try {
if (!configFileExists()) {
logger().info(
"Initializing GeoServer specific GWC configuration {}",
configPersister.findConfigFile());
GWCConfig defaults = new GWCConfig();
defaults.setVersion("1.1.0");
configPersister.save(defaults);
}
} finally {
configLock.unlock();
}

/**
* In case the {@link GWCConfig} exists and its lock provider name is not {@link
* #GWC_LOCK_PROVIDER_BEAN_NAME}, updates and saves the configuration.
*
* <p>At this point, {@link #configFileExists()} is known to be true.
*/
private void updateLockProviderName() throws IOException {
final GWCConfig gwcConfig = configPersister.getConfig();
if (!GWC_LOCK_PROVIDER_BEAN_NAME.equals(gwcConfig.getLockProviderName())) {
if (null == gwcConfig.getLockProviderName()) {
logger().info(
"Setting GeoWebCache lock provider to {}",
GWC_LOCK_PROVIDER_BEAN_NAME);
} else {
logger().warn(
"Updating GeoWebCache lock provider from {} to {}",
gwcConfig.getLockProviderName(),
GWC_LOCK_PROVIDER_BEAN_NAME);
}
gwcConfig.setLockProviderName(GWC_LOCK_PROVIDER_BEAN_NAME);
configPersister.save(gwcConfig);
}
}

Expand Down

0 comments on commit 745eba1

Please sign in to comment.