/* (c) 2016 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.cluster.impl.handlers.configuration;
import com.thoughtworks.xstream.XStream;
import org.apache.commons.lang.NullArgumentException;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.catalog.impl.ModificationProxy;
import org.geoserver.cluster.events.ToggleSwitch;
import org.geoserver.cluster.impl.events.configuration.JMSSettingsModifyEvent;
import org.geoserver.cluster.impl.utils.BeanUtils;
import org.geoserver.config.GeoServer;
import org.geoserver.config.SettingsInfo;
import java.util.logging.Level;
/**
*/
public class JMSSettingsHandler extends JMSConfigurationHandler<JMSSettingsModifyEvent> {
private final GeoServer geoServer;
private final ToggleSwitch producer;
public JMSSettingsHandler(GeoServer geo, XStream xstream, Class clazz, ToggleSwitch producer) {
super(xstream, clazz);
this.geoServer = geo;
this.producer = producer;
}
@Override
protected void omitFields(final XStream xstream) {
xstream.omitField(GeoServer.class, "geoServer");
}
@Override
public boolean synchronize(JMSSettingsModifyEvent event) throws Exception {
if (event == null) {
throw new NullArgumentException("Incoming event is NULL.");
}
try {
// disable the message producer to avoid recursion
producer.disable();
// let's see which type of event we have and handle it
switch (event.getEventType()) {
case MODIFIED:
handleModifiedSettings(event);
break;
case ADDED:
handleAddedSettings(event);
break;
case REMOVED:
handleRemovedSettings(event);
break;
}
} catch (Exception exception) {
LOGGER.log(Level.SEVERE, "Error handling settings event.", exception);
throw exception;
} finally {
// enabling the events producer again
producer.enable();
}
return true;
}
private void handleModifiedSettings(JMSSettingsModifyEvent event) {
// let's extract some useful information from the event
WorkspaceInfo workspace = event.getSource().getWorkspace();
// settings are global or specific to a certain workspace
SettingsInfo settingsInfo = workspace == null
? geoServer.getSettings() : geoServer.getSettings(workspace);
// if not settings were found this means that a user just deleted this workspace
// or deleted this workspace settings on this GeoServer instance or that a previously
// synchronization problem happened
if (settingsInfo == null) {
throw new IllegalArgumentException(String.format(
"No settings for workspace '%s' found on this instance.", workspace.getName()));
}
// well let's update our settings updating only the modified properties
try {
BeanUtils.smartUpdate(settingsInfo, event.getPropertyNames(), event.getNewValues());
} catch (Exception exception) {
String message = workspace == null ? "Error updating GeoServer global settings."
: "Error updating workspace '%s' settings.";
throw new RuntimeException(String.format(message, workspace), exception);
}
// save the updated settings
geoServer.save(settingsInfo);
}
private void handleAddedSettings(JMSSettingsModifyEvent event) {
// we only need to save the new settings, if the workspace associated
// with this settings doesn't exists or this settings already exists
// GeoServer will complain about it with a proper exception
geoServer.add(event.getSource());
}
private void handleRemovedSettings(JMSSettingsModifyEvent event) {
// we only need to remove the new settings
geoServer.remove(event.getSource());
}
}