summaryrefslogtreecommitdiffstats
path: root/v3po/data-impl
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 /v3po/data-impl
parentd421438681e97ef7213a5cb925c49755cd9fb4b6 (diff)
HONEYCOMB-61: Restore configuration and context from persisted files
Change-Id: I6edce127f8895f5d65998b4be71a0a111ca2e8bb Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
Diffstat (limited to 'v3po/data-impl')
-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/data-impl/src/test/resources/test-persistence.yang16
9 files changed, 19 insertions, 147 deletions
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/data-impl/src/test/resources/test-persistence.yang b/v3po/data-impl/src/test/resources/test-persistence.yang
deleted file mode 100644
index b7dbbb1bc..000000000
--- a/v3po/data-impl/src/test/resources/test-persistence.yang
+++ /dev/null
@@ -1,16 +0,0 @@
-module test-persistence {
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:test:persistence";
- prefix "tp";
-
- revision "2015-01-05" {
- description "Initial revision";
- }
-
- container top-container {
- leaf string {
- type string;
- }
- }
-
-}