Switch initial config files format to xml and add autodetect adapter for config persi... 85/3785/4
authorMaros Marsalek <mmarsale@cisco.com>
Mon, 16 Dec 2013 15:29:58 +0000 (16:29 +0100)
committerMaros Marsalek <mmarsale@cisco.com>
Tue, 14 Jan 2014 11:53:21 +0000 (12:53 +0100)
Autodetect adapter allows to read initial configuration from xml as well as plaintext files.
The detection of file type is based on file content.

Change-Id: I499f0983bbea60f07e2ea7deb93814aa4f9e59e6
Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
21 files changed:
opendaylight/config/config-persister-directory-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/DirectoryPersister.java
opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersister.java [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryStorageAdapter.java [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileType.java [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersisterTest.java [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileTypeTest.java [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/1controller.txt.config [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/2controller.xml.config [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.txt.config [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.xml.config [new file with mode: 0644]
opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/unknown.config [new file with mode: 0644]
opendaylight/config/config-persister-directory-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/xml/XmlDirectoryPersister.java
opendaylight/config/config-persister-file-xml-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/file/xml/model/ConfigSnapshot.java
opendaylight/config/pom.xml
opendaylight/distribution/opendaylight/pom.xml
opendaylight/distribution/opendaylight/src/main/resources/configuration/config.ini
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.conf [deleted file]
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml.conf [new file with mode: 0644]
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.conf [deleted file]
opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml.conf [new file with mode: 0644]

index a123eb9..eb8ef8c 100644 (file)
@@ -33,21 +33,23 @@ public class DirectoryPersister implements Persister {
     private static final Logger logger = LoggerFactory.getLogger(DirectoryPersister.class);
     private static final Charset ENCODING = Charsets.UTF_8;
 
-    static final String MODULES_START = "//MODULES START";
+    public static final String MODULES_START = "//MODULES START";
     static final String SERVICES_START = "//SERVICES START";
     static final String CAPABILITIES_START = "//CAPABILITIES START";
 
 
     private final File storage;
-    private final String header, middle, footer;
+    private static final String header, middle, footer;
 
-    public DirectoryPersister(File storage) {
-        checkArgument(storage.exists() && storage.isDirectory(), "Storage directory does not exist: " + storage);
-        this.storage = storage;
+    static {
         header = readResource("header.txt");
         middle = readResource("middle.txt");
         footer = readResource("footer.txt");
+    }
 
+    public DirectoryPersister(File storage) {
+        checkArgument(storage.exists() && storage.isDirectory(), "Storage directory does not exist: " + storage);
+        this.storage = storage;
     }
 
     private static String readResource(String resource) {
@@ -78,13 +80,18 @@ public class DirectoryPersister implements Persister {
         for (File file : sortedFiles) {
             logger.trace("Adding file '{}' to combined result", file);
 
-            final MyLineProcessor lineProcessor = new MyLineProcessor(file.getAbsolutePath());
-            Files.readLines(file, ENCODING, lineProcessor);
-            result.add(lineProcessor.getConfigSnapshotHolder(header, middle, footer));
+            ConfigSnapshotHolder configSnapshotHolder = loadLastConfig(file);
+            result.add(configSnapshotHolder);
         }
         return result;
     }
 
+    public static ConfigSnapshotHolder loadLastConfig(File file) throws IOException {
+        final MyLineProcessor lineProcessor = new MyLineProcessor(file.getAbsolutePath());
+        Files.readLines(file, ENCODING, lineProcessor);
+        return lineProcessor.getConfigSnapshotHolder(header, middle, footer);
+    }
+
 
     @Override
     public void close() {
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml b/opendaylight/config/config-persister-directory-autodetect-adapter/pom.xml
new file mode 100644 (file)
index 0000000..0ec7726
--- /dev/null
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>config-subsystem</artifactId>
+        <groupId>org.opendaylight.controller</groupId>
+        <version>0.2.3-SNAPSHOT</version>
+        <relativePath>..</relativePath>
+    </parent>
+    <artifactId>config-persister-directory-autodetect-adapter</artifactId>
+    <name>${project.artifactId}</name>
+    <packaging>bundle</packaging>
+
+    <dependencies>
+        <!-- compile dependencies -->
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>config-persister-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-persister-directory-adapter</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.controller</groupId>
+            <artifactId>config-persister-directory-xml-adapter</artifactId>
+            <version>${config.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+        </dependency>
+
+        <!-- test dependencies -->
+        <dependency>
+            <groupId>org.opendaylight.bgpcep</groupId>
+            <artifactId>mockito-configuration</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <!-- workaround for creating version according to OSGi specification (major.minor.micro[.qualifier] -->
+            <plugin>
+                <groupId>org.codehaus.groovy.maven</groupId>
+                <artifactId>gmaven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>generate-sources</phase>
+                        <goals>
+                            <goal>execute</goal>
+                        </goals>
+                        <configuration>
+                            <source>
+                                System.setProperty("osgiversion", "${project.version}".replace('-', '.'))
+                            </source>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Fragment-Host>${project.groupId}.config-persister-impl;bundle-version=${osgiversion}
+                        </Fragment-Host>
+                        <Provide-Capability>org.opendaylight.controller.config.persister.storage.adapter
+                        </Provide-Capability>
+                        <Import-Package>
+                            com.google.common.base,
+                            com.google.common.io,
+                            org.apache.commons.io,
+                            org.opendaylight.controller.config.persist.api,
+                            org.slf4j,
+                            com.google.common.collect,
+                            javax.xml.bind,
+                            javax.xml.bind.annotation,
+                            javax.xml.transform,
+                            javax.xml.transform.stream,
+                            org.eclipse.persistence.jaxb,
+                            org.apache.commons.lang3
+                        </Import-Package>
+                        <Private-Package>
+                            org.opendaylight.controller.config.persist.storage.file.xml.model,
+                            org.opendaylight.controller.config.persist.storage.directory,
+                            org.opendaylight.controller.config.persist.storage.directory.xml,
+                        </Private-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersister.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersister.java
new file mode 100644 (file)
index 0000000..f262952
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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.config.persist.storage.directory.autodetect;
+
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.storage.directory.DirectoryPersister;
+import org.opendaylight.controller.config.persist.storage.directory.xml.XmlDirectoryPersister;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.bind.JAXBException;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class AutodetectDirectoryPersister implements Persister {
+    private static final Logger logger = LoggerFactory.getLogger(AutodetectDirectoryPersister.class);
+
+    private final File storage;
+
+    public AutodetectDirectoryPersister(File storage) {
+        checkArgument(storage.exists() && storage.isDirectory(), "Storage directory does not exist: " + storage);
+        this.storage = storage;
+    }
+
+    @Override
+    public void persistConfig(ConfigSnapshotHolder holder) throws IOException {
+        throw new UnsupportedOperationException("This adapter is read only. Please set readonly=true on " + getClass());
+    }
+
+    @Override
+    public List<ConfigSnapshotHolder> loadLastConfigs() throws IOException {
+        File[] filesArray = storage.listFiles();
+        if (filesArray == null || filesArray.length == 0) {
+            return Collections.emptyList();
+        }
+        List<File> sortedFiles = new ArrayList<>(Arrays.asList(filesArray));
+        Collections.sort(sortedFiles);
+
+        // combine all found files
+        logger.debug("Reading files in following order: {}", sortedFiles);
+
+        List<ConfigSnapshotHolder> result = new ArrayList<>();
+        for (File file : sortedFiles) {
+            logger.trace("Adding file '{}' to combined result", file);
+
+            FileType fileType = FileType.getFileType(file);
+            logger.trace("File '{}' detected as {} storage", file, fileType);
+
+            ConfigSnapshotHolder snapshot = loadLastConfig(file, fileType);
+            result.add(snapshot);
+        }
+        return result;
+    }
+
+    private ConfigSnapshotHolder loadLastConfig(File file, FileType fileType) throws IOException {
+        switch (fileType) {
+        case plaintext:
+            return DirectoryPersister.loadLastConfig(file);
+        case xml:
+            try {
+                return XmlDirectoryPersister.loadLastConfig(file);
+            } catch (JAXBException e) {
+                logger.warn("Unable to restore configuration snapshot from {}", file, e);
+                throw new IllegalStateException("Unable to restore configuration snapshot from " + file, e);
+            }
+        default:
+            throw new IllegalStateException("Unknown storage type " + fileType);
+        }
+    }
+
+    @Override
+    public void close() {
+
+    }
+
+    @Override
+    public String toString() {
+        final StringBuffer sb = new StringBuffer("AutodetectDirectoryPersister{");
+        sb.append("storage=").append(storage);
+        sb.append('}');
+        return sb.toString();
+    }
+}
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryStorageAdapter.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryStorageAdapter.java
new file mode 100644 (file)
index 0000000..f856ddd
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * 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.config.persist.storage.directory.autodetect;
+
+import com.google.common.base.Preconditions;
+import org.opendaylight.controller.config.persist.api.Persister;
+import org.opendaylight.controller.config.persist.api.PropertiesProvider;
+import org.opendaylight.controller.config.persist.api.StorageAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+
+/**
+ * StorageAdapter that retrieves initial configuration from a directory. If multiple files are present, snapshot and
+ * required capabilities will be merged together. Writing to this persister is not supported.
+ */
+public class AutodetectDirectoryStorageAdapter implements StorageAdapter {
+    private static final Logger logger = LoggerFactory.getLogger(AutodetectDirectoryStorageAdapter.class);
+
+    public static final String DIRECTORY_STORAGE_PROP = "directoryStorage";
+
+
+    @Override
+    public Persister instantiate(PropertiesProvider propertiesProvider) {
+        String fileStorageProperty = propertiesProvider.getProperty(DIRECTORY_STORAGE_PROP);
+        Preconditions.checkNotNull(fileStorageProperty, "Unable to find " + propertiesProvider.getFullKeyForReporting(DIRECTORY_STORAGE_PROP));
+        File storage  = new File(fileStorageProperty);
+        logger.debug("Using {}", storage);
+        return new AutodetectDirectoryPersister(storage);
+    }
+
+}
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileType.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/main/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileType.java
new file mode 100644 (file)
index 0000000..03654eb
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * 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.config.persist.storage.directory.autodetect;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+import org.apache.commons.lang3.StringUtils;
+import org.opendaylight.controller.config.persist.storage.directory.DirectoryPersister;
+import org.opendaylight.controller.config.persist.storage.file.xml.model.ConfigSnapshot;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+enum FileType {
+
+    plaintext, xml;
+
+    public static final String XML_STORAGE_FIRST_LINE = "<" + ConfigSnapshot.SNAPSHOT_ROOT_ELEMENT_NAME + ">";
+
+    static FileType getFileType(File file) {
+        String firstLine = readFirstLine(file);
+        if(isPlaintextStorage(firstLine)) {
+            return plaintext;
+        } else if(isXmlStorage(firstLine))
+            return xml;
+
+        throw new IllegalArgumentException("File " + file + " is not of permitted storage type: " + Arrays.toString(FileType.values()));
+    }
+
+    private static boolean isXmlStorage(String firstLine) {
+        return firstLine.startsWith(XML_STORAGE_FIRST_LINE);
+    }
+
+    private static boolean isPlaintextStorage(String firstLine) {
+        return firstLine.startsWith(DirectoryPersister.MODULES_START);
+
+    }
+
+    @VisibleForTesting
+    static String readFirstLine(File file) {
+        FirstLineReadingProcessor callback = new FirstLineReadingProcessor();
+        try {
+            return Files.readLines(file, Charsets.UTF_8, callback);
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Unable to detect file type of file " + file, e);
+        }
+    }
+
+
+    private static class FirstLineReadingProcessor implements com.google.common.io.LineProcessor<String> {
+        private String firstNonBlankLine;
+
+        @Override
+        public boolean processLine(String line) throws IOException {
+            if(isEmptyLine(line)) {
+                return true;
+            } else {
+                firstNonBlankLine = line.trim();
+                return false;
+            }
+        }
+
+        private boolean isEmptyLine(String line) {
+            return StringUtils.isBlank(line);
+        }
+
+        @Override
+        public String getResult() {
+            return firstNonBlankLine;
+        }
+    }
+}
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersisterTest.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/AutodetectDirectoryPersisterTest.java
new file mode 100644 (file)
index 0000000..7e42391
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.config.persist.storage.directory.autodetect;
+
+import junit.framework.Assert;
+import org.junit.Test;
+import org.junit.matchers.JUnitMatchers;
+import org.opendaylight.controller.config.persist.api.ConfigSnapshotHolder;
+
+import java.io.File;
+import java.util.List;
+
+public class AutodetectDirectoryPersisterTest {
+
+    @Test
+    public void testCombined() throws Exception {
+        File resourcePath = FileTypeTest.getResourceAsFile("/combined/1controller.txt.config");
+
+        AutodetectDirectoryPersister persister = new AutodetectDirectoryPersister(resourcePath.getParentFile());
+        List<ConfigSnapshotHolder> configs = persister.loadLastConfigs();
+
+        Assert.assertEquals(2, configs.size());
+        String snapFromTxt = configs.get(0).getConfigSnapshot();
+        org.junit.Assert.assertThat(snapFromTxt, JUnitMatchers.containsString("<config>txt</config>"));
+        org.junit.Assert.assertThat(snapFromTxt, JUnitMatchers.containsString("<service>txt</service>"));
+
+        String snapFromXml = configs.get(1).getConfigSnapshot();
+        org.junit.Assert.assertThat(snapFromXml, JUnitMatchers.containsString("<config>xml</config>"));
+
+        Assert.assertEquals(configs.get(0).getCapabilities(), configs.get(1).getCapabilities());
+    }
+}
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileTypeTest.java b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/java/org/opendaylight/controller/config/persist/storage/directory/autodetect/FileTypeTest.java
new file mode 100644 (file)
index 0000000..bbc272d
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.config.persist.storage.directory.autodetect;
+
+import junit.framework.Assert;
+import org.junit.Test;
+import org.junit.matchers.JUnitMatchers;
+
+import java.io.File;
+
+public class FileTypeTest {
+
+    @Test
+    public void testPlaintext() throws Exception {
+        File file = getResourceAsFile("/test.txt.config");
+
+        FileType type = FileType.getFileType(file);
+        Assert.assertEquals(FileType.plaintext, type);
+
+    }
+
+    @Test
+    public void testXml() throws Exception {
+        File file = getResourceAsFile("/test.xml.config");
+
+        FileType type = FileType.getFileType(file);
+        Assert.assertEquals(FileType.xml, type);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testUnknown() throws Exception {
+        File file = getResourceAsFile("/unknown.config");
+
+        try {
+            FileType.getFileType(file);
+        } catch (IllegalArgumentException e) {
+            org.junit.Assert.assertThat(e.getMessage(), JUnitMatchers.containsString("File " + file + " is not of permitted storage type"));
+            throw e;
+        }
+    }
+
+    static File getResourceAsFile(String resource) {
+        String f = FileTypeTest.class.getResource(resource).getFile();
+        return new File(f);
+    }
+
+}
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/1controller.txt.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/1controller.txt.config
new file mode 100644 (file)
index 0000000..f72cd1c
--- /dev/null
@@ -0,0 +1,8 @@
+//MODULES START
+        <config>txt</config>
+//SERVICES START
+        <service>txt</service>
+//CAPABILITIES START
+cap1&rev
+cap2
+capa a
\ No newline at end of file
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/2controller.xml.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/combined/2controller.xml.config
new file mode 100644 (file)
index 0000000..988f866
--- /dev/null
@@ -0,0 +1,10 @@
+<snapshot>
+    <required-capabilities>
+        <capability>cap1&amp;rev</capability>
+        <capability>cap2</capability>
+        <capability>capa a</capability>
+    </required-capabilities>
+    <configuration>
+        <config>xml</config>
+    </configuration>
+</snapshot>
\ No newline at end of file
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.txt.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.txt.config
new file mode 100644 (file)
index 0000000..edf37ca
--- /dev/null
@@ -0,0 +1,2 @@
+//MODULES START
+configuration
\ No newline at end of file
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.xml.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/test.xml.config
new file mode 100644 (file)
index 0000000..fe94299
--- /dev/null
@@ -0,0 +1,2 @@
+
+<snapshot>
\ No newline at end of file
diff --git a/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/unknown.config b/opendaylight/config/config-persister-directory-autodetect-adapter/src/test/resources/unknown.config
new file mode 100644 (file)
index 0000000..c4218c8
--- /dev/null
@@ -0,0 +1,2 @@
+unknown
+file type
\ No newline at end of file
index f6f6de9..0ca47ed 100644 (file)
@@ -63,17 +63,21 @@ public class XmlDirectoryPersister implements Persister {
 
     private ConfigSnapshotHolder fromXmlSnapshot(File file) {
         try {
-            JAXBContext jaxbContext = JAXBContext.newInstance(ConfigSnapshot.class);
-            Unmarshaller um = jaxbContext.createUnmarshaller();
-
-            return asHolder((ConfigSnapshot) um.unmarshal(file));
+            return loadLastConfig(file);
         } catch (JAXBException e) {
             logger.warn("Unable to restore configuration snapshot from {}", file, e);
             throw new IllegalStateException("Unable to restore configuration snapshot from " + file, e);
         }
     }
 
-    private ConfigSnapshotHolder asHolder(final ConfigSnapshot unmarshalled) {
+    public static ConfigSnapshotHolder loadLastConfig(File file) throws JAXBException {
+        JAXBContext jaxbContext = JAXBContext.newInstance(ConfigSnapshot.class);
+        Unmarshaller um = jaxbContext.createUnmarshaller();
+
+        return asHolder((ConfigSnapshot) um.unmarshal(file));
+    }
+
+    private static ConfigSnapshotHolder asHolder(final ConfigSnapshot unmarshalled) {
         return new ConfigSnapshotHolder() {
             @Override
             public String getConfigSnapshot() {
index 4197600..cfc7085 100644 (file)
@@ -15,9 +15,11 @@ import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 import java.util.SortedSet;
 
-@XmlRootElement(name = "snapshot")
+@XmlRootElement(name = ConfigSnapshot.SNAPSHOT_ROOT_ELEMENT_NAME)
 public class ConfigSnapshot {
 
+    public static final String SNAPSHOT_ROOT_ELEMENT_NAME = "snapshot";
+
     private String configSnapshot;
     private SortedSet<String> capabilities;
 
index 36b109f..1a29046 100644 (file)
@@ -41,6 +41,7 @@
         <module>netty-timer-config</module>
         <module>config-persister-directory-adapter</module>
         <module>config-persister-directory-xml-adapter</module>
+        <module>config-persister-directory-autodetect-adapter</module>
         <module>yang-test-plugin</module>
     </modules>
 
index f1eca41..9f3862f 100644 (file)
           <artifactId>config-persister-directory-xml-adapter</artifactId>
           <version>${config.version}</version>
         </dependency>
+        <dependency>
+          <groupId>org.opendaylight.controller</groupId>
+          <artifactId>config-persister-directory-autodetect-adapter</artifactId>
+          <version>${config.version}</version>
+        </dependency>
 
        <!-- Netconf -->
         <dependency>
index 995e407..dccb267 100644 (file)
@@ -26,7 +26,11 @@ netconf.ssh.pk.path = ./configuration/RSA.pk
 
 netconf.config.persister.active=1,2
 # read startup configuration
-netconf.config.persister.1.storageAdapterClass=org.opendaylight.controller.config.persist.storage.directory.DirectoryStorageAdapter
+#netconf.config.persister.1.storageAdapterClass=org.opendaylight.controller.config.persist.storage.directory.DirectoryStorageAdapter
+#netconf.config.persister.1.properties.directoryStorage=configuration/initial/
+#netconf.config.persister.1.readonly=true
+
+netconf.config.persister.1.storageAdapterClass=org.opendaylight.controller.config.persist.storage.directory.autodetect.AutodetectDirectoryStorageAdapter
 netconf.config.persister.1.properties.directoryStorage=configuration/initial/
 netconf.config.persister.1.readonly=true
 
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.conf b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.conf
deleted file mode 100644 (file)
index c2f9bc3..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-//MODULES START
-       <module>
-               <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
-               <name>global-boss-group</name>
-       </module>
-       <module>
-               <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
-               <name>global-worker-group</name>
-       </module>
-       <module>
-               <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:timer">netty:netty-hashed-wheel-timer</type>
-               <name>global-timer</name>
-       </module>
-       <module>
-               <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor">netty:netty-global-event-executor</type>
-               <name>global-event-executor</name>
-       </module>
-//SERVICES START
-       <service>
-               <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-threadgroup</type>
-               <instance>
-                       <name>global-boss-group</name>
-                       <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-boss-group']</provider>
-               </instance>
-               <instance>
-                       <name>global-worker-group</name>
-                       <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-worker-group']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-event-executor</type>
-               <instance>
-                       <name>global-event-executor</name>
-                       <provider>/modules/module[type='netty-global-event-executor'][name='global-event-executor']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-timer</type>
-               <instance>
-                       <name>global-timer</name>
-                       <provider>/modules/module[type='netty-hashed-wheel-timer'][name='global-timer']</provider>
-               </instance>
-       </service>
-//CAPABILITIES START
-urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&revision=2013-11-19
-urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&revision=2013-11-12
-urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup?module=threadgroup&revision=2013-11-07
-urn:opendaylight:params:xml:ns:yang:controller:netty:timer?module=netty-timer&revision=2013-11-19
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml.conf b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/00-netty.xml.conf
new file mode 100644 (file)
index 0000000..9ba5908
--- /dev/null
@@ -0,0 +1,60 @@
+<snapshot>
+    <required-capabilities>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty?module=netty&amp;revision=2013-11-19</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&amp;revision=2013-11-12</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup?module=threadgroup&amp;revision=2013-11-07</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:timer?module=netty-timer&amp;revision=2013-11-19</capability>
+    </required-capabilities>
+    <configuration>
+    
+        <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <module>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
+                    <name>global-boss-group</name>
+                </module>
+                <module>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:threadgroup">netty:netty-threadgroup-fixed</type>
+                    <name>global-worker-group</name>
+                </module>
+                <module>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:timer">netty:netty-hashed-wheel-timer</type>
+                    <name>global-timer</name>
+                </module>
+                <module>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor">netty:netty-global-event-executor</type>
+                    <name>global-event-executor</name>
+                </module>
+            </modules>
+            
+            <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <service>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-threadgroup</type>
+                    <instance>
+                        <name>global-boss-group</name>
+                        <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-boss-group']</provider>
+                    </instance>
+                    <instance>
+                        <name>global-worker-group</name>
+                        <provider>/modules/module[type='netty-threadgroup-fixed'][name='global-worker-group']</provider>
+                    </instance>
+                </service>
+                <service>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-event-executor</type>
+                    <instance>
+                        <name>global-event-executor</name>
+                        <provider>/modules/module[type='netty-global-event-executor'][name='global-event-executor']</provider>
+                    </instance>
+                </service>
+                <service>
+                    <type xmlns:netty="urn:opendaylight:params:xml:ns:yang:controller:netty">netty:netty-timer</type>
+                    <instance>
+                        <name>global-timer</name>
+                        <provider>/modules/module[type='netty-hashed-wheel-timer'][name='global-timer']</provider>
+                    </instance>
+                </service>
+            </services>
+        </data>
+
+    </configuration>
+</snapshot>
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.conf b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.conf
deleted file mode 100644 (file)
index edee185..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-//MODULES START
-       <module>
-               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:schema-service-singleton</type>
-               <name>yang-schema-service</name>
-       </module>
-       <module>
-               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:hash-map-data-store</type>
-               <name>hash-map-data-store</name>
-       </module>
-       <module>
-        <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store">prefix:dom-clustered-store-impl</type>
-        <name>cluster-data-store</name>
-    </module>
-       <module>
-               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
-               <name>dom-broker</name>
-               <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
-                       <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
-            <!-- to switch to the clustered data store, comment out the hash-map-data-store <name> and uncomment the cluster-data-store one -->
-            <name>hash-map-data-store</name>
-            <!-- <name>cluster-data-store</name> -->
-               </data-store>
-       </module>
-       <module>
-               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
-               <name>binding-broker-impl</name>
-               <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                       <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
-                       <name>binding-notification-broker</name>
-               </notification-service>
-               <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                       <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
-                       <name>binding-data-broker</name>
-               </data-broker>
-       </module>
-       <module>
-               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
-               <name>runtime-mapping-singleton</name>
-       </module>
-       <module>
-               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
-               <name>binding-notification-broker</name>
-       </module>
-       <module>
-               <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-broker</type>
-               <name>binding-data-broker</name>
-               <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                       <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
-                       <name>dom-broker</name>
-               </dom-broker>
-               <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
-                       <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
-                       <name>runtime-mapping-singleton</name>
-               </mapping-service>
-       </module>
-//SERVICES START
-       <service>
-               <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
-               <instance>
-                       <name>yang-schema-service</name>
-                       <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
-               <instance>
-                       <name>binding-notification-broker</name>
-                       <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
-               <instance>
-                       <name>hash-map-data-store</name>
-                       <provider>/modules/module[type='hash-map-data-store'][name='hash-map-data-store']</provider>
-               </instance>
-               <instance>
-                       <name>cluster-data-store</name>
-                       <provider>/modules/module[type='dom-clustered-store-impl'][name='cluster-data-store']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
-               <instance>
-                       <name>binding-osgi-broker</name>
-                       <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
-               <instance>
-                       <name>binding-rpc-broker</name>
-                       <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
-               <instance>
-                       <name>runtime-mapping-singleton</name>
-                       <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
-               </instance>
-       </service>
-       <service>
-       <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
-               <instance>
-                       <name>dom-broker</name>
-                       <provider>/modules/module[type='dom-broker-impl'][name='dom-broker']</provider>
-               </instance>
-       </service>
-       <service>
-               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
-               <instance>
-                       <name>binding-data-broker</name>
-                       <provider>/modules/module[type='binding-data-broker'][name='binding-data-broker']</provider>
-               </instance>
-       </service>
-//CAPABILITIES START
-urn:opendaylight:l2:types?module=opendaylight-l2-types&revision=2013-08-27
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:threadpool?module=threadpool&revision=2013-04-09
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:controller:config?module=config&revision=2013-04-05
-urn:ietf:params:netconf:capability:candidate:1.0
-urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&revision=2010-10-04
-urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&revision=2013-11-12
-urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&revision=2013-06-17
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&revision=2013-10-28
-urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&revision=2010-09-24
-urn:ietf:params:netconf:capability:rollback-on-error:1.0
-urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&revision=2010-09-24
-urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl?module=threadpool-impl&revision=2013-04-05
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28
-urn:opendaylight:yang:extension:yang-ext?module=yang-ext&revision=2013-07-09
-urn:opendaylight:params:xml:ns:yang:iana?module=iana&revision=2013-08-16
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&revision=2013-10-28
-urn:opendaylight:params:xml:ns:yang:ieee754?module=ieee754&revision=2013-08-19
-urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store?module=odl-sal-dom-clustered-store-cfg&revision=2013-10-28
diff --git a/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml.conf b/opendaylight/distribution/opendaylight/src/main/resources/configuration/initial/01-md-sal.xml.conf
new file mode 100644 (file)
index 0000000..20f5989
--- /dev/null
@@ -0,0 +1,153 @@
+<snapshot>
+
+    <configuration>
+    
+        <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+            <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:schema-service-singleton</type>
+                    <name>yang-schema-service</name>
+                </module>
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:hash-map-data-store</type>
+                    <name>hash-map-data-store</name>
+                </module>
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store">prefix:dom-clustered-store-impl</type>
+                    <name>cluster-data-store</name>
+                </module>
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-broker-impl</type>
+                    <name>dom-broker</name>
+                    <data-store xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
+                        <!-- to switch to the clustered data store, comment out the hash-map-data-store <name> and uncomment the cluster-data-store one -->
+                        <name>hash-map-data-store</name>
+                        <!-- <name>cluster-data-store</name> -->
+                    </data-store>
+                </module>
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-broker-impl</type>
+                    <name>binding-broker-impl</name>
+                    <notification-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+                        <name>binding-notification-broker</name>
+                    </notification-service>
+                    <data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+                        <name>binding-data-broker</name>
+                    </data-broker>
+                </module>
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:runtime-generated-mapping</type>
+                    <name>runtime-mapping-singleton</name>
+                </module>
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-notification-broker</type>
+                    <name>binding-notification-broker</name>
+                </module>
+                <module>
+                    <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-broker</type>
+                    <name>binding-data-broker</name>
+                    <dom-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                        <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+                        <name>dom-broker</name>
+                    </dom-broker>
+                    <mapping-service xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+                        <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding:binding-dom-mapping-service</type>
+                        <name>runtime-mapping-singleton</name>
+                    </mapping-service>
+                </module>
+            </modules>
+            
+            <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+                       <service>
+                               <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+                               <instance>
+                                       <name>yang-schema-service</name>
+                                       <provider>/modules/module[type='schema-service-singleton'][name='yang-schema-service']</provider>
+                               </instance>
+                       </service>
+                       <service>
+                               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-notification-service</type>
+                               <instance>
+                                       <name>binding-notification-broker</name>
+                                       <provider>/modules/module[type='binding-notification-broker'][name='binding-notification-broker']</provider>
+                               </instance>
+                       </service>
+                       <service>
+                               <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-data-store</type>
+                               <instance>
+                                       <name>hash-map-data-store</name>
+                                       <provider>/modules/module[type='hash-map-data-store'][name='hash-map-data-store']</provider>
+                               </instance>
+                               <instance>
+                                       <name>cluster-data-store</name>
+                                       <provider>/modules/module[type='dom-clustered-store-impl'][name='cluster-data-store']</provider>
+                               </instance>
+                       </service>
+                       <service>
+                               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
+                               <instance>
+                                       <name>binding-osgi-broker</name>
+                                       <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+                               </instance>
+                       </service>
+                       <service>
+                               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
+                               <instance>
+                                       <name>binding-rpc-broker</name>
+                                       <provider>/modules/module[type='binding-broker-impl'][name='binding-broker-impl']</provider>
+                               </instance>
+                       </service>
+                       <service>
+                               <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">binding-impl:binding-dom-mapping-service</type>
+                               <instance>
+                                       <name>runtime-mapping-singleton</name>
+                                       <provider>/modules/module[type='runtime-generated-mapping'][name='runtime-mapping-singleton']</provider>
+                               </instance>
+                       </service>
+                       <service>
+                       <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-broker-osgi-registry</type>
+                               <instance>
+                                       <name>dom-broker</name>
+                                       <provider>/modules/module[type='dom-broker-impl'][name='dom-broker']</provider>
+                               </instance>
+                       </service>
+                       <service>
+                               <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-data-broker</type>
+                               <instance>
+                                       <name>binding-data-broker</name>
+                                       <provider>/modules/module[type='binding-data-broker'][name='binding-data-broker']</provider>
+                               </instance>
+                       </service>
+
+            </services>
+        </data>
+
+    </configuration>
+    
+    <required-capabilities>
+        <capability>urn:opendaylight:l2:types?module=opendaylight-l2-types&amp;revision=2013-08-27</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool?module=threadpool&amp;revision=2013-04-09</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:config?module=config&amp;revision=2013-04-05</capability>
+        <capability>urn:ietf:params:netconf:capability:candidate:1.0</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring?module=ietf-netconf-monitoring&amp;revision=2010-10-04</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:netty:eventexecutor?module=netty-event-executor&amp;revision=2013-11-12</capability>
+        <capability>urn:ietf:params:xml:ns:yang:rpc-context?module=rpc-context&amp;revision=2013-06-17</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl?module=opendaylight-sal-binding-broker-impl&amp;revision=2013-10-28</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-inet-types?module=ietf-inet-types&amp;revision=2010-09-24</capability>
+        <capability>urn:ietf:params:netconf:capability:rollback-on-error:1.0</capability>
+        <capability>urn:ietf:params:xml:ns:yang:ietf-yang-types?module=ietf-yang-types&amp;revision=2010-09-24</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:threadpool:impl?module=threadpool-impl&amp;revision=2013-04-05</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:yang:extension:yang-ext?module=yang-ext&amp;revision=2013-07-09</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:iana?module=iana&amp;revision=2013-08-16</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:common?module=opendaylight-md-sal-common&amp;revision=2013-10-28</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:ieee754?module=ieee754&amp;revision=2013-08-19</capability>
+        <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:cluster:store?module=odl-sal-dom-clustered-store-cfg&amp;revision=2013-10-28</capability>
+    </required-capabilities>
+</snapshot>
+