summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaros Marsalek <mmarsale@cisco.com>2016-05-18 15:05:51 +0200
committerMaros Marsalek <mmarsale@cisco.com>2016-05-24 08:36:34 +0000
commitf9b2551eae7b4410b6910a05f19413b9b83137d4 (patch)
tree476f11bd2fdf611083ffe5e6363620046f37eca8
parentd421438681e97ef7213a5cb925c49755cd9fb4b6 (diff)
HONEYCOMB-61: Restore configuration and context from persisted files
Change-Id: I6edce127f8895f5d65998b4be71a0a111ca2e8bb Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
-rw-r--r--v3po/data-api/src/main/yang/data-api.yang6
-rw-r--r--v3po/data-impl/pom.xml4
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/PersistingDataTreeAdapter.java51
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/WriteTransaction.java4
-rw-r--r--v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/InMemoryDataTreeModule.java1
-rw-r--r--v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/PersistingDataTreeAdapterModule.java8
-rw-r--r--v3po/data-impl/src/main/yang/data-impl.yang9
-rw-r--r--v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/PersistingDataTreeAdapterTest.java68
-rw-r--r--v3po/data-impl/src/test/resources/expected-persisted-output.txt5
-rw-r--r--v3po/features/pom.xml7
-rw-r--r--v3po/features/src/main/features/features.xml1
-rw-r--r--v3po/impl/pom.xml5
-rw-r--r--v3po/impl/src/main/config/default-config.xml120
-rw-r--r--v3po/impl/src/main/config/initializer-config.xml224
-rw-r--r--v3po/translate-utils/pom.xml4
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/JsonUtils.java102
-rw-r--r--v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/JsonUtilsTest.java109
-rw-r--r--v3po/translate-utils/src/test/resources/expected-persisted-output.txt8
-rw-r--r--v3po/translate-utils/src/test/resources/test-persistence.yang (renamed from v3po/data-impl/src/test/resources/test-persistence.yang)6
-rw-r--r--v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/DataTreeInitializer.java4
-rw-r--r--v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/InterfacesInitializer.java2
-rw-r--r--v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/RestoringInitializer.java109
-rw-r--r--v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/VppInitializer.java2
-rw-r--r--v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/ConfigurationInitializerRegistryModule.java55
-rw-r--r--v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/ConfigurationInitializerRegistryModuleFactory.java13
-rw-r--r--v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/InterfacesConfigurationInitializerModule.java24
-rw-r--r--v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/InterfacesConfigurationInitializerModuleFactory.java13
-rw-r--r--v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/PersistedFileInitializerModule.java38
-rw-r--r--v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/PersistedFileInitializerModuleFactory.java13
-rw-r--r--v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/VppConfigurationInitializerModule.java25
-rw-r--r--v3po/vpp-cfg-init/src/main/yang/vpp-cfg-init.yang127
31 files changed, 886 insertions, 281 deletions
diff --git a/v3po/data-api/src/main/yang/data-api.yang b/v3po/data-api/src/main/yang/data-api.yang
index 11d963e4b..693a73acd 100644
--- a/v3po/data-api/src/main/yang/data-api.yang
+++ b/v3po/data-api/src/main/yang/data-api.yang
@@ -29,4 +29,10 @@ module data-api {
config:java-class io.fd.honeycomb.v3po.data.ModifiableDataManager;
}
+ typedef datatree-type {
+ type enumeration {
+ enum config;
+ enum oper;
+ }
+ }
} \ No newline at end of file
diff --git a/v3po/data-impl/pom.xml b/v3po/data-impl/pom.xml
index 46faab7a2..1d716a6d9 100644
--- a/v3po/data-impl/pom.xml
+++ b/v3po/data-impl/pom.xml
@@ -49,10 +49,6 @@
<artifactId>mdsal-binding-dom-codec</artifactId>
</dependency>
<dependency>
- <groupId>org.opendaylight.yangtools</groupId>
- <artifactId>yang-data-codec-gson</artifactId>
- </dependency>
- <dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-core-api</artifactId>
<version>1.3.0-Beryllium</version> <!-- FIXME use dependency management -->
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/PersistingDataTreeAdapter.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/PersistingDataTreeAdapter.java
index a54b7f148..df5bbee4b 100644
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/PersistingDataTreeAdapter.java
+++ b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/PersistingDataTreeAdapter.java
@@ -18,33 +18,22 @@ package io.fd.honeycomb.v3po.data.impl;
import static com.google.common.base.Preconditions.checkArgument;
-import com.google.common.base.Charsets;
import com.google.common.base.Optional;
-import com.google.gson.stream.JsonWriter;
+import io.fd.honeycomb.v3po.translate.util.JsonUtils;
import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import javax.annotation.Nonnull;
import org.opendaylight.controller.sal.core.api.model.SchemaService;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactory;
-import org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter;
-import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -82,17 +71,16 @@ public class PersistingDataTreeAdapter implements org.opendaylight.yangtools.yan
private Path testPersistPath(final Path persistPath) {
try {
checkArgument(!Files.isDirectory(persistPath), "Path %s points to a directory", persistPath);
+ if(Files.exists(persistPath)) {
+ checkArgument(Files.isReadable(persistPath),
+ "Provided path %s points to existing, but non-readable file", persistPath);
+ return persistPath;
+ }
Files.createDirectories(persistPath.getParent());
Files.write(persistPath, new byte[]{}, StandardOpenOption.CREATE);
} catch (IOException | UnsupportedOperationException e) {
LOG.warn("Provided path for persistence: {} is not usable", persistPath, e);
throw new IllegalArgumentException("Path " + persistPath + " cannot be used as ");
- } finally {
- try {
- Files.delete(persistPath);
- } catch (IOException e) {
- LOG.warn("Unable to delete file at {}", persistPath, e);
- }
}
return persistPath;
@@ -131,17 +119,8 @@ public class PersistingDataTreeAdapter implements org.opendaylight.yangtools.yan
if(Files.exists(path)) {
Files.delete(path);
}
- // TODO once we are in static environment, do the writer, streamWriter and NNWriter initialization only once
- final JsonWriter
- jsonWriter = createJsonWriter(Files.newOutputStream(path, StandardOpenOption.CREATE), true);
- final NormalizedNodeStreamWriter streamWriter = JSONNormalizedNodeStreamWriter
- .createNestedWriter(JSONCodecFactory.create(schemaServiceDependency.getGlobalContext()), SchemaPath.ROOT, null, jsonWriter);
- final NormalizedNodeWriter normalizedNodeWriter =
- NormalizedNodeWriter.forStreamWriter(streamWriter, true);
- jsonWriter.beginObject();
- writeChildren(normalizedNodeWriter,(ContainerNode) currentRoot.get());
- jsonWriter.endObject();
- jsonWriter.flush();
+ JsonUtils.writeJsonRoot(currentRoot.get(), schemaServiceDependency.getGlobalContext(),
+ Files.newOutputStream(path, StandardOpenOption.CREATE));
LOG.trace("Data persisted successfully in {}", path);
} catch (IOException e) {
throw new IllegalStateException("Unable to persist current data", e);
@@ -151,20 +130,6 @@ public class PersistingDataTreeAdapter implements org.opendaylight.yangtools.yan
}
}
- private void writeChildren(final NormalizedNodeWriter nnWriter, final ContainerNode data) throws IOException {
- for(final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> child : data.getValue()) {
- nnWriter.write(child);
- }
- }
-
- private JsonWriter createJsonWriter(final OutputStream entityStream, boolean prettyPrint) {
- if (prettyPrint) {
- return JsonWriterFactory.createJsonWriter(new OutputStreamWriter(entityStream, Charsets.UTF_8), 2);
- } else {
- return JsonWriterFactory.createJsonWriter(new OutputStreamWriter(entityStream, Charsets.UTF_8));
- }
- }
-
@Override
public YangInstanceIdentifier getRootPath() {
return delegateDependency.getRootPath();
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/WriteTransaction.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/WriteTransaction.java
index 3644a9fe7..ac4ba9049 100644
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/WriteTransaction.java
+++ b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/WriteTransaction.java
@@ -77,11 +77,11 @@ final class WriteTransaction implements DOMDataWriteTransaction {
final java.util.function.Consumer<DataModification> r) {
switch (store) {
case CONFIGURATION:
- checkArgument(configModification != null, "Modification of {} is not supported", store);
+ checkArgument(configModification != null, "Modification of %s is not supported", store);
r.accept(configModification);
break;
case OPERATIONAL:
- checkArgument(operationalModification != null, "Modification of {} is not supported", store);
+ checkArgument(operationalModification != null, "Modification of %s is not supported", store);
r.accept(operationalModification);
break;
}
diff --git a/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/InMemoryDataTreeModule.java b/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/InMemoryDataTreeModule.java
index 54c830ec0..956aa90f4 100644
--- a/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/InMemoryDataTreeModule.java
+++ b/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/InMemoryDataTreeModule.java
@@ -1,5 +1,6 @@
package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.data.impl.rev160411;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.data.api.rev160411.DatatreeType;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.tree.*;
import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory;
diff --git a/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/PersistingDataTreeAdapterModule.java b/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/PersistingDataTreeAdapterModule.java
index aa57f4d9b..145fc4345 100644
--- a/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/PersistingDataTreeAdapterModule.java
+++ b/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/PersistingDataTreeAdapterModule.java
@@ -1,6 +1,8 @@
package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.data.impl.rev160411;
+import java.nio.file.InvalidPathException;
import java.nio.file.Paths;
+import org.opendaylight.controller.config.api.JmxAttributeValidationException;
public class PersistingDataTreeAdapterModule extends
org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.data.impl.rev160411.AbstractPersistingDataTreeAdapterModule {
@@ -18,7 +20,11 @@ public class PersistingDataTreeAdapterModule extends
@Override
public void customValidation() {
- // add custom validation form module attributes here.
+ try {
+ Paths.get(getPersistFilePath());
+ } catch (InvalidPathException e) {
+ throw new JmxAttributeValidationException("Invalid persist path", e, persistFilePathJmxAttribute);
+ }
}
@Override
diff --git a/v3po/data-impl/src/main/yang/data-impl.yang b/v3po/data-impl/src/main/yang/data-impl.yang
index 3af9d8d3f..a6b217a84 100644
--- a/v3po/data-impl/src/main/yang/data-impl.yang
+++ b/v3po/data-impl/src/main/yang/data-impl.yang
@@ -24,13 +24,6 @@ module data-impl {
config:java-name-prefix InMemoryDataTree;
}
- typedef datatree-type {
- type enumeration {
- enum config;
- enum oper;
- }
- }
-
augment "/config:modules/config:module/config:configuration" {
case inmemory-data-tree {
when "/config:modules/config:module/config:type = 'inmemory-data-tree'";
@@ -45,7 +38,7 @@ module data-impl {
}
leaf type {
- type datatree-type;
+ type dapi:datatree-type;
}
}
}
diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/PersistingDataTreeAdapterTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/PersistingDataTreeAdapterTest.java
index 986d7cfb1..523d9dd70 100644
--- a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/PersistingDataTreeAdapterTest.java
+++ b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/PersistingDataTreeAdapterTest.java
@@ -16,17 +16,12 @@
package io.fd.honeycomb.v3po.data.impl;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
-import com.google.common.io.ByteStreams;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.Before;
@@ -34,28 +29,12 @@ import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.opendaylight.controller.sal.core.api.model.SchemaService;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext;
public class PersistingDataTreeAdapterTest {
- public static final String NAMESPACE = "urn:opendaylight:params:xml:ns:yang:test:persistence";
-
- // The root QNAME can be anything, onyl its children are iterated
- private static final QName ROOT_QNAME = QName.create("random", "data");
- private static final QName TOP_CONTAINER_NAME = QName.create(NAMESPACE, "2015-01-05", "top-container");
- private static final QName STRING_LEAF_QNAME = QName.create(TOP_CONTAINER_NAME, "string");
-
@Mock
private DataTree delegatingDataTree;
@Mock
@@ -71,47 +50,10 @@ public class PersistingDataTreeAdapterTest {
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
tmpPersistFile = Files.createTempFile("testing-hc-persistence", "json");
-
- // Build test yang schemas
- final CrossSourceStatementReactor.BuildAction buildAction = YangInferencePipeline.RFC6020_REACTOR.newBuild();
- buildAction.addSource(new YangStatementSourceImpl(getClass().getResourceAsStream("/test-persistence.yang")));
- final EffectiveSchemaContext effectiveSchemaContext = buildAction.buildEffective();
- doReturn(effectiveSchemaContext).when(schemaService).getGlobalContext();
-
persistingDataTreeAdapter = new PersistingDataTreeAdapter(delegatingDataTree, schemaService, tmpPersistFile);
}
@Test
- public void testPersist() throws Exception {
- doReturn(snapshot).when(delegatingDataTree).takeSnapshot();
-
- NormalizedNode<?, ?> data = getData("testing");
- doReturn(com.google.common.base.Optional.of(data)).when(snapshot).readNode(YangInstanceIdentifier.EMPTY);
- persistingDataTreeAdapter.commit(null);
- assertTrue(Files.exists(tmpPersistFile));
-
- String persisted = new String(Files.readAllBytes(tmpPersistFile));
- String expected =
- new String(ByteStreams.toByteArray(getClass().getResourceAsStream("/expected-persisted-output.txt")));
-
- assertEquals(expected, persisted);
-
- data = getData("testing2");
- doReturn(com.google.common.base.Optional.of(data)).when(snapshot).readNode(YangInstanceIdentifier.EMPTY);
- persistingDataTreeAdapter.commit(null);
-
- verify(delegatingDataTree, times(2)).commit(null);
-
- persisted = new String(Files.readAllBytes(tmpPersistFile));
- assertEquals(expected.replace("testing", "testing2"), persisted);
-
- persistingDataTreeAdapter.close();
-
- // File has to stay even after close
- assertTrue(Files.exists(tmpPersistFile));
- }
-
- @Test
public void testNoPersistOnFailure() throws Exception {
doThrow(new IllegalStateException("testing errors")).when(delegatingDataTree).commit(any(DataTreeCandidate.class));
@@ -119,19 +61,9 @@ public class PersistingDataTreeAdapterTest {
persistingDataTreeAdapter.commit(null);
fail("Exception expected");
} catch (IllegalStateException e) {
- assertFalse(Files.exists(tmpPersistFile));
verify(delegatingDataTree, times(0)).takeSnapshot();
verify(delegatingDataTree).commit(any(DataTreeCandidate.class));
}
}
- private NormalizedNode<?, ?> getData(final String stringValue) {
- return Builders.containerBuilder()
- .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(ROOT_QNAME))
- .withChild(Builders.containerBuilder()
- .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TOP_CONTAINER_NAME))
- .withChild(ImmutableNodes.leafNode(STRING_LEAF_QNAME, stringValue))
- .build())
- .build();
- }
} \ No newline at end of file
diff --git a/v3po/data-impl/src/test/resources/expected-persisted-output.txt b/v3po/data-impl/src/test/resources/expected-persisted-output.txt
deleted file mode 100644
index fb21d61e8..000000000
--- a/v3po/data-impl/src/test/resources/expected-persisted-output.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "test-persistence:top-container": {
- "string": "testing"
- }
-} \ No newline at end of file
diff --git a/v3po/features/pom.xml b/v3po/features/pom.xml
index 1233f7d96..b79e62d92 100644
--- a/v3po/features/pom.xml
+++ b/v3po/features/pom.xml
@@ -133,6 +133,13 @@
<artifactId>v3po-impl</artifactId>
<version>${project.version}</version>
<type>xml</type>
+ <classifier>init</classifier>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>v3po-impl</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
<classifier>context</classifier>
</dependency>
<dependency>
diff --git a/v3po/features/src/main/features/features.xml b/v3po/features/src/main/features/features.xml
index 66e57fce5..1e5f28f8c 100644
--- a/v3po/features/src/main/features/features.xml
+++ b/v3po/features/src/main/features/features.xml
@@ -49,6 +49,7 @@
<configfile finalname="${configfile.directory}/vpp-jvpp.xml">mvn:io.fd.honeycomb.v3po/vpp-jvpp-cfg/${project.version}/xml/config</configfile>
<configfile finalname="${configfile.directory}/v3po-context.xml">mvn:io.fd.honeycomb.v3po/v3po-impl/${project.version}/xml/context</configfile>
<configfile finalname="${configfile.directory}/v3po.xml">mvn:io.fd.honeycomb.v3po/v3po-impl/${project.version}/xml/config</configfile>
+ <configfile finalname="${configfile.directory}/v3po-init.xml">mvn:io.fd.honeycomb.v3po/v3po-impl/${project.version}/xml/init</configfile>
<configfile finalname="${configfile.directory}/v3po-netconf.xml">mvn:io.fd.honeycomb.v3po/v3po-impl/${project.version}/xml/netconf</configfile>
<configfile finalname="${configfile.directory}/v3po-restconf.xml">mvn:io.fd.honeycomb.v3po/v3po-impl/${project.version}/xml/restconf</configfile>
<configfile finalname="${configfile.directory}/v3po2vpp.xml">mvn:io.fd.honeycomb.v3po/v3po2vpp/${project.version}/xml/config</configfile>
diff --git a/v3po/impl/pom.xml b/v3po/impl/pom.xml
index 6db420bef..6f4f4e172 100644
--- a/v3po/impl/pom.xml
+++ b/v3po/impl/pom.xml
@@ -111,6 +111,11 @@
<classifier>netconf</classifier>
</artifact>
<artifact>
+ <file>src/main/config/initializer-config.xml</file>
+ <type>xml</type>
+ <classifier>init</classifier>
+ </artifact>
+ <artifact>
<file>src/main/config/context-datatree-config.xml</file>
<type>xml</type>
<classifier>context</classifier>
diff --git a/v3po/impl/src/main/config/default-config.xml b/v3po/impl/src/main/config/default-config.xml
index 7106c78ce..961ca72c0 100644
--- a/v3po/impl/src/main/config/default-config.xml
+++ b/v3po/impl/src/main/config/default-config.xml
@@ -19,7 +19,6 @@
<capability>urn:opendaylight:params:xml:ns:yang:v3po:impl?module=v3po-impl&amp;revision=2014-12-10</capability>
<capability>urn:honeycomb:params:xml:ns:yang:translate:utils?module=translate-utils&amp;revision=2016-04-06</capability>
<capability>urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg?module=vpp-jvpp-cfg&amp;revision=2016-04-06</capability>
- <capability>urn:honeycomb:params:xml:ns:yang:vpp:data:init?module=vpp-cfg-init&amp;revision=2016-04-07</capability>
<capability>urn:honeycomb:params:xml:ns:yang:data:api?module=data-api&amp;revision=2016-04-11</capability>
<capability>urn:honeycomb:params:xml:ns:yang:data:impl?module=data-impl&amp;revision=2016-04-11</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
@@ -209,85 +208,6 @@
<name>honeycomb-dom-data-broker</name>
</honeycomb-dom-data-broker>
</module>
-
- <!-- Config initialization -->
- <!-- Empty registry which does not pass data to VPP -->
- <module>
- <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:utils">prefix:noop-writer-registry</type>
- <name>noop-writer-registry</name>
- </module>
- <!-- Config data tree which does not pass data to translation layer (uses noop-write-registry) -->
- <module>
- <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:impl">prefix:honeycomb-config-data-tree</type>
- <name>cfg-init-config-data-tree</name>
-
- <!--FIXME do we need/want persistence here ? Do initializers only merge the data ? -->
- <!-- Without persistence -->
- <!--<data-tree>-->
- <!--<type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:impl">prefix:data-tree</type>-->
- <!--<name>inmemory-config-data-tree</name>-->
- <!--</data-tree>-->
- <!-- With persistence -->
- <data-tree>
- <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:data-tree</type>
- <name>inmemory-persisted-config-data-tree</name>
- </data-tree>
-
- <serializer>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-dom-mapping-service</type>
- <name>runtime-mapping-singleton</name>
- </serializer>
- <writer-registry>
- <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-writer-registry</type>
- <name>noop-writer-registry</name>
- </writer-registry>
- <context-binding-broker>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
- <name>honeycomb-context-binding-data-broker</name>
- </context-binding-broker>
- </module>
- <!-- DOM data broker for config initialization -->
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:v3po:impl">prefix:honeycomb-dom-data-broker</type>
- <name>cfg-init-dom-data-broker</name>
- <config-data-tree>
- <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:honeycomb-modifiable-data-tree</type>
- <name>cfg-init-config-data-tree</name>
- </config-data-tree>
- <operational-data-tree>
- <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:honeycomb-readable-data-tree</type>
- <name>operational-data-tree</name>
- </operational-data-tree>
- </module>
- <!-- Binding data broker for config initialization -->
- <module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-forwarded-data-broker</type>
- <name>cfg-init-binding-data-broker</name>
- <binding-forwarded-data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
- <dom-async-broker>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
- <name>cfg-init-dom-data-broker</name>
- </dom-async-broker>
- <schema-service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
- <name>yang-schema-service</name>
- </schema-service>
- <binding-mapping-service>
- <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>
- </binding-mapping-service>
- </binding-forwarded-data-broker>
- </module>
- <!-- Config initializer -->
- <module>
- <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:data:init">prefix:vpp-cfg-initializer-impl</type>
- <name>vpp-cfg-initializer</name>
- <binding-data-broker>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-async-data-broker</type>
- <name>cfg-init-binding-data-broker</name>
- </binding-data-broker>
- </module>noop-writer-registry
- <!-- END: Config initialization -->
</modules>
<services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
@@ -388,46 +308,6 @@
</instance>
</service>
- <!-- Config initialization -->
- <service>
- <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-writer-registry</type>
- <instance>
- <name>noop-writer-registry</name>
- <provider>/modules/module[type='noop-writer-registry'][name='noop-writer-registry']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:honeycomb-modifiable-data-tree</type>
- <instance>
- <name>cfg-init-config-data-tree</name>
- <provider>/modules/module[type='honeycomb-config-data-tree'][name='cfg-init-config-data-tree']
- </provider>
- </instance>
- </service>
- <service>
- <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
- <instance>
- <name>cfg-init-dom-data-broker</name>
- <provider>/modules/module[type='honeycomb-dom-data-broker'][name='cfg-init-dom-data-broker']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
- <instance>
- <name>cfg-init-binding-data-broker</name>
- <provider>/modules/module[type='binding-forwarded-data-broker'][name='cfg-init-binding-data-broker']</provider>
- </instance>
- </service>
- <service>
- <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:data:init">prefix:vpp-cfg-initializer</type>
- <instance>
- <name>vpp-cfg-initializer</name>
- <provider>/modules/module[type='vpp-cfg-initializer-impl'][name='vpp-cfg-initializer']
- </provider>
- </instance>
- </service>
- <!-- END: Config initialization -->
-
</services>
</data>
</configuration>
diff --git a/v3po/impl/src/main/config/initializer-config.xml b/v3po/impl/src/main/config/initializer-config.xml
new file mode 100644
index 000000000..c5ee10f91
--- /dev/null
+++ b/v3po/impl/src/main/config/initializer-config.xml
@@ -0,0 +1,224 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (c) 2016 Cisco and/or its affiliates.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at:
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+
+<snapshot>
+ <required-capabilities>
+ <capability>urn:opendaylight:params:xml:ns:yang:v3po:impl?module=v3po-impl&amp;revision=2014-12-10</capability>
+ <capability>urn:honeycomb:params:xml:ns:yang:translate:utils?module=translate-utils&amp;revision=2016-04-06</capability>
+ <capability>urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg?module=vpp-jvpp-cfg&amp;revision=2016-04-06</capability>
+ <capability>urn:honeycomb:params:xml:ns:yang:vpp:data:init?module=vpp-cfg-init&amp;revision=2016-04-07</capability>
+ <capability>urn:honeycomb:params:xml:ns:yang:data:api?module=data-api&amp;revision=2016-04-11</capability>
+ <capability>urn:honeycomb:params:xml:ns:yang:data:impl?module=data-impl&amp;revision=2016-04-11</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</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">
+ <!-- Config initialization -->
+ <!-- Empty registry which does not pass data to VPP -->
+ <module>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:utils">prefix:noop-writer-registry</type>
+ <name>noop-writer-registry</name>
+ </module>
+ <!-- Config data tree which does not pass data to translation layer (uses noop-write-registry) -->
+ <module>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:impl">prefix:honeycomb-config-data-tree</type>
+ <name>cfg-init-config-data-tree</name>
+ <!-- Without persistence -->
+ <data-tree>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:data-tree</type>
+ <name>inmemory-config-data-tree</name>
+ </data-tree>
+ <serializer>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-dom-mapping-service</type>
+ <name>runtime-mapping-singleton</name>
+ </serializer>
+ <writer-registry>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-writer-registry</type>
+ <name>noop-writer-registry</name>
+ </writer-registry>
+ <context-binding-broker>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
+ <name>honeycomb-context-binding-data-broker</name>
+ </context-binding-broker>
+ </module>
+ <!-- DOM data broker for config initialization -->
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:v3po:impl">prefix:honeycomb-dom-data-broker</type>
+ <name>cfg-init-dom-data-broker</name>
+ <config-data-tree>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:honeycomb-modifiable-data-tree</type>
+ <name>cfg-init-config-data-tree</name>
+ </config-data-tree>
+ <operational-data-tree>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:honeycomb-readable-data-tree</type>
+ <name>operational-data-tree</name>
+ </operational-data-tree>
+ </module>
+ <!-- Binding data broker for config initialization -->
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-forwarded-data-broker</type>
+ <name>cfg-init-binding-data-broker</name>
+ <binding-forwarded-data-broker xmlns="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+ <dom-async-broker>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
+ <name>cfg-init-dom-data-broker</name>
+ </dom-async-broker>
+ <schema-service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+ <name>yang-schema-service</name>
+ </schema-service>
+ <binding-mapping-service>
+ <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>
+ </binding-mapping-service>
+ </binding-forwarded-data-broker>
+ </module>
+ <!-- Config initializer for VPP subtree-->
+ <module>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:data:init">prefix:vpp-cfg-initializer</type>
+ <name>vpp-cfg-initializer</name>
+ <binding-data-broker>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-async-data-broker</type>
+ <name>cfg-init-binding-data-broker</name>
+ </binding-data-broker>
+ </module>
+ <!-- Config initializer for Interfaces subtree-->
+ <module>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:data:init">prefix:interfaces-cfg-initializer</type>
+ <name>interfaces-cfg-initializer</name>
+ <binding-data-broker>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">prefix:binding-async-data-broker</type>
+ <name>cfg-init-binding-data-broker</name>
+ </binding-data-broker>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:data:init">prefix:persisted-file-initializer</type>
+ <name>persisted-context-initializer</name>
+ <dom-data-broker>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
+ <name>honeycomb-context-data-broker</name>
+ </dom-data-broker>
+ <schema-service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+ <name>yang-schema-service</name>
+ </schema-service>
+ <persist-file-path>etc/opendaylight/honeycomb/context.json</persist-file-path>
+ <restoration-type>merge</restoration-type>
+ <datastore-type>oper</datastore-type>
+ </module>
+ <module>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:data:init">prefix:persisted-file-initializer</type>
+ <name>persisted-config-initializer</name>
+ <dom-data-broker>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">prefix:dom-async-data-broker</type>
+ <name>honeycomb-dom-data-broker</name>
+ </dom-data-broker>
+ <schema-service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+ <name>yang-schema-service</name>
+ </schema-service>
+ <persist-file-path>etc/opendaylight/honeycomb/config.json</persist-file-path>
+ <restoration-type>merge</restoration-type>
+ <datastore-type>config</datastore-type>
+ </module>
+
+ <module>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:data:init">prefix:cfg-initializer-registry</type>
+ <name>initializer-registry</name>
+ <persisted-context-initializer>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:data:init">prefix:cfg-initializer</type>
+ <name>persisted-context-initializer</name>
+ </persisted-context-initializer>
+ <initializers>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:data:init">prefix:cfg-initializer</type>
+ <name>vpp-cfg-initializer</name>
+ </initializers>
+ <initializers>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:data:init">prefix:cfg-initializer</type>
+ <name>interfaces-cfg-initializer</name>
+ </initializers>
+ <persisted-config-initializer>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:data:init">prefix:cfg-initializer</type>
+ <name>persisted-config-initializer</name>
+ </persisted-config-initializer>
+ </module>
+ <!-- END: Config initialization -->
+ </modules>
+
+ <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <!-- Config initialization -->
+ <service>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-writer-registry</type>
+ <instance>
+ <name>noop-writer-registry</name>
+ <provider>/modules/module[type='noop-writer-registry'][name='noop-writer-registry']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:honeycomb-modifiable-data-tree</type>
+ <instance>
+ <name>cfg-init-config-data-tree</name>
+ <provider>/modules/module[type='honeycomb-config-data-tree'][name='cfg-init-config-data-tree']
+ </provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
+ <instance>
+ <name>cfg-init-dom-data-broker</name>
+ <provider>/modules/module[type='honeycomb-dom-data-broker'][name='cfg-init-dom-data-broker']</provider>
+ </instance>
+ </service>
+ <service>
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-async-data-broker</type>
+ <instance>
+ <name>cfg-init-binding-data-broker</name>
+ <provider>/modules/module[type='binding-forwarded-data-broker'][name='cfg-init-binding-data-broker']</provider>
+ </instance>
+ </service>
+
+ <service>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:data:init">prefix:cfg-initializer</type>
+ <instance>
+ <name>vpp-cfg-initializer</name>
+ <provider>/modules/module[type='vpp-cfg-initializer'][name='vpp-cfg-initializer']
+ </provider>
+ </instance>
+ <instance>
+ <name>interfaces-cfg-initializer</name>
+ <provider>/modules/module[type='interfaces-cfg-initializer'][name='interfaces-cfg-initializer']
+ </provider>
+ </instance>
+ <instance>
+ <name>persisted-context-initializer</name>
+ <provider>/modules/module[type='persisted-file-initializer'][name='persisted-context-initializer']
+ </provider>
+ </instance>
+ <instance>
+ <name>persisted-config-initializer</name>
+ <provider>/modules/module[type='persisted-file-initializer'][name='persisted-config-initializer']
+ </provider>
+ </instance>
+ </service>
+ </services>
+ </data>
+ </configuration>
+</snapshot>
diff --git a/v3po/translate-utils/pom.xml b/v3po/translate-utils/pom.xml
index 346757cc2..9cb6590d8 100644
--- a/v3po/translate-utils/pom.xml
+++ b/v3po/translate-utils/pom.xml
@@ -66,6 +66,10 @@
<groupId>org.opendaylight.mdsal</groupId>
<artifactId>mdsal-binding-dom-codec</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-data-codec-gson</artifactId>
+ </dependency>
<!-- Testing Dependencies -->
<dependency>
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/JsonUtils.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/JsonUtils.java
new file mode 100644
index 000000000..be6ffa235
--- /dev/null
+++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/JsonUtils.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.translate.util;
+
+import com.google.common.base.Charsets;
+import com.google.gson.stream.JsonReader;
+import com.google.gson.stream.JsonWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
+import org.opendaylight.yangtools.yang.data.codec.gson.JSONCodecFactory;
+import org.opendaylight.yangtools.yang.data.codec.gson.JSONNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream;
+import org.opendaylight.yangtools.yang.data.codec.gson.JsonWriterFactory;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+public class JsonUtils {
+
+ private JsonUtils() {}
+
+ /**
+ * Serialize normalized node root structure into provided output stream
+ *
+ * @throws IOException if serialized data cannot be written into provided output stream
+ */
+ public static void writeJsonRoot(@Nonnull final NormalizedNode<?, ?> rootData,
+ @Nonnull final SchemaContext schemaContext,
+ @Nonnull final OutputStream outputStream) throws IOException {
+ final JsonWriter
+ jsonWriter = createJsonWriter(outputStream, true);
+ final NormalizedNodeStreamWriter streamWriter = JSONNormalizedNodeStreamWriter
+ .createNestedWriter(JSONCodecFactory.create(schemaContext), SchemaPath.ROOT, null, jsonWriter);
+ final NormalizedNodeWriter normalizedNodeWriter =
+ NormalizedNodeWriter.forStreamWriter(streamWriter, true);
+ jsonWriter.beginObject();
+ writeChildren(normalizedNodeWriter,(ContainerNode) rootData);
+ jsonWriter.endObject();
+ jsonWriter.flush();
+ }
+
+ /**
+ * Read json serialized normalized node root structure and parse them into normalized nodes
+ *
+ * @return artificial normalized node holding all the top level nodes from provided stream as children. In case
+ * the stream is empty, empty artificial normalized node is returned
+ *
+ * @throws IllegalArgumentException if content in the provided input stream is not restore-able
+ */
+ public static ContainerNode readJsonRoot(@Nonnull final SchemaContext schemaContext,
+ @Nonnull final InputStream stream) {
+ final DataContainerNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode> builder =
+ Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(schemaContext.getQName()));
+ final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(builder);
+
+ final JsonParserStream jsonParser = JsonParserStream.create(writer, schemaContext);
+ final JsonReader reader = new JsonReader(new InputStreamReader(stream));
+ jsonParser.parse(reader);
+
+ return builder.build();
+ }
+
+ private static void writeChildren(final NormalizedNodeWriter nnWriter, final ContainerNode data) throws IOException {
+ for(final DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> child : data.getValue()) {
+ nnWriter.write(child);
+ }
+ }
+
+ private static JsonWriter createJsonWriter(final OutputStream entityStream, boolean prettyPrint) {
+ if (prettyPrint) {
+ return JsonWriterFactory.createJsonWriter(new OutputStreamWriter(entityStream, Charsets.UTF_8), 2);
+ } else {
+ return JsonWriterFactory.createJsonWriter(new OutputStreamWriter(entityStream, Charsets.UTF_8));
+ }
+ }
+}
diff --git a/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/JsonUtilsTest.java b/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/JsonUtilsTest.java
new file mode 100644
index 000000000..bd48cb446
--- /dev/null
+++ b/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/util/JsonUtilsTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.translate.util;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.io.ByteStreams;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext;
+
+public class JsonUtilsTest {
+
+ public static final String NAMESPACE = "urn:opendaylight:params:xml:ns:yang:test:persistence";
+
+ private static final QName ROOT_QNAME = QName.create("urn:ietf:params:xml:ns:netconf:base:1.0", "data");
+ private static final QName TOP_CONTAINER_NAME = QName.create(NAMESPACE, "2015-01-05", "top-container");
+ private static final QName TOP_CONTAINER2_NAME = QName.create(NAMESPACE, "2015-01-05", "top-container2");
+ private static final QName STRING_LEAF_QNAME = QName.create(TOP_CONTAINER_NAME, "string");
+
+ private Path tmpPersistFile;
+ private EffectiveSchemaContext effectiveSchemaContext;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ tmpPersistFile = Files.createTempFile("testing-hc-persistence", "json");
+
+ final CrossSourceStatementReactor.BuildAction buildAction = YangInferencePipeline.RFC6020_REACTOR.newBuild();
+ buildAction.addSource(new YangStatementSourceImpl(getClass().getResourceAsStream("/test-persistence.yang")));
+ effectiveSchemaContext = buildAction.buildEffective();
+ }
+
+ @Test
+ public void testPersist() throws Exception {
+
+ NormalizedNode<?, ?> data = getData("testing");
+ JsonUtils.writeJsonRoot(data, effectiveSchemaContext, Files.newOutputStream(tmpPersistFile, StandardOpenOption.CREATE));
+ assertTrue(Files.exists(tmpPersistFile));
+
+ String persisted = new String(Files.readAllBytes(tmpPersistFile));
+ String expected =
+ new String(ByteStreams.toByteArray(getClass().getResourceAsStream("/expected-persisted-output.txt")));
+
+ assertEquals(expected, persisted);
+
+ data = getData("testing2");
+ JsonUtils.writeJsonRoot(data, effectiveSchemaContext, Files.newOutputStream(tmpPersistFile, StandardOpenOption.CREATE));
+ persisted = new String(Files.readAllBytes(tmpPersistFile));
+ assertEquals(expected.replace("testing", "testing2"), persisted);
+
+ // File has to stay even after close
+ assertTrue(Files.exists(tmpPersistFile));
+ }
+
+ @Test
+ public void testRestore() throws Exception {
+ final ContainerNode normalizedNodeOptional = JsonUtils
+ .readJsonRoot(effectiveSchemaContext, getClass().getResourceAsStream("/expected-persisted-output.txt"));
+ assertEquals(getData("testing"), normalizedNodeOptional);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testRestoreInvalidFile() throws Exception {
+ JsonUtils.readJsonRoot(effectiveSchemaContext, getClass().getResourceAsStream("/test-persistence.yang"));
+ }
+
+ private ContainerNode getData(final String stringValue) {
+ return Builders.containerBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(ROOT_QNAME))
+ .withChild(Builders.containerBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TOP_CONTAINER_NAME))
+ .withChild(ImmutableNodes.leafNode(STRING_LEAF_QNAME, stringValue))
+ .build())
+ .withChild(Builders.containerBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TOP_CONTAINER2_NAME))
+ .withChild(ImmutableNodes.leafNode(STRING_LEAF_QNAME, stringValue))
+ .build())
+ .build();
+ }
+} \ No newline at end of file
diff --git a/v3po/translate-utils/src/test/resources/expected-persisted-output.txt b/v3po/translate-utils/src/test/resources/expected-persisted-output.txt
new file mode 100644
index 000000000..f0f5902e2
--- /dev/null
+++ b/v3po/translate-utils/src/test/resources/expected-persisted-output.txt
@@ -0,0 +1,8 @@
+{
+ "test-persistence:top-container": {
+ "string": "testing"
+ },
+ "test-persistence:top-container2": {
+ "string": "testing"
+ }
+} \ No newline at end of file
diff --git a/v3po/data-impl/src/test/resources/test-persistence.yang b/v3po/translate-utils/src/test/resources/test-persistence.yang
index b7dbbb1bc..6dca9f2d5 100644
--- a/v3po/data-impl/src/test/resources/test-persistence.yang
+++ b/v3po/translate-utils/src/test/resources/test-persistence.yang
@@ -13,4 +13,10 @@ module test-persistence {
}
}
+ container top-container2 {
+ leaf string {
+ type string;
+ }
+ }
+
}
diff --git a/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/DataTreeInitializer.java b/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/DataTreeInitializer.java
index 3cb6f14e4..d760401f9 100644
--- a/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/DataTreeInitializer.java
+++ b/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/DataTreeInitializer.java
@@ -43,5 +43,9 @@ public interface DataTreeInitializer extends AutoCloseable {
public InitializeException(final String message, final Throwable cause) {
super(message, cause);
}
+
+ public InitializeException(final String msg) {
+ super(msg);
+ }
}
}
diff --git a/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/InterfacesInitializer.java b/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/InterfacesInitializer.java
index fde2a2893..9ecbe0c13 100644
--- a/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/InterfacesInitializer.java
+++ b/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/InterfacesInitializer.java
@@ -43,6 +43,8 @@ public class InterfacesInitializer extends AbstractDataTreeConverter<InterfacesS
InstanceIdentifier.create(Interfaces.class));
}
+ // TODO move to v3po2vpp
+
@Override
protected Interfaces convert(final InterfacesState operationalData) {
LOG.debug("InterfacesInitializer.convert()");
diff --git a/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/RestoringInitializer.java b/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/RestoringInitializer.java
new file mode 100644
index 000000000..eed22313c
--- /dev/null
+++ b/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/RestoringInitializer.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.honeycomb.v3po.vpp.data.init;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import io.fd.honeycomb.v3po.translate.util.JsonUtils;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407.RestorationType;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+
+public class RestoringInitializer implements DataTreeInitializer {
+
+ private final SchemaService schemaService;
+ private final Path path;
+ private final DOMDataBroker dataTree;
+ private final RestorationType restorationType;
+ private final LogicalDatastoreType datastoreType;
+
+ public RestoringInitializer(@Nonnull final SchemaService schemaService,
+ @Nonnull final Path path,
+ @Nonnull final DOMDataBroker dataTree,
+ @Nonnull final RestorationType restorationType,
+ @Nonnull final LogicalDatastoreType datastoreType) {
+ this.schemaService = schemaService;
+ this.datastoreType = datastoreType;
+ this.path = checkStorage(path);
+ this.dataTree = dataTree;
+ this.restorationType = restorationType;
+ }
+
+ private Path checkStorage(final Path path) {
+ try {
+ if(Files.exists(path)) {
+ checkArgument(!Files.isDirectory(path), "File %s is a directory", path);
+ checkArgument(Files.isReadable(path), "File %s is not readable", path);
+ } else {
+ return checkStorage(Files.createFile(path));
+ }
+ } catch (IOException e) {
+ throw new IllegalArgumentException("Cannot use " + path + " for restoring data", e);
+ }
+
+ return path;
+ }
+
+ @Override
+ public void initialize() throws InitializeException {
+ if(!Files.exists(path)) {
+ return;
+ }
+
+ try {
+ final ContainerNode containerNode = JsonUtils
+ .readJsonRoot(schemaService.getGlobalContext(), Files.newInputStream(path, StandardOpenOption.READ));
+
+ final DOMDataWriteTransaction domDataWriteTransaction = dataTree.newWriteOnlyTransaction();
+ for (DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> dataContainerChild : containerNode
+ .getValue()) {
+ final YangInstanceIdentifier iid = YangInstanceIdentifier.create(dataContainerChild.getIdentifier());
+ switch (restorationType) {
+ case Merge:
+ domDataWriteTransaction.merge(datastoreType, iid, dataContainerChild);
+ break;
+ case Put:
+ domDataWriteTransaction.put(datastoreType, iid, dataContainerChild);
+ break;
+ default:
+ throw new InitializeException(
+ "Unable to initialize data using " + restorationType + " restoration strategy. Unsupported");
+ }
+ }
+
+ // Block here to prevent subsequent initializers processing before context is fully restored
+ domDataWriteTransaction.submit().checkedGet();
+
+ } catch (IOException | TransactionCommitFailedException e) {
+ throw new InitializeException("Unable to restore data from " + path, e);
+ }
+ }
+
+ @Override
+ public void close() {}
+}
diff --git a/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/VppInitializer.java b/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/VppInitializer.java
index 77bb3a563..d7a67870a 100644
--- a/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/VppInitializer.java
+++ b/v3po/vpp-cfg-init/src/main/java/io/fd/honeycomb/v3po/vpp/data/init/VppInitializer.java
@@ -42,6 +42,8 @@ public class VppInitializer extends AbstractDataTreeConverter<VppState, Vpp> {
super(bindingDataBroker, InstanceIdentifier.create(VppState.class), InstanceIdentifier.create(Vpp.class));
}
+ // TODO move to v3po2vpp
+
@Override
protected Vpp convert(final VppState operationalData) {
LOG.debug("VppInitializer.convert()");
diff --git a/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/ConfigurationInitializerRegistryModule.java b/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/ConfigurationInitializerRegistryModule.java
new file mode 100644
index 000000000..d80b9ed30
--- /dev/null
+++ b/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/ConfigurationInitializerRegistryModule.java
@@ -0,0 +1,55 @@
+package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407;
+
+import io.fd.honeycomb.v3po.vpp.data.init.InitializerRegistry;
+import io.fd.honeycomb.v3po.vpp.data.init.InitializerRegistryImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+* Initializer registry, delegating initialization to a list of initializers
+*/
+public class ConfigurationInitializerRegistryModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407.AbstractConfigurationInitializerRegistryModule {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ConfigurationInitializerRegistryModule.class);
+
+ public ConfigurationInitializerRegistryModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public ConfigurationInitializerRegistryModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407.ConfigurationInitializerRegistryModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void customValidation() {
+ // add custom validation form module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ LOG.info("VppConfigurationInitializerModule.createInstance(): initialization started");
+
+ final InitializerRegistry initializer = new InitializerRegistryImpl(getInitializersDependency());
+
+ try {
+ // Initialize contexts first so that other initializers can find any relevant mapping before initializing
+ // configuration to what is already in VPP
+ getPersistedContextInitializerDependency().initialize();
+ LOG.info("Persisted context restored successfully");
+ // Initialize all registered initializers
+ initializer.initialize();
+ LOG.info("VPP configuration initialized successfully from VPP");
+ // Initialize stored configuration on top
+ // FIXME uncomment and test
+// getPersistedConfigInitializerDependency().initialize();
+ LOG.info("Persisted configuration restored successfully");
+ } catch (Exception e) {
+ LOG.warn("Failed to initialize config", e);
+ }
+
+ LOG.info("Honeycomb initialized");
+
+ return initializer;
+ }
+
+}
diff --git a/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/ConfigurationInitializerRegistryModuleFactory.java b/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/ConfigurationInitializerRegistryModuleFactory.java
new file mode 100644
index 000000000..f07be953e
--- /dev/null
+++ b/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/ConfigurationInitializerRegistryModuleFactory.java
@@ -0,0 +1,13 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: vpp-cfg-init yang module local name: cfg-initializer-registry
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed May 18 14:43:49 CEST 2016
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407;
+public class ConfigurationInitializerRegistryModuleFactory extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407.AbstractConfigurationInitializerRegistryModuleFactory {
+
+}
diff --git a/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/InterfacesConfigurationInitializerModule.java b/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/InterfacesConfigurationInitializerModule.java
new file mode 100644
index 000000000..51a7c482a
--- /dev/null
+++ b/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/InterfacesConfigurationInitializerModule.java
@@ -0,0 +1,24 @@
+package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407;
+
+import io.fd.honeycomb.v3po.vpp.data.init.InterfacesInitializer;
+
+public class InterfacesConfigurationInitializerModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407.AbstractInterfacesConfigurationInitializerModule {
+ public InterfacesConfigurationInitializerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public InterfacesConfigurationInitializerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407.InterfacesConfigurationInitializerModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void customValidation() {
+ // add custom validation form module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ return new InterfacesInitializer(getBindingDataBrokerDependency());
+ }
+
+}
diff --git a/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/InterfacesConfigurationInitializerModuleFactory.java b/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/InterfacesConfigurationInitializerModuleFactory.java
new file mode 100644
index 000000000..b74947917
--- /dev/null
+++ b/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/InterfacesConfigurationInitializerModuleFactory.java
@@ -0,0 +1,13 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: vpp-cfg-init yang module local name: interfaces-cfg-initializer
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed May 18 14:43:49 CEST 2016
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407;
+public class InterfacesConfigurationInitializerModuleFactory extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407.AbstractInterfacesConfigurationInitializerModuleFactory {
+
+}
diff --git a/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/PersistedFileInitializerModule.java b/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/PersistedFileInitializerModule.java
new file mode 100644
index 000000000..188d1641c
--- /dev/null
+++ b/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/PersistedFileInitializerModule.java
@@ -0,0 +1,38 @@
+package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407;
+
+import io.fd.honeycomb.v3po.vpp.data.init.RestoringInitializer;
+import java.nio.file.InvalidPathException;
+import java.nio.file.Paths;
+import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.data.api.rev160411.DatatreeType;
+
+/**
+* Initializer restoring data from a persisted file
+*/
+public class PersistedFileInitializerModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407.AbstractPersistedFileInitializerModule {
+ public PersistedFileInitializerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public PersistedFileInitializerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407.PersistedFileInitializerModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void customValidation() {
+ try {
+ Paths.get(getPersistFilePath());
+ } catch (InvalidPathException e) {
+ throw new JmxAttributeValidationException("Invalid persist path", e, persistFilePathJmxAttribute);
+ }
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ return new RestoringInitializer(getSchemaServiceDependency(), Paths.get(getPersistFilePath()),
+ getDomDataBrokerDependency(), getRestorationType(),
+ getDatastoreType() == DatatreeType.Config ? LogicalDatastoreType.CONFIGURATION : LogicalDatastoreType.OPERATIONAL);
+ }
+
+}
diff --git a/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/PersistedFileInitializerModuleFactory.java b/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/PersistedFileInitializerModuleFactory.java
new file mode 100644
index 000000000..1d7a3c9c6
--- /dev/null
+++ b/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/PersistedFileInitializerModuleFactory.java
@@ -0,0 +1,13 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: vpp-cfg-init yang module local name: persisted-file-initializer
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Wed May 18 13:48:52 CEST 2016
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407;
+public class PersistedFileInitializerModuleFactory extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407.AbstractPersistedFileInitializerModuleFactory {
+
+}
diff --git a/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/VppConfigurationInitializerModule.java b/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/VppConfigurationInitializerModule.java
index ae83cb3fe..cc4f183fc 100644
--- a/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/VppConfigurationInitializerModule.java
+++ b/v3po/vpp-cfg-init/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/data/init/rev160407/VppConfigurationInitializerModule.java
@@ -1,12 +1,6 @@
package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.data.init.rev160407;
-import io.fd.honeycomb.v3po.vpp.data.init.DataTreeInitializer;
-import io.fd.honeycomb.v3po.vpp.data.init.InitializerRegistry;
-import io.fd.honeycomb.v3po.vpp.data.init.InitializerRegistryImpl;
-import io.fd.honeycomb.v3po.vpp.data.init.InterfacesInitializer;
import io.fd.honeycomb.v3po.vpp.data.init.VppInitializer;
-import java.util.Arrays;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -34,24 +28,7 @@ public class VppConfigurationInitializerModule extends
@Override
public java.lang.AutoCloseable createInstance() {
- LOG.info("VppConfigurationInitializerModule.createInstance(): initialization started");
- final DataBroker bindingDataBroker = getBindingDataBrokerDependency();
-
- final VppInitializer vppInitializer = new VppInitializer(bindingDataBroker);
- final InterfacesInitializer interfacesInitializer = new InterfacesInitializer(bindingDataBroker);
-
- // TODO make configurable
- final InitializerRegistry initializer =
- new InitializerRegistryImpl(Arrays.<DataTreeInitializer>asList(vppInitializer, interfacesInitializer));
-
- try {
- initializer.initialize();
- } catch (Exception e) {
- LOG.warn("Failed to initialize config", e);
- }
- LOG.info("VppConfigurationInitializerModule.createInstance(): initialization completed");
-
- return initializer;
+ return new VppInitializer(getBindingDataBrokerDependency());
}
}
diff --git a/v3po/vpp-cfg-init/src/main/yang/vpp-cfg-init.yang b/v3po/vpp-cfg-init/src/main/yang/vpp-cfg-init.yang
index e4ce95aea..024c930b7 100644
--- a/v3po/vpp-cfg-init/src/main/yang/vpp-cfg-init.yang
+++ b/v3po/vpp-cfg-init/src/main/yang/vpp-cfg-init.yang
@@ -5,6 +5,7 @@ module vpp-cfg-init {
import config { prefix config; revision-date 2013-04-05; }
import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
+ import opendaylight-md-sal-dom {prefix dom;}
import translate-api { prefix tapi; revision-date 2016-04-06; }
import data-api { prefix dapi; revision-date 2016-04-11; }
@@ -16,20 +17,43 @@ module vpp-cfg-init {
"Initial revision";
}
- identity vpp-cfg-initializer {
+ identity cfg-initializer {
base "config:service-type";
- config:java-class io.fd.honeycomb.v3po.vpp.data.init.InitializerRegistry;
+ config:java-class io.fd.honeycomb.v3po.vpp.data.init.DataTreeInitializer;
}
- identity vpp-cfg-initializer-impl {
+ // TODO move to v3po2vpp
+ identity vpp-cfg-initializer {
base config:module-type;
- config:provided-service vpp-cfg-initializer;
+ config:provided-service cfg-initializer;
config:java-name-prefix VppConfigurationInitializer;
}
augment "/config:modules/config:module/config:configuration" {
- case vpp-cfg-initializer-impl {
- when "/config:modules/config:module/config:type = 'vpp-cfg-initializer-impl'";
+ case vpp-cfg-initializer {
+ when "/config:modules/config:module/config:type = 'vpp-cfg-initializer'";
+
+ container binding-data-broker {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity md-sal-binding:binding-async-data-broker;
+ }
+ }
+ }
+ }
+ }
+
+ // TODO move to v3po2vpp
+ identity interfaces-cfg-initializer {
+ base config:module-type;
+ config:provided-service cfg-initializer;
+ config:java-name-prefix InterfacesConfigurationInitializer;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case interfaces-cfg-initializer {
+ when "/config:modules/config:module/config:type = 'interfaces-cfg-initializer'";
container binding-data-broker {
uses config:service-ref {
@@ -42,4 +66,95 @@ module vpp-cfg-init {
}
}
+ identity cfg-initializer-registry {
+ base config:module-type;
+ config:provided-service cfg-initializer;
+ config:java-name-prefix ConfigurationInitializerRegistry;
+ description "Initializer registry, delegating initialization to a list of initializers";
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case cfg-initializer-registry {
+ when "/config:modules/config:module/config:type = 'cfg-initializer-registry'";
+
+ list initializers {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity cfg-initializer;
+ }
+ }
+ }
+
+ container persisted-context-initializer {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity cfg-initializer;
+ }
+ }
+ }
+
+ container persisted-config-initializer {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity cfg-initializer;
+ }
+ }
+ }
+ }
+ }
+
+ identity persisted-file-initializer {
+ base config:module-type;
+ config:provided-service cfg-initializer;
+ description "Initializer restoring data from a persisted file";
+ }
+
+ typedef restoration-type {
+ type enumeration {
+ enum merge;
+ enum put;
+ }
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case persisted-file-initializer {
+ when "/config:modules/config:module/config:type = 'persisted-file-initializer'";
+
+ container dom-data-broker {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity dom:dom-async-data-broker;
+ }
+ }
+ }
+
+ container schema-service {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity dom:schema-service;
+ }
+ }
+ }
+
+ leaf persist-file-path {
+ type string;
+ }
+
+ leaf restoration-type {
+ type restoration-type;
+ default merge;
+ }
+
+
+ leaf datastore-type {
+ type dapi:datatree-type;
+ }
+ }
+ }
+
} \ No newline at end of file