* Container configuration service
*/
public interface IConfigurationContainerService extends IConfigurationServiceCommon {
+
+ /**
+ * Bundle will call this function to ask ContainerConfigurationService to provide the
+ * directory location of container
+ *
+ * @return The path to active container directory
+ */
+ String getConfigurationRoot();
}
package org.opendaylight.controller.configuration.internal;
+import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import org.opendaylight.controller.configuration.ConfigurationEvent;
import org.opendaylight.controller.configuration.ConfigurationObject;
import org.opendaylight.controller.configuration.IConfigurationAware;
+import org.opendaylight.controller.configuration.IConfigurationContainerService;
import org.opendaylight.controller.configuration.IConfigurationService;
import org.opendaylight.controller.sal.utils.GlobalConstants;
import org.opendaylight.controller.sal.utils.IObjectReader;
private static final Logger logger = LoggerFactory
.getLogger(ConfigurationService.class);
public static final String SAVE_EVENT_CACHE = "config.event.save";
- private static final Object ROOT = GlobalConstants.STARTUPHOME.toString();
+ private static final String ROOT = GlobalConstants.STARTUPHOME.toString();
private IClusterGlobalServices clusterServices;
private ConcurrentMap <ConfigurationEvent, String> configEvent;
private Set<IConfigurationAware> configurationAwareList = Collections
return saveConfigurationsInternal();
}
+
+ private List<String> getContainerDirectoryList() {
+ List<String> containerList = new ArrayList<String>();
+ for (IConfigurationAware configurationAware : this.configurationAwareList) {
+ if (configurationAware instanceof IConfigurationContainerService) {
+ String containerFilePath = ((ContainerConfigurationService)configurationAware).getConfigurationRoot();
+ containerList.add(containerFilePath);
+ }
+ }
+ return containerList;
+ }
+
+ private void createContainerDirectory(IConfigurationAware configurationAware) {
+ String containerFilePath = ((ContainerConfigurationService) configurationAware).getConfigurationRoot();
+ if (!new File(containerFilePath).exists()) {
+ boolean created = new File(containerFilePath).mkdir();
+ if (!created) {
+ logger.error("Failed to create startup config directory: {}", containerFilePath);
+ }
+ }
+ }
+
+ private void clearStaleContainerDirectories() {
+ List<String> activeContainers = getContainerDirectoryList();
+ for (File file : new File(ROOT).listFiles()) {
+ if (file.isDirectory() && !activeContainers.contains(file.toPath() + File.separator)) {
+ logger.trace("Removing directory for container {}", file.getName());
+ for (File innerFile : file.listFiles()) {
+ innerFile.delete();
+ }
+ boolean removed = file.delete();
+ if (!removed) {
+ logger.warn("Failed to remove stale directory: {}", file.getName());
+ }
+ }
+ }
+ }
+
+
private Status saveConfigurationsInternal() {
boolean success = true;
for (IConfigurationAware configurationAware : configurationAwareList) {
+ if (configurationAware instanceof IConfigurationContainerService) {
+ // Create directory for new containers
+ createContainerDirectory(configurationAware);
+ }
Status status = configurationAware.saveConfiguration();
if (!status.isSuccess()) {
success = false;
- logger.warn("Failed to save config for {}",
- configurationAware.getClass().getName());
+ logger.warn("Failed to save config for {}", configurationAware.getClass().getName());
}
}
+ // Remove startup directories of containers that were removed from
+ // the configuration but not saved
+ clearStaleContainerDirectories();
+
if (success) {
return new Status(StatusCode.SUCCESS);
} else {
- return new Status(StatusCode.INTERNALERROR,
- "Failed to Save All Configurations");
+ return new Status(StatusCode.INTERNALERROR, "Failed to Save All Configurations");
}
}
package org.opendaylight.controller.configuration.internal;
-import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Dictionary;
private static final Logger logger = LoggerFactory.getLogger(ContainerConfigurationService.class);
private IClusterContainerServices clusterServices;
private ConcurrentMap <ConfigurationEvent, String> 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
- */
+ // Directory which contains the startup files for this container
+ private String root;
private Set<IConfigurationContainerAware> configurationAwareList = Collections
.synchronizedSet(new HashSet<IConfigurationContainerAware>());
- private String root;
private ObjectReader objReader;
private ObjectWriter objWriter;
void init(Component c) {
Dictionary<?, ?> props = c.getServiceProperties();
- String containerName = (props != null) ? (String) props.get("containerName") : GlobalConstants.DEFAULT.toString();
- root = String.format("%s%s/", GlobalConstants.STARTUPHOME.toString(), containerName);
- if (!new File(root).exists()) {
- boolean created = new File(root).mkdir();
- if (!created) {
- logger.error("Failed to create startup config directory for container {}", containerName);
- }
- }
+ String containerName = (props != null) ? (String) props.get("containerName") :
+ GlobalConstants.DEFAULT.toString();
+ root = String.format("%s%s/", GlobalConstants.STARTUPHOME.toString(), containerName);
}
public void start() {
* Function called by the dependency manager before Container is Stopped and Destroyed.
*/
public void containerStop() {
- // Remove container directory along with its startup files
- File[] files = new File(root).listFiles();
- for (File file : files) {
- file.delete();
- }
- new File(root).delete();
+ // Do nothing
+ }
+
+ @Override
+ public String getConfigurationRoot() {
+ return root;
}
@Override
public Status saveConfiguration() {
boolean success = true;
+
for (IConfigurationContainerAware configurationAware : configurationAwareList) {
logger.trace("Save Config triggered for {}", configurationAware.getClass().getSimpleName());
package org.opendaylight.controller.containermanager.internal;
-import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
return status;
}
- private void removeComponentsStartUpfiles(String containerName) {
- String startupLocation = String.format("./%s", GlobalConstants.STARTUPHOME.toString());
- String containerPrint = String.format("_%s.", containerName.toLowerCase(Locale.ENGLISH));
-
- File directory = new File(startupLocation);
- String[] fileList = directory.list();
-
- logger.trace("Deleting startup configuration files for container {}", containerName);
- if (fileList != null) {
- for (String fileName : fileList) {
- if (fileName.contains(containerPrint)) {
- String fullPath = String.format("%s/%s", startupLocation, fileName);
- File file = new File(fullPath);
- boolean done = file.delete();
- logger.trace("{} {}", (done ? "Deleted: " : "Failed to delete: "), fileName);
- }
- }
- }
- }
-
/**
* Create and initialize default all resource group and create association
* with default well known users and profiles, if not already learnt from
notifyContainerModeChange(delete, notifyLocal);
// Notify listeners
notifyContainerAwareListeners(container, delete);
-
- /*
- * This is a quick fix until configuration service becomes the
- * centralized configuration management place. Here container manager
- * will remove the startup files for all the bundles that are present in
- * the container being deleted. Do the cleanup here in Container manger
- * as do not want to put this temporary code in Configuration manager
- * yet which is ODL.
- */
- if (delete) {
- // TODO: remove when Config Mgr takes over
- removeComponentsStartUpfiles(containerName);
- }
}
private void notifyContainerEntryChangeInternal(String containerName, List<NodeConnector> ncList, UpdateType update, boolean notifyLocal) {