/* * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ 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.IClusterContainerServices; import org.opendaylight.controller.clustering.services.IClusterServices; import org.opendaylight.controller.configuration.ConfigurationEvent; import org.opendaylight.controller.configuration.IConfigurationAware; import org.opendaylight.controller.configuration.IConfigurationContainerAware; import org.opendaylight.controller.configuration.IConfigurationContainerService; import org.opendaylight.controller.sal.utils.Status; import org.opendaylight.controller.sal.utils.StatusCode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @file ConfigurationImpl.java * * @brief Backend functionality for all ConfigurationService related tasks. * * */ public class ContainerConfigurationService implements IConfigurationContainerService, IConfigurationAware, ICacheUpdateAware { public static final String CONTAINER_SAVE_EVENT_CACHE = "config.container.event.save"; private static final Logger logger = LoggerFactory.getLogger(ContainerConfigurationService.class); private IClusterContainerServices clusterServices; private ConcurrentMap containerConfigEvent; /* * Collection containing the configuration objects. * This is configuration world: container names (also the map key) * are maintained as they were configured by user, same case */ private Set configurationAwareList = Collections .synchronizedSet(new HashSet()); public void addConfigurationContainerAware( IConfigurationContainerAware configurationAware) { if (!this.configurationAwareList.contains(configurationAware)) { this.configurationAwareList.add(configurationAware); } } public int getConfigurationAwareListSize() { return this.configurationAwareList.size(); } public void removeConfigurationContainerAware( IConfigurationContainerAware configurationAware) { this.configurationAwareList.remove(configurationAware); } public void setClusterServices(IClusterContainerServices i) { this.clusterServices = i; logger.debug("IClusterServices set"); } public void unsetClusterServices(IClusterContainerServices i) { if (this.clusterServices == i) { this.clusterServices = null; logger.debug("IClusterServices Unset"); } } public void init() { } public void start() { allocateCache(); retrieveCache(); } public void destroy() { // Clear local states this.configurationAwareList.clear(); } @Override public Status saveConfiguration() { boolean success = true; for (IConfigurationContainerAware configurationAware : configurationAwareList) { logger.trace("Save Config triggered for {}", configurationAware.getClass().getSimpleName()); Status status = configurationAware.saveConfiguration(); if (!status.isSuccess()) { success = false; logger.warn("Failed to save config for {}", configurationAware.getClass().getSimpleName()); } } if (success) { return new Status(StatusCode.SUCCESS); } else { return new Status(StatusCode.INTERNALERROR, "Failed to Save All Configurations"); } } @Override public Status saveConfigurations() { containerConfigEvent.put(ConfigurationEvent.SAVE, ""); return saveConfiguration(); } @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; } logger.debug("Processing {} event", key); if (key == ConfigurationEvent.SAVE) { saveConfiguration(); } } @Override public void entryDeleted(ConfigurationEvent key, String cacheName, boolean originLocal) { if (originLocal) { return; } } private void allocateCache() { if (this.clusterServices == null) { logger.error("uninitialized clusterServices, can't create cache"); return; } try { this.clusterServices.createCache(CONTAINER_SAVE_EVENT_CACHE, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL)); } catch (CacheConfigException cce) { logger.debug("Error creating ContainerConfigurationService cache ", cce); } catch (CacheExistException cce) { logger.debug("ConfigurationService Cache already exists, destroy and recreate ", cce); } } @SuppressWarnings({ "unchecked" }) private void retrieveCache() { if (this.clusterServices == null) { logger.error("uninitialized clusterServices, can't retrieve cache"); return; } containerConfigEvent = (ConcurrentMap) this.clusterServices.getCache(CONTAINER_SAVE_EVENT_CACHE); if (containerConfigEvent == null) { logger.error("Failed to retrieve configuration Cache"); } } }