Skip to content

Commit

Permalink
pgconfig: synchronize resources upon CatalogInfo object changes
Browse files Browse the repository at this point in the history
`PgsqlGeoSeverLoader` didn't add `CatalogListener`s that would replace
the datadirectory-approach based `GeoServerResourcePersister` and
`GeoServerConfigPersister`, hence style side-car files like sld's
wouldn't be moved when a style changes workspace or removed when a
style is removed.
  • Loading branch information
groldan committed May 3, 2024
1 parent 1f6ceb3 commit 27d5c5f
Show file tree
Hide file tree
Showing 16 changed files with 482 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

import org.geoserver.catalog.Info;
import org.geoserver.catalog.event.CatalogModifyEvent;
import org.geoserver.catalog.event.impl.CatalogModifyEventImpl;
import org.geoserver.catalog.impl.DefaultCatalogFacade;
import org.geoserver.catalog.impl.ModificationProxy;
import org.geoserver.catalog.plugin.CatalogPlugin;
import org.geoserver.catalog.plugin.CatalogPluginStyleResourcePersister;
import org.geoserver.config.GeoServerConfigPersister;
import org.geoserver.config.util.XStreamPersister;
import org.geoserver.platform.GeoServerResourceLoader;
Expand Down Expand Up @@ -37,7 +37,7 @@ public CatalogPluginGeoServerConfigPersister(GeoServerResourceLoader rl, XStream

@Override
public void handleModifyEvent(CatalogModifyEvent event) {
CatalogModifyEventImpl e = CatalogPluginGeoServerResourcePersister.withRealSource(event);
CatalogModifyEvent e = CatalogPluginStyleResourcePersister.withRealSource(event);
super.handleModifyEvent(e);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import org.geoserver.GeoServerConfigurationLock;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.plugin.CatalogPluginStyleResourcePersister;
import org.geoserver.catalog.plugin.locking.LockingCatalog;
import org.geoserver.catalog.plugin.locking.LockingGeoServer;
import org.geoserver.catalog.plugin.locking.LockingSupport;
Expand Down Expand Up @@ -155,6 +156,6 @@ protected void loadCatalog(Catalog catalog, XStreamPersister xp) throws Exceptio

catalog.addListener(
new CatalogPluginGeoServerConfigPersister(catalog.getResourceLoader(), xp));
catalog.addListener(new CatalogPluginGeoServerResourcePersister(catalog));
catalog.addListener(new CatalogPluginStyleResourcePersister(catalog));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.geoserver.catalog.FeatureTypeCallback;
import org.geoserver.catalog.impl.CatalogImpl;
import org.geoserver.catalog.plugin.CatalogPlugin;
import org.geoserver.catalog.plugin.CatalogPluginStyleResourcePersister;
import org.geoserver.catalog.plugin.locking.LockingCatalog;
import org.geoserver.catalog.plugin.locking.LockingGeoServer;
import org.geoserver.catalog.plugin.locking.LockingSupport;
Expand Down Expand Up @@ -152,7 +153,7 @@ public void loadCatalog(Catalog catalog, XStreamPersister xp) throws Exception {

catalog.addListener(
new CatalogPluginGeoServerConfigPersister(catalog.getResourceLoader(), xp));
catalog.addListener(new CatalogPluginGeoServerResourcePersister(catalog));
catalog.addListener(new CatalogPluginStyleResourcePersister(catalog));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
* @since 1.4
*/
@Configuration(proxyBeanMethods = true)
@Slf4j(topic = "org.geoserver.cloud.config.catalog.backend.pgsql")
@Slf4j(topic = "org.geoserver.cloud.config.catalog.backend.pgconfig")
public class PgsqlBackendConfiguration extends GeoServerBackendConfigurer {

private String instanceId;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
package org.geoserver.cloud.config.catalog.backend.pgconfig;

import lombok.extern.slf4j.Slf4j;

import org.geoserver.catalog.CatalogException;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.NamespaceInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.StoreInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.catalog.event.CatalogAddEvent;
import org.geoserver.catalog.event.CatalogListener;
import org.geoserver.catalog.event.CatalogModifyEvent;
import org.geoserver.catalog.event.CatalogPostModifyEvent;
import org.geoserver.catalog.event.CatalogRemoveEvent;
import org.geoserver.catalog.plugin.CatalogPluginStyleResourcePersister;
import org.geoserver.config.GeoServerConfigPersister;
import org.geoserver.config.GeoServerDataDirectory;
import org.geoserver.platform.ExtensionPriority;
import org.geoserver.platform.GeoServerResourceLoader;
import org.geoserver.platform.resource.Resource;
import org.geoserver.platform.resource.Resource.Type;
import org.geoserver.platform.resource.ResourceStore;

/**
* A {@link GeoServerConfigPersister} alike {@link CatalogListener} to synchronize {@link
* ResourceStore} resources related to catalog changes.
*/
@Slf4j(topic = "org.geoserver.cloud.config.catalog.backend.pgconfig")
public class PgsqlCatalogResourcesSynchronizer implements CatalogListener, ExtensionPriority {

private GeoServerResourceLoader rl;
private GeoServerDataDirectory dd;

public PgsqlCatalogResourcesSynchronizer(GeoServerResourceLoader rl) {
this.rl = rl;
this.dd = new GeoServerDataDirectory(rl);
}

@Override
public int getPriority() {
return ExtensionPriority.HIGHEST;
}

@Override
public void reloaded() {
// no-op
}

/**
* No-op, {@link GeoServerConfigPersister} would persist the xml files here, pgconfig doesn't do
* that
*/
@Override
public void handleAddEvent(CatalogAddEvent event) {
// no-op
}

/**
* No-op, {@link GeoServerConfigPersister} would persist the xml files here, pgconfig doesn't do
* that.
*/
@Override
public void handlePostModifyEvent(CatalogPostModifyEvent event) {
// no-op
}

/**
* @throws CatalogException
*/
@Override
public void handleRemoveEvent(CatalogRemoveEvent event) {
final Object source = event.getSource();
if (source instanceof WorkspaceInfo ws) {
log.debug("Removing workspace {}", ws.getName());
rmRes(dd.get(ws));
} else if (source instanceof NamespaceInfo ns) {
// do not remove the directory, only when removing the workspace
} else if (source instanceof StoreInfo store) {
log.debug("Removing datastore {}", store.getName());
rmRes(dd.get(store));
} else if (source instanceof ResourceInfo r) {
log.debug("Removing ResourceInfo {}", r.getName());
rmRes(dd.get(r));
} else if (source instanceof LayerInfo l) {
log.debug("Removing layer {}", l.getName());
rmRes(dd.get(l));
} else if (source instanceof LayerGroupInfo lg) {
log.debug("Removing layer group " + lg.getName());
Resource directory = dd.get(lg);
boolean exists = directory.getType() == Type.DIRECTORY;
if (exists && directory.list().isEmpty()) {
rmRes(directory);
}
}
}

/**
* @throws CatalogException
*/
@Override
public void handleModifyEvent(CatalogModifyEvent event) {
event = CatalogPluginStyleResourcePersister.withRealSource(event);
final Object source = event.getSource();
// here we handle name changes
handleRenames(event);

// handle the case of a store changing workspace
if (source instanceof StoreInfo s) {
handleWorkspaceChange(event, s);
} else if (source instanceof FeatureTypeInfo ft) {
handleStoreChange(event, ft);
}
}

private void handleWorkspaceChange(CatalogModifyEvent event, StoreInfo s) {
final int i = event.getPropertyNames().indexOf("workspace");
if (i > -1) {
WorkspaceInfo newWorkspace = (WorkspaceInfo) event.getNewValues().get(i);
Resource oldDir = dd.get(s);
moveResToDir(oldDir, dd.get(newWorkspace));
}
}

private void handleStoreChange(CatalogModifyEvent event, ResourceInfo resourceInfo) {
final int i = event.getPropertyNames().indexOf("store");
if (i > -1) {
StoreInfo newStore = (StoreInfo) event.getNewValues().get(i);
Resource oldDir = dd.get(resourceInfo);
Resource newDir = dd.get(newStore);
moveResToDir(oldDir, newDir);
}
}

private void handleRenames(CatalogModifyEvent event) {
final int i = event.getPropertyNames().indexOf("name");
if (i > -1) {
String newName = (String) event.getNewValues().get(i);
var source = event.getSource();
if (source instanceof WorkspaceInfo ws) {
renameWorkspace(ws, newName);
} else if (source instanceof StoreInfo s) {
renameStore(s, newName);
} else if (source instanceof ResourceInfo r) {
renameResource(r, newName);
}
}
}

private void renameWorkspace(WorkspaceInfo ws, String newName) {
log.debug("Renaming workspace {} to {}", ws.getName(), newName);
renameRes(dd.get(ws), newName);
}

private void renameStore(StoreInfo s, String newName) {
log.debug("Renaming store {} to {}", s.getName(), newName);
renameRes(dd.get(s), newName);
}

private void renameResource(ResourceInfo r, String newName) {
log.debug("Renaming resource {} to {}", r.getName(), newName);
renameRes(dd.get(r), newName);
}

private void rmRes(Resource r) {
try {
rl.remove(r.path());
} catch (Exception e) {
throw new CatalogException(e);
}
}

private void renameRes(Resource r, String newName) {
try {
rl.move(r.path(), r.parent().get(newName).path());
} catch (Exception e) {
throw new CatalogException(e);
}
}

private void moveResToDir(Resource r, Resource newDir) {
try {
rl.move(r.path(), newDir.get(r.name()).path());
} catch (Exception e) {
throw new CatalogException(e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
/**
* @since 1.4
*/
@Slf4j(topic = "org.geoserver.cloud.config.catalog.backend.pgsql")
@Slf4j(topic = "org.geoserver.cloud.config.catalog.backend.pgconfig")
@Data
@Accessors(chain = true)
public class PgsqlDatabaseMigrations {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@
import org.geoserver.GeoServerConfigurationLock.LockType;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.plugin.CatalogPluginStyleResourcePersister;
import org.geoserver.config.GeoServer;
import org.geoserver.config.GeoServerConfigPersister;
import org.geoserver.config.GeoServerInfo;
import org.geoserver.config.GeoServerLoader;
import org.geoserver.config.GeoServerLoaderProxy;
import org.geoserver.config.GeoServerResourcePersister;
import org.geoserver.config.LoggingInfo;
import org.geoserver.config.ServiceInfo;
import org.geoserver.config.util.XStreamPersister;
Expand Down Expand Up @@ -67,6 +70,11 @@ public PgsqlGeoServerLoader(
@Override
protected void loadCatalog(Catalog catalog, XStreamPersister xp) throws Exception {
log.info("Loading catalog with pgsql loader...");
catalog.removeListeners(GeoServerConfigPersister.class);
catalog.removeListeners(GeoServerResourcePersister.class);
final boolean backupSldFiles = false;
catalog.addListener(new CatalogPluginStyleResourcePersister(catalog, backupSldFiles));
catalog.addListener(new PgsqlCatalogResourcesSynchronizer(resourceLoader));
}

/**
Expand Down
Loading

0 comments on commit 27d5c5f

Please sign in to comment.