From: Madhu Venugopal Date: Fri, 5 Jul 2013 06:17:37 +0000 (-0700) Subject: Configuration Save event sync mechanism using Clustering services. X-Git-Tag: releasepom-0.1.0~311 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=8c0e77ebab90f7d42f3103318e8d7578ea140638 Configuration Save event sync mechanism using Clustering services. Every Controller in the cluster will receive a Config save event and the save is performed locally on each of the Controllers. This is the first step towards the centralized configuration service. Change-Id: Icbff65117ccb237a4c31091d392b27de43d8ae1d Signed-off-by: Madhu Venugopal --- diff --git a/opendaylight/configuration/api/src/main/java/org/opendaylight/controller/configuration/ConfigurationEvent.java b/opendaylight/configuration/api/src/main/java/org/opendaylight/controller/configuration/ConfigurationEvent.java new file mode 100644 index 0000000000..77333e2dc2 --- /dev/null +++ b/opendaylight/configuration/api/src/main/java/org/opendaylight/controller/configuration/ConfigurationEvent.java @@ -0,0 +1,27 @@ +package org.opendaylight.controller.configuration; + +public enum ConfigurationEvent { + SAVE("Save"), + BACKUP("Backup"), + RESTORE("Restore"), + DELETE("Delete"); + + private ConfigurationEvent(String name) { + this.name = name; + } + + private String name; + + public String toString() { + return name; + } + + public static ConfigurationEvent fromString(String pName) { + for(ConfigurationEvent p:ConfigurationEvent.values()) { + if (p.toString().equals(pName)) { + return p; + } + } + return null; + } +} diff --git a/opendaylight/configuration/implementation/src/main/java/org/opendaylight/controller/configuration/internal/Activator.java b/opendaylight/configuration/implementation/src/main/java/org/opendaylight/controller/configuration/internal/Activator.java index 9fb5b159f6..78b64400c8 100644 --- a/opendaylight/configuration/implementation/src/main/java/org/opendaylight/controller/configuration/internal/Activator.java +++ b/opendaylight/configuration/implementation/src/main/java/org/opendaylight/controller/configuration/internal/Activator.java @@ -9,7 +9,13 @@ package org.opendaylight.controller.configuration.internal; +import java.util.Dictionary; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Set; + import org.apache.felix.dm.Component; +import org.opendaylight.controller.clustering.services.ICacheUpdateAware; import org.opendaylight.controller.clustering.services.IClusterGlobalServices; import org.opendaylight.controller.configuration.IConfigurationAware; import org.opendaylight.controller.configuration.IConfigurationContainerAware; @@ -84,8 +90,8 @@ public class Activator extends ComponentActivatorAbstractBase { c.add(createContainerServiceDependency(containerName).setService( IConfigurationContainerAware.class).setCallbacks( - "addConfigurationContainerAware", - "removeConfigurationContainerAware").setRequired(false)); + "addConfigurationContainerAware", + "removeConfigurationContainerAware").setRequired(false)); } } @@ -117,21 +123,26 @@ public class Activator extends ComponentActivatorAbstractBase { */ protected void configureGlobalInstance(Component c, Object imp) { if (imp.equals(ConfigurationImpl.class)) { + Dictionary> props = new Hashtable>(); + Set propSet = new HashSet(); + propSet.add("config.event.save"); + props.put("cachenames", propSet); // export the service c.setInterface( - new String[] { IConfigurationService.class.getName() }, - null); + new String[] { IConfigurationService.class.getName(), + ICacheUpdateAware.class.getName()}, + props); c.add(createServiceDependency().setService( IClusterGlobalServices.class).setCallbacks( - "setClusterServices", "unsetClusterServices").setRequired( - true)); + "setClusterServices", "unsetClusterServices").setRequired( + true)); c.add(createServiceDependency().setService( IConfigurationAware.class).setCallbacks( - "addConfigurationAware", "removeConfigurationAware") - .setRequired(false)); + "addConfigurationAware", "removeConfigurationAware") + .setRequired(false)); } } } diff --git a/opendaylight/configuration/implementation/src/main/java/org/opendaylight/controller/configuration/internal/ConfigurationImpl.java b/opendaylight/configuration/implementation/src/main/java/org/opendaylight/controller/configuration/internal/ConfigurationImpl.java index 20821f1028..8e2741e7d1 100644 --- a/opendaylight/configuration/implementation/src/main/java/org/opendaylight/controller/configuration/internal/ConfigurationImpl.java +++ b/opendaylight/configuration/implementation/src/main/java/org/opendaylight/controller/configuration/internal/ConfigurationImpl.java @@ -10,10 +10,17 @@ package org.opendaylight.controller.configuration.internal; import java.util.Collections; +import java.util.EnumSet; import java.util.HashSet; import java.util.Set; +import java.util.concurrent.ConcurrentMap; +import org.opendaylight.controller.clustering.services.CacheConfigException; +import org.opendaylight.controller.clustering.services.CacheExistException; +import org.opendaylight.controller.clustering.services.ICacheUpdateAware; import org.opendaylight.controller.clustering.services.IClusterGlobalServices; +import org.opendaylight.controller.clustering.services.IClusterServices; +import org.opendaylight.controller.configuration.ConfigurationEvent; import org.opendaylight.controller.configuration.IConfigurationAware; import org.opendaylight.controller.configuration.IConfigurationService; import org.opendaylight.controller.sal.utils.StatusCode; @@ -29,10 +36,11 @@ import org.slf4j.LoggerFactory; * */ -public class ConfigurationImpl implements IConfigurationService { +public class ConfigurationImpl implements IConfigurationService, ICacheUpdateAware { private static final Logger logger = LoggerFactory .getLogger(ConfigurationImpl.class); private IClusterGlobalServices clusterServices; + private ConcurrentMap configEvent; /* * Collection containing the configuration objects. * This is configuration world: container names (also the map key) @@ -72,6 +80,11 @@ public class ConfigurationImpl implements IConfigurationService { logger.info("ContainerManager startup...."); } + public void start() { + allocateCache(); + retrieveCache(); + } + public void destroy() { // Clear local states this.configurationAwareList.clear(); @@ -79,21 +92,76 @@ public class ConfigurationImpl implements IConfigurationService { @Override public Status saveConfigurations() { + if (configEvent != null) { + configEvent.put(ConfigurationEvent.SAVE, ""); + } + return saveConfigurationsInternal(); + } + + private Status saveConfigurationsInternal() { boolean success = true; for (IConfigurationAware configurationAware : configurationAwareList) { - Status status = configurationAware.saveConfiguration(); + Status status = configurationAware.saveConfiguration(); if (!status.isSuccess()) { success = false; logger.info("Failed to save config for {}", - configurationAware.getClass().getName()); + configurationAware.getClass().getName()); } } if (success) { - return new Status(StatusCode.SUCCESS, null); + return new Status(StatusCode.SUCCESS); } else { return new Status(StatusCode.INTERNALERROR, - "Failed to Save All Configurations"); + "Failed to Save All Configurations"); + } + } + + @Override + public void entryCreated(ConfigurationEvent key, String cacheName, + boolean originLocal) { + if (originLocal) return; + } + + @Override + public void entryUpdated(ConfigurationEvent key, String new_value, + String cacheName, boolean originLocal) { + if (originLocal) return; + if (key == ConfigurationEvent.SAVE) { + saveConfigurationsInternal(); } } + @Override + public void entryDeleted(ConfigurationEvent key, String cacheName, + boolean originLocal) { + if (originLocal) return; + } + + @SuppressWarnings("deprecation") + private void allocateCache() { + if (this.clusterServices == null) { + logger.error("uninitialized clusterServices, can't create cache"); + return; + } + try { + this.clusterServices.createCache("config.event.save", + EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL)); + } catch (CacheConfigException cce) { + logger.error("Error creating Configuration cache ", cce); + } catch (CacheExistException cce) { + logger.error("Configuration Cache already exists, destroy and recreate ", cce); + } + } + + @SuppressWarnings({ "unchecked", "deprecation" }) + private void retrieveCache() { + if (this.clusterServices == null) { + logger.error("uninitialized clusterServices, can't retrieve cache"); + return; + } + configEvent = (ConcurrentMap) this.clusterServices.getCache("config.event.save"); + if (configEvent == null) { + logger.error("Failed to retrieve configuration Cache"); + } + } }