summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaros Marsalek <mmarsale@cisco.com>2016-05-17 09:10:39 +0200
committerMaros Marsalek <mmarsale@cisco.com>2016-05-23 09:24:12 +0000
commitd54ea758da8dcf71d52727c4f01f87090c50bf2e (patch)
treebf86e49ad4899b50c97654ae144d4b2e8902d1b8
parent9e59a344c5a5b81fb7b7292184e849ad0fc9507c (diff)
HONEYCOMB-61: Add BA broker for context data tree
With broker, context data can be accessed in a transactional manner, same as config data + Renamed data-api concepts to not include DataTree + Renamed context related concepts to better distinguish between them + Now passing full ReadContext to read customizers + Naming context is backed by context data broker Change-Id: I0b2876dd74a31a9ced7d9b5145672868e12f8b82 Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
-rw-r--r--v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/DataModification.java70
-rw-r--r--v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/ModifiableDataManager.java (renamed from v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/DataTreeSnapshot.java)11
-rw-r--r--v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/ModifiableDataTree.java44
-rw-r--r--v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/ReadableDataManager.java (renamed from v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/ReadableDataTree.java)3
-rw-r--r--v3po/data-api/src/main/yang/data-api.yang4
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ConfigDataTree.java173
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/DataBroker.java134
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/DataTreeUtils.java1
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegator.java174
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeManager.java122
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/PersistingDataTreeAdapter.java4
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransaction.java68
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegator.java (renamed from v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/OperationalDataTree.java)73
-rw-r--r--v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/WriteTransaction.java103
-rw-r--r--v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/ConfigDataTreeModule.java37
-rw-r--r--v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/OperationalDataTreeModule.java14
-rw-r--r--v3po/data-impl/src/main/yang/data-impl.yang17
-rw-r--r--v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/DataBrokerTest.java20
-rw-r--r--v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java (renamed from v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ConfigDataTreeTest.java)77
-rw-r--r--v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransactionTest.java10
-rw-r--r--v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegatorTest.java (renamed from v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/OperationalDataTreeTest.java)14
-rw-r--r--v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/WriteTransactionTest.java30
-rw-r--r--v3po/impl/src/main/config/context-datatree-config.xml49
-rw-r--r--v3po/impl/src/main/config/default-config.xml12
-rw-r--r--v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/ContextDataBrokerModule.java26
-rw-r--r--v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/ContextDataBrokerModuleFactory.java13
-rw-r--r--v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/DataBrokerModule.java72
-rw-r--r--v3po/impl/src/main/yang/v3po-impl.yang22
-rw-r--r--v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/MappingContext.java66
-rw-r--r--v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/ModificationCache.java (renamed from v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/Context.java)4
-rw-r--r--v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/ModificationContext.java44
-rw-r--r--v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ReadContext.java17
-rw-r--r--v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriteContext.java22
-rw-r--r--v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeChildReader.java4
-rw-r--r--v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeListReader.java4
-rw-r--r--v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeRootReader.java2
-rw-r--r--v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/AbstractCompositeWriter.java6
-rw-r--r--v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ListReaderCustomizer.java4
-rw-r--r--v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/RootReaderCustomizer.java5
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/NoopReaderCustomizer.java4
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionMappingContext.java75
-rw-r--r--v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionWriteContext.java44
-rw-r--r--v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/impl/write/util/TransactionWriteContextTest.java18
-rw-r--r--v3po/v3po2vpp/src/main/config/default-config.xml8
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java18
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java29
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java8
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java9
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizer.java17
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizer.java20
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VlanTagRewriteCustomizer.java11
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java12
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java9
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java8
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java21
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java6
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java10
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizer.java12
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java12
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java12
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VlanTagRewriteCustomizer.java6
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java8
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java8
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizer.java21
-rw-r--r--v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java4
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/ContextTestUtils.java40
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceTypeTestUtils.java12
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizerTest.java20
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizerTest.java28
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizerTest.java37
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VlanTagRewriteCustomizerTest.java10
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizerTest.java31
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java26
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2CustomizerTest.java32
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizerTest.java30
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VlanTagRewriteCustomizerTest.java12
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizerTest.java15
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/RootReaderCustomizerTest.java14
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java32
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppTest.java40
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java4
-rw-r--r--v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java77
-rw-r--r--v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java10
-rw-r--r--v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/DataTreeNamingContext.java193
-rw-r--r--v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/NamingContext.java89
-rw-r--r--v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModule.java7
-rw-r--r--v3po/vpp-translate-utils/src/main/yang/vpp-util.yang9
87 files changed, 1741 insertions, 1012 deletions
diff --git a/v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/DataModification.java b/v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/DataModification.java
new file mode 100644
index 000000000..d05c55716
--- /dev/null
+++ b/v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/DataModification.java
@@ -0,0 +1,70 @@
+/*
+ * 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.data;
+
+import com.google.common.annotations.Beta;
+import io.fd.honeycomb.v3po.translate.TranslationException;
+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.DataValidationFailedException;
+
+/**
+ * Modification of a {@link ModifiableDataManager}.
+ */
+@Beta
+public interface DataModification extends ReadableDataManager {
+
+ /**
+ * Delete the node at specified path.
+ *
+ * @param path Node path
+ */
+ void delete(YangInstanceIdentifier path);
+
+ /**
+ * Merge the specified data with the currently-present data
+ * at specified path.
+ *
+ * @param path Node path
+ * @param data Data to be merged
+ */
+ void merge(YangInstanceIdentifier path, NormalizedNode<?, ?> data);
+
+ /**
+ * Replace the data at specified path with supplied data.
+ *
+ * @param path Node path
+ * @param data New node data
+ */
+ void write(YangInstanceIdentifier path, NormalizedNode<?, ?> data);
+
+ /**
+ * Alters data tree using this modification.
+ *
+ * @throws DataValidationFailedException if modification data is not valid
+ * @throws TranslationException if failed while updating data tree state
+ */
+ void commit() throws DataValidationFailedException, TranslationException;
+
+ /**
+ * Validate and prepare modification before commit. Besides commit, no further operation is expected after validate
+ * and the behaviour is undefined.
+ *
+ * @throws DataValidationFailedException if modification data is not valid
+ */
+ void validate() throws DataValidationFailedException;
+}
diff --git a/v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/DataTreeSnapshot.java b/v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/ModifiableDataManager.java
index cae459299..11cd513ea 100644
--- a/v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/DataTreeSnapshot.java
+++ b/v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/ModifiableDataManager.java
@@ -17,18 +17,17 @@
package io.fd.honeycomb.v3po.data;
import com.google.common.annotations.Beta;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
/**
- * Read-only snapshot of a {@link ReadableDataTree}.
+ * Facade over data tree that allows tree modification.
*/
@Beta
-public interface DataTreeSnapshot extends ReadableDataTree {
+public interface ModifiableDataManager extends ReadableDataManager {
/**
- * Creates a new data tree modification.
+ * Creates read-only snapshot of a ModifiableDataTree.
*
- * @return A new data tree modification
+ * @return modification
*/
- DataTreeModification newModification();
+ DataModification newModification();
}
diff --git a/v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/ModifiableDataTree.java b/v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/ModifiableDataTree.java
deleted file mode 100644
index 8b21ddf24..000000000
--- a/v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/ModifiableDataTree.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * 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.data;
-
-import com.google.common.annotations.Beta;
-import io.fd.honeycomb.v3po.translate.TranslationException;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-
-/**
- * Facade over data tree that allows tree modification.
- */
-@Beta
-public interface ModifiableDataTree {
- /**
- * Alters data tree using supplied modification.
- *
- * @param modification data tree modification
- * @throws DataValidationFailedException if modification data is not valid
- * @throws TranslationException if failed while updating data tree state
- */
- void modify(final DataTreeModification modification) throws DataValidationFailedException, TranslationException;
-
- /**
- * Creates read-only snapshot of a ModifiableDataTree.
- *
- * @return Data tree snapshot.
- */
- DataTreeSnapshot takeSnapshot();
-}
diff --git a/v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/ReadableDataTree.java b/v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/ReadableDataManager.java
index 1cb8f806d..0e98c0903 100644
--- a/v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/ReadableDataTree.java
+++ b/v3po/data-api/src/main/java/io/fd/honeycomb/v3po/data/ReadableDataManager.java
@@ -28,7 +28,8 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
* Facade over data tree that allows reading tree nodes.
*/
@Beta
-public interface ReadableDataTree {
+public interface ReadableDataManager {
+
/**
* Reads a particular node from the data tree.
*
diff --git a/v3po/data-api/src/main/yang/data-api.yang b/v3po/data-api/src/main/yang/data-api.yang
index 92def4bc4..11d963e4b 100644
--- a/v3po/data-api/src/main/yang/data-api.yang
+++ b/v3po/data-api/src/main/yang/data-api.yang
@@ -21,12 +21,12 @@ module data-api {
identity honeycomb-readable-data-tree {
base "config:service-type";
- config:java-class io.fd.honeycomb.v3po.data.ReadableDataTree;
+ config:java-class io.fd.honeycomb.v3po.data.ReadableDataManager;
}
identity honeycomb-modifiable-data-tree {
base "config:service-type";
- config:java-class io.fd.honeycomb.v3po.data.ModifiableDataTree;
+ config:java-class io.fd.honeycomb.v3po.data.ModifiableDataManager;
}
} \ No newline at end of file
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ConfigDataTree.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ConfigDataTree.java
deleted file mode 100644
index 1e118ff2a..000000000
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ConfigDataTree.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * 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.data.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static io.fd.honeycomb.v3po.data.impl.DataTreeUtils.childrenFromNormalized;
-
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import io.fd.honeycomb.v3po.data.DataTreeSnapshot;
-import io.fd.honeycomb.v3po.data.ModifiableDataTree;
-import io.fd.honeycomb.v3po.data.ReadableDataTree;
-import io.fd.honeycomb.v3po.translate.TranslationException;
-import io.fd.honeycomb.v3po.translate.util.write.TransactionWriteContext;
-import io.fd.honeycomb.v3po.translate.write.WriteContext;
-import io.fd.honeycomb.v3po.translate.write.WriterRegistry;
-import java.util.Collections;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
-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.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * DataTree implementation for configuration data.
- */
-public final class ConfigDataTree implements ModifiableDataTree {
-
- private static final Logger LOG = LoggerFactory.getLogger(ConfigDataTree.class);
-
- private final BindingNormalizedNodeSerializer serializer;
- private final DataTree dataTree;
- private final WriterRegistry writerRegistry;
- public static final ReadableDataTree EMPTY_OPERATIONAL = new ReadableDataTree() {
- @Override
- public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(
- @Nonnull final YangInstanceIdentifier path) {
- return Futures.immediateCheckedFuture(Optional.<NormalizedNode<?, ?>>absent());
- }
- };
-
- /**
- * Creates configuration data tree instance.
- *
- * @param serializer service for serialization between Java Binding Data representation and NormalizedNode
- * representation.
- * @param dataTree data tree for configuration data representation
- * @param writerRegistry service for translation between Java Binding Data and data provider, capable of performing
- * bulk updates.
- */
- public ConfigDataTree(@Nonnull final BindingNormalizedNodeSerializer serializer,
- @Nonnull final DataTree dataTree, @Nonnull final WriterRegistry writerRegistry) {
- this.serializer = checkNotNull(serializer, "serializer should not be null");
- this.dataTree = checkNotNull(dataTree, "dataTree should not be null");
- this.writerRegistry = checkNotNull(writerRegistry, "writerRegistry should not be null");
- }
-
- @Override
- public DataTreeSnapshot takeSnapshot() {
- return new ConfigSnapshot(dataTree.takeSnapshot());
- }
-
- @Override
- public void modify(final DataTreeModification modification)
- throws DataValidationFailedException, TranslationException {
- LOG.debug("ConfigDataTree.modify");
-
- dataTree.validate(modification);
-
- final DataTreeCandidate candidate = dataTree.prepare(modification);
-
- final DataTreeCandidateNode rootNode = candidate.getRootNode();
- final YangInstanceIdentifier rootPath = candidate.getRootPath();
- final Optional<NormalizedNode<?, ?>> normalizedDataBefore = rootNode.getDataBefore();
- final Optional<NormalizedNode<?, ?>> normalizedDataAfter = rootNode.getDataAfter();
- LOG.debug("ConfigDataTree.modify() rootPath={}, rootNode={}, dataBefore={}, dataAfter={}",
- rootPath, rootNode, normalizedDataBefore, normalizedDataAfter);
-
- final Map<InstanceIdentifier<?>, DataObject> nodesBefore = extractNetconfData(normalizedDataBefore);
- LOG.debug("ConfigDataTree.modify() extracted nodesBefore={}", nodesBefore.keySet());
-
- final Map<InstanceIdentifier<?>, DataObject> nodesAfter = extractNetconfData(normalizedDataAfter);
- LOG.debug("ConfigDataTree.modify() extracted nodesAfter={}", nodesAfter.keySet());
-
- final DOMDataReadOnlyTransaction beforeTx = new ReadOnlyTransaction(EMPTY_OPERATIONAL, takeSnapshot());
- final ConfigSnapshot modificationSnapshot = new ConfigSnapshot(modification);
- final DOMDataReadOnlyTransaction afterTx = new ReadOnlyTransaction(EMPTY_OPERATIONAL, modificationSnapshot);
- try (final WriteContext ctx = new TransactionWriteContext(serializer, beforeTx, afterTx)) {
- writerRegistry.update(nodesBefore, nodesAfter, ctx);
- } catch (io.fd.honeycomb.v3po.translate.write.WriterRegistry.BulkUpdateException e) {
- LOG.warn("Failed to apply all changes", e);
- LOG.info("Trying to revert successful changes for current transaction");
-
- try {
- e.revertChanges();
- LOG.info("Changes successfully reverted");
- } catch (io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter.RevertFailedException revertFailedException) {
- // fail with failed revert
- LOG.error("Failed to revert successful changes", revertFailedException);
- throw revertFailedException;
- }
-
- throw e; // fail with success revert
- } catch (TranslationException e) {
- LOG.error("Error while processing data change (before={}, after={})", nodesBefore, nodesAfter, e);
- throw e;
- }
-
- dataTree.commit(candidate);
- }
-
- private Map<InstanceIdentifier<?>, DataObject> extractNetconfData(
- final Optional<NormalizedNode<?, ?>> parentOptional) {
- if (parentOptional.isPresent()) {
- final DataContainerNode parent = (DataContainerNode) parentOptional.get();
- return childrenFromNormalized(parent, serializer);
- }
- return Collections.emptyMap();
- }
-
- private final static class ConfigSnapshot implements DataTreeSnapshot {
- private final org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot snapshot;
-
- ConfigSnapshot(@Nonnull final org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot snapshot) {
- this.snapshot = snapshot;
- }
-
- @Override
- public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(
- @Nonnull final YangInstanceIdentifier path) {
- final Optional<NormalizedNode<?, ?>> node = snapshot.readNode(path);
- if (LOG.isTraceEnabled() && node.isPresent()) {
- LOG.trace("ConfigSnapshot.read: {}", node.get());
- }
- return Futures.immediateCheckedFuture(node);
- }
-
- @Override
- public DataTreeModification newModification() {
- return snapshot.newModification();
- }
- }
-}
-
-
-
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/DataBroker.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/DataBroker.java
index a0b585143..c418ed332 100644
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/DataBroker.java
+++ b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/DataBroker.java
@@ -16,10 +16,13 @@
package io.fd.honeycomb.v3po.data.impl;
-import com.google.common.base.Preconditions;
-import io.fd.honeycomb.v3po.data.DataTreeSnapshot;
-import io.fd.honeycomb.v3po.data.ModifiableDataTree;
-import io.fd.honeycomb.v3po.data.ReadableDataTree;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.honeycomb.v3po.data.DataModification;
+import io.fd.honeycomb.v3po.data.ModifiableDataManager;
+import io.fd.honeycomb.v3po.data.ReadableDataManager;
+import java.io.Closeable;
+import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import javax.annotation.Nonnull;
@@ -42,45 +45,36 @@ import org.slf4j.LoggerFactory;
* Data Broker which provides data transaction functionality for YANG capable data provider using {@link NormalizedNode}
* data format.
*/
-public class DataBroker implements DOMDataBroker {
+public class DataBroker implements DOMDataBroker, Closeable {
private static final Logger LOG = LoggerFactory.getLogger(DataBroker.class);
- private final ReadableDataTree operationalDataTree;
- private final ModifiableDataTree configDataTree;
+ private final TransactionFactory transactionFactory;
/**
* Creates DataBroker instance.
*
- * @param operationalDataTree operational data
- * @param configDataTree configuration data
+ * @param transactionFactory transaction producing factory
*/
- public DataBroker(@Nonnull final ReadableDataTree operationalDataTree,
- @Nonnull final ModifiableDataTree configDataTree) {
- this.operationalDataTree =
- Preconditions.checkNotNull(operationalDataTree, "operationalDataTree should not be null");
- this.configDataTree = Preconditions.checkNotNull(configDataTree, "configDataTree should not be null");
- LOG.trace("DataBroker({}).init() operationalDataTree={}, configDataTree={}", this, operationalDataTree, configDataTree);
+ public DataBroker(final TransactionFactory transactionFactory) {
+ this.transactionFactory = transactionFactory;
}
@Override
public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
LOG.trace("DataBroker({}).newReadOnlyTransaction()", this);
- return new ReadOnlyTransaction(operationalDataTree, configDataTree.takeSnapshot());
+ return transactionFactory.newReadOnlyTransaction();
}
@Override
public DOMDataReadWriteTransaction newReadWriteTransaction() {
LOG.trace("DataBroker({}).newReadWriteTransaction()", this);
- final DataTreeSnapshot configSnapshot = configDataTree.takeSnapshot();
- final DOMDataReadOnlyTransaction readOnlyTx = new ReadOnlyTransaction(operationalDataTree, configSnapshot);
- final DOMDataWriteTransaction writeOnlyTx = new WriteTransaction(configDataTree, configSnapshot);
- return new ReadWriteTransaction(readOnlyTx, writeOnlyTx);
+ return transactionFactory.newReadWriteTransaction();
}
@Override
public DOMDataWriteTransaction newWriteOnlyTransaction() {
LOG.trace("DataBroker({}).newWriteOnlyTransaction()", this);
- return new WriteTransaction(configDataTree);
+ return transactionFactory.newWriteOnlyTransaction();
}
@Override
@@ -101,6 +95,104 @@ public class DataBroker implements DOMDataBroker {
public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
return Collections.emptyMap();
}
+
+ /**
+ * Create DataBroker for a modifiable config DT, but only readable Operational
+ */
+ @Nonnull
+ public static DataBroker create(@Nonnull final ModifiableDataManager configDataTree,
+ @Nonnull final ReadableDataManager operationalDataTree) {
+ checkNotNull(operationalDataTree, "operationalDataTree should not be null");
+ checkNotNull(configDataTree, "configDataTree should not be null");
+ return new DataBroker(new MainPipelineTxFactory(configDataTree, operationalDataTree));
+ }
+
+ /**
+ * Create DataBroker for modifiable operational DT, but no support for config
+ */
+ @Nonnull
+ public static DataBroker create(@Nonnull final ModifiableDataManager operationalDataTree) {
+ checkNotNull(operationalDataTree, "operationalDataTree should not be null");
+ return new DataBroker(new ContextPipelineTxFactory(operationalDataTree));
+ }
+
+ @Override
+ public void close() throws IOException {
+ // NOOP
+ }
+
+ /**
+ * Transaction provider factory to be used by {@link DataBroker}
+ */
+ public interface TransactionFactory {
+
+ DOMDataReadOnlyTransaction newReadOnlyTransaction();
+
+ DOMDataReadWriteTransaction newReadWriteTransaction();
+
+ DOMDataWriteTransaction newWriteOnlyTransaction();
+ }
+
+ /**
+ * Transaction factory specific for Honeycomb's main pipeline (config: read+write, operational: read-only)
+ */
+ private static class MainPipelineTxFactory implements TransactionFactory {
+ private final ReadableDataManager operationalDataTree;
+ private final ModifiableDataManager configDataTree;
+
+ MainPipelineTxFactory(@Nonnull final ModifiableDataManager configDataTree,
+ @Nonnull final ReadableDataManager operationalDataTree) {
+ this.operationalDataTree = operationalDataTree;
+ this.configDataTree = configDataTree;
+ }
+
+ @Override
+ public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
+ return ReadOnlyTransaction.create(configDataTree.newModification(), operationalDataTree);
+ }
+
+ @Override
+ public DOMDataReadWriteTransaction newReadWriteTransaction() {
+ final DataModification configModification = configDataTree.newModification();
+ return new ReadWriteTransaction(
+ ReadOnlyTransaction.create(configModification, operationalDataTree),
+ WriteTransaction.createConfigOnly(configModification));
+ }
+
+ @Override
+ public DOMDataWriteTransaction newWriteOnlyTransaction() {
+ return WriteTransaction.createConfigOnly(configDataTree.newModification());
+ }
+ }
+
+ /**
+ * Transaction factory specific for Honeycomb's context pipeline (config: none, operational: read+write)
+ */
+ private static class ContextPipelineTxFactory implements TransactionFactory {
+ private final ModifiableDataManager operationalDataTree;
+
+ ContextPipelineTxFactory(@Nonnull final ModifiableDataManager operationalDataTree) {
+ this.operationalDataTree = operationalDataTree;
+ }
+
+ @Override
+ public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
+ return ReadOnlyTransaction.createOperationalOnly(operationalDataTree);
+ }
+
+ @Override
+ public DOMDataReadWriteTransaction newReadWriteTransaction() {
+ final DataModification dataModification = operationalDataTree.newModification();
+ return new ReadWriteTransaction(
+ ReadOnlyTransaction.createOperationalOnly(dataModification),
+ WriteTransaction.createOperationalOnly(dataModification));
+ }
+
+ @Override
+ public DOMDataWriteTransaction newWriteOnlyTransaction() {
+ return WriteTransaction.createOperationalOnly(operationalDataTree.newModification());
+ }
+ }
}
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/DataTreeUtils.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/DataTreeUtils.java
index de83a198b..5833459ea 100644
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/DataTreeUtils.java
+++ b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/DataTreeUtils.java
@@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory;
* Utility class for various operations on DataTree.
*/
final class DataTreeUtils {
+
private static final Logger LOG = LoggerFactory.getLogger(DataTreeUtils.class);
private DataTreeUtils() {
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegator.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegator.java
new file mode 100644
index 000000000..2b9010747
--- /dev/null
+++ b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegator.java
@@ -0,0 +1,174 @@
+/*
+ * 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.data.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.util.concurrent.Futures.immediateCheckedFuture;
+import static io.fd.honeycomb.v3po.data.impl.DataTreeUtils.childrenFromNormalized;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import io.fd.honeycomb.v3po.data.DataModification;
+import io.fd.honeycomb.v3po.data.ReadableDataManager;
+import io.fd.honeycomb.v3po.translate.TranslationException;
+import io.fd.honeycomb.v3po.translate.util.write.TransactionMappingContext;
+import io.fd.honeycomb.v3po.translate.util.write.TransactionWriteContext;
+import io.fd.honeycomb.v3po.translate.write.WriteContext;
+import io.fd.honeycomb.v3po.translate.write.WriterRegistry;
+import java.util.Collections;
+import java.util.Map;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
+import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+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.DataTreeCandidateNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Extension of {@link ModifiableDataTreeManager} that propagates data changes to underlying writer layer before they
+ * are fully committed in the backing data tree. Data changes are propagated in BA format.
+ */
+public final class ModifiableDataTreeDelegator extends ModifiableDataTreeManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ModifiableDataTreeDelegator.class);
+ private static final ReadableDataManager EMPTY_OPERATIONAL = p -> immediateCheckedFuture(Optional.absent());
+
+ // TODO what to use instead of deprecated BindingNormalizedNodeSerializer ?
+ private final BindingNormalizedNodeSerializer serializer;
+ private final WriterRegistry writerRegistry;
+ private final org.opendaylight.controller.md.sal.binding.api.DataBroker contextBroker;
+
+ /**
+ * Creates configuration data tree instance.
+ * @param serializer service for serialization between Java Binding Data representation and NormalizedNode
+ * representation.
+ * @param dataTree data tree for configuration data representation
+ * @param writerRegistry service for translation between Java Binding Data and data provider, capable of performing
+ * @param contextBroker BA broker providing full access to mapping context data
+ */
+ public ModifiableDataTreeDelegator(@Nonnull final BindingNormalizedNodeSerializer serializer,
+ @Nonnull final DataTree dataTree,
+ @Nonnull final WriterRegistry writerRegistry,
+ @Nonnull final org.opendaylight.controller.md.sal.binding.api.DataBroker contextBroker) {
+ super(dataTree);
+ this.contextBroker = checkNotNull(contextBroker, "contextBroker should not be null");
+ this.serializer = checkNotNull(serializer, "serializer should not be null");
+ this.writerRegistry = checkNotNull(writerRegistry, "writerRegistry should not be null");
+ }
+
+ @Override
+ public DataModification newModification() {
+ return new ConfigSnapshot(super.newModification());
+ }
+
+ private final class ConfigSnapshot extends ModifiableDataTreeManager.ConfigSnapshot {
+
+ private final DataModification untouchedModification;
+
+ /**
+ * @param untouchedModification DataModification captured while this modification/snapshot was created.
+ * To be used later while invoking writers to provide them with before state
+ * (state without current modifications).
+ * It must be captured as close as possible to when current modification started.
+ */
+ ConfigSnapshot(final DataModification untouchedModification) {
+ this.untouchedModification = untouchedModification;
+ }
+
+ /**
+ * Pass the changes to underlying writer layer.
+ * Transform from BI to BA.
+ * Revert(Write data before to subtrees that have been successfully modified before failure) in case of failure.
+ */
+ @Override
+ protected void processCandidate(final DataTreeCandidate candidate)
+ throws TranslationException {
+ final DataTreeCandidateNode rootNode = candidate.getRootNode();
+ final YangInstanceIdentifier rootPath = candidate.getRootPath();
+ final Optional<NormalizedNode<?, ?>> normalizedDataBefore = rootNode.getDataBefore();
+ final Optional<NormalizedNode<?, ?>> normalizedDataAfter = rootNode.getDataAfter();
+ LOG.debug("ConfigDataTree.modify() rootPath={}, rootNode={}, dataBefore={}, dataAfter={}",
+ rootPath, rootNode, normalizedDataBefore, normalizedDataAfter);
+
+ final Map<InstanceIdentifier<?>, DataObject> nodesBefore = toBindingAware(normalizedDataBefore);
+ LOG.debug("ConfigDataTree.modify() extracted nodesBefore={}", nodesBefore.keySet());
+ final Map<InstanceIdentifier<?>, DataObject> nodesAfter = toBindingAware(normalizedDataAfter);
+ LOG.debug("ConfigDataTree.modify() extracted nodesAfter={}", nodesAfter.keySet());
+
+ try (final WriteContext ctx = getTransactionWriteContext()) {
+ writerRegistry.update(nodesBefore, nodesAfter, ctx);
+
+ final CheckedFuture<Void, TransactionCommitFailedException> contextUpdateResult =
+ ((TransactionMappingContext) ctx.getMappingContext()).submit();
+ // Blocking on context data update
+ contextUpdateResult.checkedGet();
+
+ } catch (io.fd.honeycomb.v3po.translate.write.WriterRegistry.BulkUpdateException e) {
+ LOG.warn("Failed to apply all changes", e);
+ LOG.info("Trying to revert successful changes for current transaction");
+
+ try {
+ e.revertChanges();
+ LOG.info("Changes successfully reverted");
+ } catch (io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter.RevertFailedException revertFailedException) {
+ // fail with failed revert
+ LOG.error("Failed to revert successful changes", revertFailedException);
+ throw revertFailedException;
+ }
+
+ throw e; // fail with success revert
+ } catch (TransactionCommitFailedException e) {
+ // FIXME revert should probably occur when context is not written successfully, but can that even happen ?
+ final String msg = "Error while updating mapping context data";
+ LOG.error(msg, e);
+ throw new TranslationException(msg, e);
+ } catch (TranslationException e) {
+ LOG.error("Error while processing data change (before={}, after={})", nodesBefore, nodesAfter, e);
+ throw e;
+ }
+ }
+
+ private TransactionWriteContext getTransactionWriteContext() {
+ // Before Tx must use modification
+ final DOMDataReadOnlyTransaction beforeTx = ReadOnlyTransaction.create(untouchedModification, EMPTY_OPERATIONAL);
+ // After Tx must use current modification
+ final DOMDataReadOnlyTransaction afterTx = ReadOnlyTransaction.create(this, EMPTY_OPERATIONAL);
+ final TransactionMappingContext mappingContext = new TransactionMappingContext(
+ contextBroker.newReadWriteTransaction());
+ return new TransactionWriteContext(serializer, beforeTx, afterTx, mappingContext);
+ }
+
+ private Map<InstanceIdentifier<?>, DataObject> toBindingAware(final Optional<NormalizedNode<?, ?>> parentOptional) {
+ if (parentOptional.isPresent()) {
+ final DataContainerNode parent = (DataContainerNode) parentOptional.get();
+ return childrenFromNormalized(parent, serializer);
+ }
+ return Collections.emptyMap();
+ }
+ }
+}
+
+
+
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeManager.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeManager.java
new file mode 100644
index 000000000..1082c479b
--- /dev/null
+++ b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeManager.java
@@ -0,0 +1,122 @@
+/*
+ * 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.data.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.util.concurrent.Futures.immediateCheckedFuture;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import io.fd.honeycomb.v3po.data.DataModification;
+import io.fd.honeycomb.v3po.data.ModifiableDataManager;
+import io.fd.honeycomb.v3po.translate.TranslationException;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+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.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * DataTree backed implementation for modifiable data manager.
+ */
+public class ModifiableDataTreeManager implements ModifiableDataManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ModifiableDataTreeManager.class);
+
+ private final DataTree dataTree;
+
+ public ModifiableDataTreeManager(@Nonnull final DataTree dataTree) {
+ this.dataTree = checkNotNull(dataTree, "dataTree should not be null");
+ }
+
+ @Override
+ public DataModification newModification() {
+ return new ConfigSnapshot();
+ }
+
+ @Override
+ public final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(@Nonnull final YangInstanceIdentifier path) {
+ return newModification().read(path);
+ }
+
+ protected class ConfigSnapshot implements DataModification {
+ private final DataTreeModification modification;
+ private boolean validated = false;
+
+ ConfigSnapshot() {
+ this(dataTree.takeSnapshot().newModification());
+ }
+
+ protected ConfigSnapshot(final DataTreeModification modification) {
+ this.modification = modification;
+ }
+
+ @Override
+ public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(
+ @Nonnull final YangInstanceIdentifier path) {
+ final Optional<NormalizedNode<?, ?>> node = modification.readNode(path);
+ if (LOG.isTraceEnabled() && node.isPresent()) {
+ LOG.trace("ConfigSnapshot.read: {}", node.get());
+ }
+ return immediateCheckedFuture(node);
+ }
+
+ @Override
+ public final void delete(final YangInstanceIdentifier path) {
+ modification.delete(path);
+ }
+
+ @Override
+ public final void merge(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+ modification.merge(path, data);
+ }
+
+ @Override
+ public final void write(final YangInstanceIdentifier path, final NormalizedNode<?, ?> data) {
+ modification.write(path, data);
+ }
+
+ @Override
+ public final void commit() throws DataValidationFailedException, TranslationException {
+ if(!validated) {
+ validate();
+ }
+ final DataTreeCandidate candidate = dataTree.prepare(modification);
+ processCandidate(candidate);
+ dataTree.commit(candidate);
+ }
+
+ protected void processCandidate(final DataTreeCandidate candidate) throws TranslationException {
+ // NOOP
+ }
+
+ @Override
+ public final void validate() throws DataValidationFailedException {
+ modification.ready();
+ dataTree.validate(modification);
+ validated = true;
+ }
+ }
+}
+
+
+
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 25d1d8dda..a54b7f148 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
@@ -127,6 +127,10 @@ public class PersistingDataTreeAdapter implements org.opendaylight.yangtools.yan
if(currentRoot.isPresent()) {
try {
LOG.trace("Persisting current data: {} into: {}", currentRoot.get(), path);
+ // Make sure the file gets overwritten
+ 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);
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransaction.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransaction.java
index 83c9e30bd..c38fa27ca 100644
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransaction.java
+++ b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransaction.java
@@ -16,14 +16,16 @@
package io.fd.honeycomb.v3po.data.impl;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+
import com.google.common.base.Function;
import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
-import io.fd.honeycomb.v3po.data.ReadableDataTree;
-import io.fd.honeycomb.v3po.data.DataTreeSnapshot;
+import io.fd.honeycomb.v3po.data.ReadableDataManager;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -37,17 +39,27 @@ import org.slf4j.LoggerFactory;
final class ReadOnlyTransaction implements DOMDataReadOnlyTransaction {
private static final Logger LOG = LoggerFactory.getLogger(ReadOnlyTransaction.class);
- private volatile ReadableDataTree operationalData;
- private volatile DataTreeSnapshot configSnapshot;
- ReadOnlyTransaction(@Nonnull final ReadableDataTree operationalData,
- @Nonnull final DataTreeSnapshot configSnapshot) {
- this.operationalData = Preconditions.checkNotNull(operationalData, "operationalData should not be null");
- this.configSnapshot = Preconditions.checkNotNull(configSnapshot, "config should not be null");
+ @Nullable
+ private volatile ReadableDataManager operationalData;
+ @Nullable
+ private volatile ReadableDataManager configSnapshot;
+
+ private volatile boolean closed = false;
+
+ /**
+ * @param configData config data tree manager. Null if config reads are not to be supported
+ * @param operationalData operational data tree manager. Null if operational reads are not to be supported
+ */
+ private ReadOnlyTransaction(@Nullable final ReadableDataManager configData,
+ @Nullable final ReadableDataManager operationalData) {
+ this.configSnapshot = configData;
+ this.operationalData = operationalData;
}
@Override
public void close() {
+ closed = true;
configSnapshot = null;
operationalData = null;
}
@@ -57,12 +69,13 @@ final class ReadOnlyTransaction implements DOMDataReadOnlyTransaction {
final LogicalDatastoreType store,
final YangInstanceIdentifier path) {
LOG.debug("ReadOnlyTransaction.read(), store={}, path={}", store, path);
-
- Preconditions.checkState(configSnapshot != null, "Transaction was closed");
+ checkState(!closed, "Transaction has been closed");
if (store == LogicalDatastoreType.OPERATIONAL) {
+ checkArgument(operationalData != null, "{} reads not supported", store);
return operationalData.read(path);
} else {
+ checkArgument(configSnapshot != null, "{} reads not supported", store);
return configSnapshot.read(path);
}
}
@@ -73,7 +86,6 @@ final class ReadOnlyTransaction implements DOMDataReadOnlyTransaction {
LOG.debug("ReadOnlyTransaction.exists() store={}, path={}", store, path);
ListenableFuture<Boolean> listenableFuture = Futures.transform(read(store, path), IS_NODE_PRESENT);
-
return Futures.makeChecked(listenableFuture, ANY_EX_TO_READ_FAILED_EXCEPTION_MAPPER);
}
@@ -83,23 +95,25 @@ final class ReadOnlyTransaction implements DOMDataReadOnlyTransaction {
return this;
}
+ @Nonnull
+ static ReadOnlyTransaction createOperationalOnly(@Nonnull final ReadableDataManager operationalData) {
+ return new ReadOnlyTransaction(null, requireNonNull(operationalData));
+ }
+
+ @Nonnull
+ static ReadOnlyTransaction createConfigOnly(@Nonnull final ReadableDataManager configData) {
+ return new ReadOnlyTransaction(requireNonNull(configData), null);
+ }
+
+ @Nonnull
+ static ReadOnlyTransaction create(@Nonnull final ReadableDataManager configData,
+ @Nonnull final ReadableDataManager operationalData) {
+ return new ReadOnlyTransaction(requireNonNull(configData), requireNonNull(operationalData));
+ }
private static final Function<? super Optional<NormalizedNode<?, ?>>, ? extends Boolean> IS_NODE_PRESENT =
- new Function<Optional<NormalizedNode<?, ?>>, Boolean>() {
- @Nullable
- @Override
- public Boolean apply(@Nullable final Optional<NormalizedNode<?, ?>> input) {
- return input == null
- ? Boolean.FALSE
- : input.isPresent();
- }
- };
+ (Function<Optional<NormalizedNode<?, ?>>, Boolean>) input -> input == null ? Boolean.FALSE : input.isPresent();
private static final Function<? super Exception, ReadFailedException> ANY_EX_TO_READ_FAILED_EXCEPTION_MAPPER =
- new Function<Exception, ReadFailedException>() {
- @Override
- public ReadFailedException apply(@Nullable final Exception e) {
- return new ReadFailedException("Exists failed", e);
- }
- };
+ (Function<Exception, ReadFailedException>) e -> new ReadFailedException("Exists failed", e);
} \ No newline at end of file
diff --git a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/OperationalDataTree.java b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegator.java
index 175f22d34..e660ee429 100644
--- a/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/OperationalDataTree.java
+++ b/v3po/data-impl/src/main/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegator.java
@@ -26,15 +26,18 @@ import com.google.common.collect.Collections2;
import com.google.common.collect.Multimap;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.Futures;
-import io.fd.honeycomb.v3po.data.ReadableDataTree;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.data.ReadableDataManager;
+import io.fd.honeycomb.v3po.translate.MappingContext;
+import io.fd.honeycomb.v3po.translate.ModificationCache;
import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.read.ReaderRegistry;
+import io.fd.honeycomb.v3po.translate.util.write.TransactionMappingContext;
import java.util.Collection;
import java.util.Map;
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.DOMDataReadOnlyTransaction;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
@@ -61,13 +64,14 @@ import org.slf4j.LoggerFactory;
/**
* ReadableDataTree implementation for operational data.
*/
-public final class OperationalDataTree implements ReadableDataTree {
- private static final Logger LOG = LoggerFactory.getLogger(OperationalDataTree.class);
+public final class ReadableDataTreeDelegator implements ReadableDataManager {
+ private static final Logger LOG = LoggerFactory.getLogger(ReadableDataTreeDelegator.class);
private final BindingNormalizedNodeSerializer serializer;
private final ReaderRegistry readerRegistry;
private final SchemaContext globalContext;
private final DOMDataBroker netconfMonitoringDomDataBrokerDependency;
+ private final org.opendaylight.controller.md.sal.binding.api.DataBroker contextBroker;
/**
* Creates operational data tree instance.
@@ -75,12 +79,16 @@ public final class OperationalDataTree implements ReadableDataTree {
* representation.
* @param globalContext service for obtaining top level context data from all yang modules.
* @param readerRegistry service responsible for translation between DataObjects and data provider.
- * @param netconfMonitoringDomDataBrokerDependency
+ * @param netconfMonitoringDomDataBrokerDependency TODO remove
+ * @param contextBroker BA broker for context data
*/
- public OperationalDataTree(@Nonnull BindingNormalizedNodeSerializer serializer,
- @Nonnull final SchemaContext globalContext, @Nonnull ReaderRegistry readerRegistry,
- final DOMDataBroker netconfMonitoringDomDataBrokerDependency) {
+ public ReadableDataTreeDelegator(@Nonnull BindingNormalizedNodeSerializer serializer,
+ @Nonnull final SchemaContext globalContext,
+ @Nonnull final ReaderRegistry readerRegistry,
+ @Nonnull final DOMDataBroker netconfMonitoringDomDataBrokerDependency,
+ @Nonnull final org.opendaylight.controller.md.sal.binding.api.DataBroker contextBroker) {
this.netconfMonitoringDomDataBrokerDependency = netconfMonitoringDomDataBrokerDependency;
+ this.contextBroker = checkNotNull(contextBroker, "contextBroker should not be null");
this.globalContext = checkNotNull(globalContext, "globalContext should not be null");
this.serializer = checkNotNull(serializer, "serializer should not be null");
this.readerRegistry = checkNotNull(readerRegistry, "reader should not be null");
@@ -91,16 +99,35 @@ public final class OperationalDataTree implements ReadableDataTree {
org.opendaylight.controller.md.sal.common.api.data.ReadFailedException> read(
@Nonnull final YangInstanceIdentifier yangInstanceIdentifier) {
- try(ReadContext ctx = new ReadContextImpl()) {
+ try(TransactionMappingContext mappingContext = new TransactionMappingContext(contextBroker.newReadWriteTransaction());
+ ReadContext ctx = new ReadContextImpl(mappingContext)) {
+
+ final Optional<NormalizedNode<?, ?>> value;
if (checkNotNull(yangInstanceIdentifier).equals(YangInstanceIdentifier.EMPTY)) {
- return Futures.immediateCheckedFuture(readRoot(ctx));
+ value = readRoot(ctx);
} else {
- return Futures.immediateCheckedFuture(readNode(yangInstanceIdentifier, ctx));
+ value = readNode(yangInstanceIdentifier, ctx);
}
+
+ // Submit context mapping updates
+ final CheckedFuture<Void, TransactionCommitFailedException> contextUpdateResult =
+ ((TransactionMappingContext) ctx.getMappingContext()).submit();
+ // Blocking on context data update
+ contextUpdateResult.checkedGet();
+
+ return Futures.immediateCheckedFuture(value);
+
} catch (ReadFailedException e) {
return Futures.immediateFailedCheckedFuture(
- new org.opendaylight.controller.md.sal.common.api.data.ReadFailedException(
- "Failed to read VPP data", e));
+ new org.opendaylight.controller.md.sal.common.api.data.ReadFailedException(
+ "Failed to read VPP data", e));
+ } catch (TransactionCommitFailedException e) {
+ // FIXME revert should probably occur when context is not written successfully, but can that even happen ?
+ final String msg = "Error while updating mapping context data";
+ LOG.error(msg, e);
+ return Futures.immediateFailedCheckedFuture(
+ new org.opendaylight.controller.md.sal.common.api.data.ReadFailedException(msg, e)
+ );
}
}
@@ -108,6 +135,8 @@ public final class OperationalDataTree implements ReadableDataTree {
final ReadContext ctx) throws ReadFailedException {
// FIXME workaround for: https://git.opendaylight.org/gerrit/#/c/37499/
+ // Just delete, dedicated reader from NetconfMonitoringReaderModule takes care of netconf state data
+ // TODO test connecting with netconf and issuing a get (netconf-state) data should be provided
if(yangInstanceIdentifier.getPathArguments().size() > 0 &&
yangInstanceIdentifier.getPathArguments().get(0).getNodeType().equals(NetconfState.QNAME)) {
return readFromNetconfDs(yangInstanceIdentifier);
@@ -222,17 +251,29 @@ public final class OperationalDataTree implements ReadableDataTree {
}
private static final class ReadContextImpl implements ReadContext {
- public final Context ctx = new Context();
+
+ public final ModificationCache ctx = new ModificationCache();
+ private final MappingContext mappingContext;
+
+ private ReadContextImpl(final MappingContext mappingContext) {
+ this.mappingContext = mappingContext;
+ }
@Nonnull
@Override
- public Context getContext() {
+ public ModificationCache getModificationCache() {
return ctx;
}
+ @Nonnull
+ @Override
+ public MappingContext getMappingContext() {
+ return mappingContext;
+ }
+
@Override
public void close() {
- // Make sure to clear the storage in case some customizer stored it to prevent memory leaks
+ // Make sure to clear the storage in case some customizer stored a reference to it to prevent memory leaks
ctx.close();
}
}
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 fbeba7e07..3644a9fe7 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
@@ -16,6 +16,8 @@
package io.fd.honeycomb.v3po.data.impl;
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
import static org.opendaylight.controller.md.sal.common.api.TransactionStatus.CANCELED;
import static org.opendaylight.controller.md.sal.common.api.TransactionStatus.COMMITED;
import static org.opendaylight.controller.md.sal.common.api.TransactionStatus.FAILED;
@@ -26,10 +28,10 @@ import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
-import io.fd.honeycomb.v3po.data.ModifiableDataTree;
-import io.fd.honeycomb.v3po.data.DataTreeSnapshot;
+import io.fd.honeycomb.v3po.data.DataModification;
import io.fd.honeycomb.v3po.translate.TranslationException;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -38,7 +40,6 @@ import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
import org.opendaylight.yangtools.yang.common.RpcResult;
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.DataTreeModification;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,30 +48,21 @@ import org.slf4j.LoggerFactory;
final class WriteTransaction implements DOMDataWriteTransaction {
private static final Logger LOG = LoggerFactory.getLogger(WriteTransaction.class);
- private final ModifiableDataTree configDataTree;
- private DataTreeModification modification;
- private TransactionStatus status;
-
- WriteTransaction(@Nonnull final ModifiableDataTree configDataTree,
- @Nonnull final DataTreeSnapshot configSnapshot) {
- this.configDataTree = Preconditions.checkNotNull(configDataTree, "configDataTree should not be null");
- Preconditions.checkNotNull(configSnapshot, "configSnapshot should not be null");
- // initialize transaction state:
- modification = configSnapshot.newModification();
- status = NEW;
- }
- WriteTransaction(@Nonnull final ModifiableDataTree configDataTree) {
- this(configDataTree, configDataTree.takeSnapshot());
- }
+ @Nullable
+ private DataModification operationalModification;
+ @Nullable
+ private DataModification configModification;
+ private TransactionStatus status = NEW;
- private static void checkConfigurationWrite(final LogicalDatastoreType store) {
- Preconditions.checkArgument(LogicalDatastoreType.CONFIGURATION == store, "Write is not supported for operational data store");
+ private WriteTransaction(@Nullable final DataModification configModification,
+ @Nullable final DataModification operationalModification) {
+ this.operationalModification = operationalModification;
+ this.configModification = configModification;
}
private void checkIsNew() {
Preconditions.checkState(status == NEW, "Transaction was submitted or canceled");
- Preconditions.checkState(modification != null, "DataTree modification should not be null");
}
@Override
@@ -78,8 +70,21 @@ final class WriteTransaction implements DOMDataWriteTransaction {
final NormalizedNode<?, ?> data) {
LOG.debug("WriteTransaction.put() store={}, path={}, data={}", store, path, data);
checkIsNew();
- checkConfigurationWrite(store);
- modification.write(path, data);
+ handleOperation(store, (modification) -> modification.write(path, data));
+ }
+
+ private void handleOperation(final LogicalDatastoreType store,
+ final java.util.function.Consumer<DataModification> r) {
+ switch (store) {
+ case CONFIGURATION:
+ checkArgument(configModification != null, "Modification of {} is not supported", store);
+ r.accept(configModification);
+ break;
+ case OPERATIONAL:
+ checkArgument(operationalModification != null, "Modification of {} is not supported", store);
+ r.accept(operationalModification);
+ break;
+ }
}
@Override
@@ -87,8 +92,7 @@ final class WriteTransaction implements DOMDataWriteTransaction {
final NormalizedNode<?, ?> data) {
LOG.debug("WriteTransaction.merge() store={}, path={}, data={}", store, path, data);
checkIsNew();
- checkConfigurationWrite(store);
- modification.merge(path, data);
+ handleOperation(store, (modification) -> modification.merge(path, data));
}
@Override
@@ -98,7 +102,6 @@ final class WriteTransaction implements DOMDataWriteTransaction {
return false;
} else {
status = CANCELED;
- modification = null;
return true;
}
}
@@ -107,29 +110,38 @@ final class WriteTransaction implements DOMDataWriteTransaction {
public void delete(LogicalDatastoreType store, final YangInstanceIdentifier path) {
LOG.debug("WriteTransaction.delete() store={}, path={}", store, path);
checkIsNew();
- checkConfigurationWrite(store);
- modification.delete(path);
+ handleOperation(store, (modification) -> modification.delete(path));
}
@Override
public CheckedFuture<Void, TransactionCommitFailedException> submit() {
- LOG.debug("WriteTransaction.submit()");
+ LOG.trace("WriteTransaction.submit()");
checkIsNew();
- // seal transaction:
- modification.ready();
- status = SUBMITED;
-
try {
- configDataTree.modify(modification);
+ status = SUBMITED;
+
+ // Validate first to catch any issues before attempting commit
+ if (configModification != null) {
+ configModification.validate();
+ }
+ if (operationalModification != null) {
+ operationalModification.validate();
+ }
+
+ if(configModification != null) {
+ configModification.commit();
+ }
+ if(operationalModification != null) {
+ operationalModification.commit();
+ }
+
status = COMMITED;
} catch (DataValidationFailedException | TranslationException e) {
status = FAILED;
LOG.error("Failed modify data tree", e);
return Futures.immediateFailedCheckedFuture(
- new TransactionCommitFailedException("Failed to validate DataTreeModification", e));
- } finally {
- modification = null;
+ new TransactionCommitFailedException("Failed to validate DataTreeModification", e));
}
return Futures.immediateCheckedFuture(null);
}
@@ -144,4 +156,21 @@ final class WriteTransaction implements DOMDataWriteTransaction {
public Object getIdentifier() {
return this;
}
+
+
+ @Nonnull
+ static WriteTransaction createOperationalOnly(@Nonnull final DataModification operationalData) {
+ return new WriteTransaction(null, requireNonNull(operationalData));
+ }
+
+ @Nonnull
+ static WriteTransaction createConfigOnly(@Nonnull final DataModification configData) {
+ return new WriteTransaction(requireNonNull(configData), null);
+ }
+
+ @Nonnull
+ static WriteTransaction create(@Nonnull final DataModification configData,
+ @Nonnull final DataModification operationalData) {
+ return new WriteTransaction(requireNonNull(configData), requireNonNull(operationalData));
+ }
}
diff --git a/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/ConfigDataTreeModule.java b/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/ConfigDataTreeModule.java
index 86a3f9db4..3e871e09a 100644
--- a/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/ConfigDataTreeModule.java
+++ b/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/ConfigDataTreeModule.java
@@ -1,11 +1,14 @@
package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.data.impl.rev160411;
-import io.fd.honeycomb.v3po.data.DataTreeSnapshot;
-import io.fd.honeycomb.v3po.data.ModifiableDataTree;
-import io.fd.honeycomb.v3po.data.impl.ConfigDataTree;
-import io.fd.honeycomb.v3po.translate.TranslationException;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import io.fd.honeycomb.v3po.data.DataModification;
+import io.fd.honeycomb.v3po.data.ModifiableDataManager;
+import io.fd.honeycomb.v3po.data.impl.ModifiableDataTreeDelegator;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -35,14 +38,15 @@ public class ConfigDataTreeModule extends
public java.lang.AutoCloseable createInstance() {
LOG.debug("ConfigDataTreeModule.createInstance()");
return new CloseableConfigDataTree(
- new ConfigDataTree(getSerializerDependency(), getDataTreeDependency(), getWriterRegistryDependency()));
+ new ModifiableDataTreeDelegator(getSerializerDependency(), getDataTreeDependency(), getWriterRegistryDependency(),
+ getContextBindingBrokerDependency()));
}
- private static final class CloseableConfigDataTree implements ModifiableDataTree, AutoCloseable {
+ private static final class CloseableConfigDataTree implements ModifiableDataManager, AutoCloseable {
- private final ConfigDataTree delegate;
+ private final ModifiableDataTreeDelegator delegate;
- CloseableConfigDataTree(final ConfigDataTree delegate) {
+ CloseableConfigDataTree(final ModifiableDataTreeDelegator delegate) {
this.delegate = delegate;
}
@@ -53,16 +57,15 @@ public class ConfigDataTreeModule extends
}
@Override
- public void modify(final DataTreeModification modification)
- throws DataValidationFailedException, TranslationException {
- LOG.trace("CloseableConfigDataTree.modify modification={}", modification);
- delegate.modify(modification);
+ public DataModification newModification() {
+ LOG.trace("CloseableConfigDataTree.newModification");
+ return delegate.newModification();
}
@Override
- public DataTreeSnapshot takeSnapshot() {
- LOG.trace("CloseableConfigDataTree.takeSnapshot");
- return delegate.takeSnapshot();
+ public CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read(
+ @Nonnull final YangInstanceIdentifier path) {
+ return delegate.read(path);
}
}
}
diff --git a/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/OperationalDataTreeModule.java b/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/OperationalDataTreeModule.java
index 2fbba75fa..286eaf664 100644
--- a/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/OperationalDataTreeModule.java
+++ b/v3po/data-impl/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/data/impl/rev160411/OperationalDataTreeModule.java
@@ -2,8 +2,8 @@ package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.data.impl.
import com.google.common.base.Optional;
import com.google.common.util.concurrent.CheckedFuture;
-import io.fd.honeycomb.v3po.data.ReadableDataTree;
-import io.fd.honeycomb.v3po.data.impl.OperationalDataTree;
+import io.fd.honeycomb.v3po.data.ReadableDataManager;
+import io.fd.honeycomb.v3po.data.impl.ReadableDataTreeDelegator;
import javax.annotation.Nonnull;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -37,15 +37,15 @@ public class OperationalDataTreeModule extends
public java.lang.AutoCloseable createInstance() {
LOG.debug("OperationalDataTreeModule.createInstance()");
return new CloseableOperationalDataTree(
- new OperationalDataTree(getSerializerDependency(), getSchemaServiceDependency().getGlobalContext(),
- getReaderRegistryDependency(), getNetconfMonitoringDomDataBrokerDependency()));
+ new ReadableDataTreeDelegator(getSerializerDependency(), getSchemaServiceDependency().getGlobalContext(),
+ getReaderRegistryDependency(), getNetconfMonitoringDomDataBrokerDependency(), getContextBindingBrokerDependency()));
}
- private static final class CloseableOperationalDataTree implements ReadableDataTree, AutoCloseable {
+ private static final class CloseableOperationalDataTree implements ReadableDataManager, AutoCloseable {
- private final OperationalDataTree delegate;
+ private final ReadableDataTreeDelegator delegate;
- CloseableOperationalDataTree(final OperationalDataTree delegate) {
+ CloseableOperationalDataTree(final ReadableDataTreeDelegator delegate) {
this.delegate = delegate;
}
diff --git a/v3po/data-impl/src/main/yang/data-impl.yang b/v3po/data-impl/src/main/yang/data-impl.yang
index 454e99a66..3af9d8d3f 100644
--- a/v3po/data-impl/src/main/yang/data-impl.yang
+++ b/v3po/data-impl/src/main/yang/data-impl.yang
@@ -121,6 +121,14 @@ module data-impl {
}
}
+ container context-binding-broker {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity md-sal-binding:binding-async-data-broker;
+ }
+ }
+ }
}
}
@@ -171,6 +179,15 @@ module data-impl {
}
}
+ container context-binding-broker {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity md-sal-binding:binding-async-data-broker;
+ }
+ }
+ }
+
}
}
} \ No newline at end of file
diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/DataBrokerTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/DataBrokerTest.java
index a2908d591..55b92b50b 100644
--- a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/DataBrokerTest.java
+++ b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/DataBrokerTest.java
@@ -22,9 +22,9 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
-import io.fd.honeycomb.v3po.data.ReadableDataTree;
-import io.fd.honeycomb.v3po.data.ModifiableDataTree;
-import io.fd.honeycomb.v3po.data.DataTreeSnapshot;
+import io.fd.honeycomb.v3po.data.ReadableDataManager;
+import io.fd.honeycomb.v3po.data.ModifiableDataManager;
+import io.fd.honeycomb.v3po.data.DataModification;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;
@@ -42,18 +42,18 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
public class DataBrokerTest {
@Mock
- private ReadableDataTree operationalData;
+ private ReadableDataManager operationalData;
@Mock
- private ModifiableDataTree confiDataTree;
+ private ModifiableDataManager confiDataTree;
@Mock
- private DataTreeSnapshot configSnapshot;
+ private DataModification configSnapshot;
private DataBroker broker;
@Before
public void setUp() {
initMocks(this);
- when(confiDataTree.takeSnapshot()).thenReturn(configSnapshot);
- broker = new DataBroker(operationalData, confiDataTree);
+ when(confiDataTree.newModification()).thenReturn(configSnapshot);
+ broker = DataBroker.create(confiDataTree, operationalData);
}
@Test
@@ -64,7 +64,7 @@ public class DataBrokerTest {
// verify that read and write transactions use the same config snapshot
verify(configSnapshot).read(path);
- verify(configSnapshot).newModification();
+ verify(confiDataTree).newModification();
}
@Test
@@ -72,7 +72,7 @@ public class DataBrokerTest {
final DOMDataWriteTransaction writeTx = broker.newWriteOnlyTransaction();
// verify that write transactions use config snapshot
- verify(configSnapshot).newModification();
+ verify(confiDataTree).newModification();
}
@Test
diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ConfigDataTreeTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java
index b7f8b9d2c..fed32da8a 100644
--- a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ConfigDataTreeTest.java
+++ b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java
@@ -25,13 +25,15 @@ import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.CheckedFuture;
-import io.fd.honeycomb.v3po.data.DataTreeSnapshot;
+import com.google.common.util.concurrent.Futures;
+import io.fd.honeycomb.v3po.data.DataModification;
import io.fd.honeycomb.v3po.translate.TranslationException;
import io.fd.honeycomb.v3po.translate.write.WriteContext;
import io.fd.honeycomb.v3po.translate.write.WriterRegistry;
@@ -42,6 +44,7 @@ import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Ethernet;
@@ -55,9 +58,8 @@ 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.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
-public class ConfigDataTreeTest {
+public class ModifiableDataTreeDelegatorTest {
@Mock
private WriterRegistry writer;
@@ -66,14 +68,16 @@ public class ConfigDataTreeTest {
@Mock
private DataTree dataTree;
@Mock
- private DataTreeModification modification;
+ private org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification modification;
+ @Mock
+ private DataBroker contextBroker;
- private ConfigDataTree configDataTree;
+ private ModifiableDataTreeManager configDataTree;
@Before
public void setUp() {
initMocks(this);
- configDataTree = new ConfigDataTree(serializer, dataTree, writer);
+ configDataTree = new ModifiableDataTreeDelegator(serializer, dataTree, writer, contextBroker);
}
@Test
@@ -81,17 +85,18 @@ public class ConfigDataTreeTest {
final org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot
snapshot = mock(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot.class);
when(dataTree.takeSnapshot()).thenReturn(snapshot);
+ when(snapshot.newModification()).thenReturn(modification);
final YangInstanceIdentifier path = mock(YangInstanceIdentifier.class);
final Optional node = mock(Optional.class);
- doReturn(node).when(snapshot).readNode(path);
+ doReturn(node).when(modification).readNode(path);
- final DataTreeSnapshot dataTreeSnapshot = configDataTree.takeSnapshot();
+ final DataModification dataTreeSnapshot = configDataTree.newModification();
final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> future =
dataTreeSnapshot.read(path);
- verify(dataTree).takeSnapshot();
- verify(snapshot).readNode(path);
+ verify(dataTree, times(2)).takeSnapshot();
+ verify(modification).readNode(path);
assertTrue(future.isDone());
assertEquals(node, future.get());
@@ -102,19 +107,29 @@ public class ConfigDataTreeTest {
final org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot
snapshot = mock(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot.class);
when(dataTree.takeSnapshot()).thenReturn(snapshot);
-
when(snapshot.newModification()).thenReturn(modification);
- final DataTreeSnapshot dataTreeSnapshot = configDataTree.takeSnapshot();
- final DataTreeModification newModification = dataTreeSnapshot.newModification();
- verify(dataTree).takeSnapshot();
- verify(snapshot).newModification();
-
- assertEquals(modification, newModification);
+ final DataModification dataTreeSnapshot = configDataTree.newModification();
+ // Snapshot captured twice, so that original data could be provided to translation layer without any possible
+ // modification
+ verify(dataTree, times(2)).takeSnapshot();
+ verify(snapshot, times(2)).newModification();
}
@Test
public void testCommitSuccessful() throws Exception {
+ final org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot
+ snapshot = mock(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot.class);
+ when(dataTree.takeSnapshot()).thenReturn(snapshot);
+ when(snapshot.newModification()).thenReturn(modification);
+ final DataTreeCandidate prepare = mock(DataTreeCandidate.class);
+ doReturn(prepare).when(dataTree).prepare(modification);
+
+ final org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction ctxTransaction = mock(
+ org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction.class);
+ doReturn(ctxTransaction).when(contextBroker).newReadWriteTransaction();
+ doReturn(Futures.immediateCheckedFuture(null)).when(ctxTransaction).submit();
+
final DataObject dataBefore = mockDataObject("before", Ethernet.class);
final DataObject dataAfter = mockDataObject("after", Ethernet.class);
@@ -128,7 +143,9 @@ public class ConfigDataTreeTest {
when(rootNode.getDataAfter()).thenReturn(Optional.<NormalizedNode<?, ?>>fromNullable(nodeAfter));
// Run the test
- configDataTree.modify(modification);
+ doReturn(rootNode).when(prepare).getRootNode();
+ final DataModification dataModification = configDataTree.newModification();
+ dataModification.commit();
// Verify all changes were processed:
verify(writer).update(
@@ -138,6 +155,8 @@ public class ConfigDataTreeTest {
// Verify modification was validated
verify(dataTree).validate(modification);
+ // Verify context transaction was finished
+ verify(ctxTransaction).submit();
}
private Map<InstanceIdentifier<?>, DataObject> mapOf(final DataObject dataBefore, final Class<Ethernet> type) {
@@ -154,6 +173,13 @@ public class ConfigDataTreeTest {
@Test
public void testCommitUndoSuccessful() throws Exception {
+ final org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot
+ snapshot = mock(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot.class);
+ when(dataTree.takeSnapshot()).thenReturn(snapshot);
+ when(snapshot.newModification()).thenReturn(modification);
+ final DataTreeCandidate prepare = mock(DataTreeCandidate.class);
+ doReturn(prepare).when(dataTree).prepare(modification);
+
// Prepare data changes:
final DataObject dataBefore = mockDataObject("before", Ethernet.class);
final DataObject dataAfter = mockDataObject("after", Ethernet.class);
@@ -177,7 +203,9 @@ public class ConfigDataTreeTest {
// Run the test
try {
- configDataTree.modify(modification);
+ doReturn(rootNode).when(prepare).getRootNode();
+ final DataModification dataModification = configDataTree.newModification();
+ dataModification.commit();
} catch (io.fd.honeycomb.v3po.translate.write.WriterRegistry.BulkUpdateException e) {
verify(writer).update(anyMap(), anyMap(), any(WriteContext.class));
verify(reverter).revert();
@@ -190,6 +218,13 @@ public class ConfigDataTreeTest {
@Test
public void testCommitUndoFailed() throws Exception {
+ final org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot
+ snapshot = mock(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot.class);
+ when(dataTree.takeSnapshot()).thenReturn(snapshot);
+ when(snapshot.newModification()).thenReturn(modification);
+ final DataTreeCandidate prepare = mock(DataTreeCandidate.class);
+ doReturn(prepare).when(dataTree).prepare(modification);
+
// Prepare data changes:
final DataObject dataBefore = mockDataObject("before", Ethernet.class);
final DataObject dataAfter = mockDataObject("after", Ethernet.class);
@@ -219,7 +254,9 @@ public class ConfigDataTreeTest {
// Run the test
try {
- configDataTree.modify(modification);
+ doReturn(rootNode).when(prepare).getRootNode();
+ final DataModification dataModification = configDataTree.newModification();
+ dataModification.commit();
} catch (io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter.RevertFailedException e) {
verify(writer).update(anyMap(), anyMap(), any(WriteContext.class));
verify(reverter).revert();
diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransactionTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransactionTest.java
index 30fdd1392..a13621725 100644
--- a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransactionTest.java
+++ b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransactionTest.java
@@ -24,8 +24,8 @@ import static org.mockito.MockitoAnnotations.initMocks;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.CheckedFuture;
-import io.fd.honeycomb.v3po.data.ReadableDataTree;
-import io.fd.honeycomb.v3po.data.DataTreeSnapshot;
+import io.fd.honeycomb.v3po.data.ReadableDataManager;
+import io.fd.honeycomb.v3po.data.DataModification;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -37,16 +37,16 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
public class ReadOnlyTransactionTest {
@Mock
- private ReadableDataTree operationalData;
+ private ReadableDataManager operationalData;
@Mock
- private DataTreeSnapshot configSnapshot;
+ private DataModification configSnapshot;
private ReadOnlyTransaction readOnlyTx;
@Before
public void setUp() {
initMocks(this);
- readOnlyTx = new ReadOnlyTransaction(operationalData, configSnapshot);
+ readOnlyTx = ReadOnlyTransaction.create(configSnapshot, operationalData);
}
@Test
diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/OperationalDataTreeTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegatorTest.java
index 7e6abcdcd..4492c70a2 100644
--- a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/OperationalDataTreeTest.java
+++ b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegatorTest.java
@@ -42,6 +42,7 @@ import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
@@ -58,14 +59,14 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-public class OperationalDataTreeTest {
+public class ReadableDataTreeDelegatorTest {
@Mock
private BindingNormalizedNodeSerializer serializer;
@Mock
private ReaderRegistry reader;
- private OperationalDataTree operationalData;
+ private ReadableDataTreeDelegator operationalData;
@Mock
private InstanceIdentifier<DataObject> id;
@@ -81,16 +82,23 @@ public class OperationalDataTreeTest {
private DOMDataBroker netconfMonitoringBroker;
@Mock
private DOMDataReadOnlyTransaction domDataReadOnlyTransaction;
+ @Mock
+ private DataBroker contextBroker;
@Before
public void setUp() {
initMocks(this);
- operationalData = new OperationalDataTree(serializer, globalContext, reader, netconfMonitoringBroker);
+ operationalData = new ReadableDataTreeDelegator(serializer, globalContext, reader, netconfMonitoringBroker, contextBroker);
doReturn(schemaNode).when(globalContext).getDataChildByName(any(QName.class));
doReturn(domDataReadOnlyTransaction).when(netconfMonitoringBroker).newReadOnlyTransaction();
doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(domDataReadOnlyTransaction)
.read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class));
+
+ final org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction ctxTransaction = mock(
+ org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction.class);
+ doReturn(ctxTransaction).when(contextBroker).newReadWriteTransaction();
+ doReturn(Futures.immediateCheckedFuture(null)).when(ctxTransaction).submit();
}
@Test
diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/WriteTransactionTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/WriteTransactionTest.java
index d0360dbd8..9cde27d2b 100644
--- a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/WriteTransactionTest.java
+++ b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/WriteTransactionTest.java
@@ -23,12 +23,10 @@ import static org.junit.Assert.fail;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import com.google.common.util.concurrent.CheckedFuture;
-import io.fd.honeycomb.v3po.data.ModifiableDataTree;
-import io.fd.honeycomb.v3po.data.DataTreeSnapshot;
+import io.fd.honeycomb.v3po.data.DataModification;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
@@ -36,54 +34,48 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
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.DataTreeModification;
import org.opendaylight.yangtools.yang.data.api.schema.tree.DataValidationFailedException;
public class WriteTransactionTest {
@Mock
- private ModifiableDataTree configDataTree;
- @Mock
- private DataTreeSnapshot configSnapshot;
+ private DataModification configSnapshot;
@Mock
private YangInstanceIdentifier path;
@Mock
private NormalizedNode<?,?> data;
- @Mock
- private DataTreeModification dataTreeModification;
private WriteTransaction writeTx;
@Before
public void setUp() {
initMocks(this);
- when(configSnapshot.newModification()).thenReturn(dataTreeModification);
- writeTx = new WriteTransaction(configDataTree, configSnapshot);
+ writeTx = WriteTransaction.createConfigOnly(configSnapshot);
}
@Test
public void testPut() {
writeTx.put(LogicalDatastoreType.CONFIGURATION, path, data);
- verify(dataTreeModification).write(path, data);
+ verify(configSnapshot).write(path, data);
}
@Test(expected = IllegalArgumentException.class)
public void testPutOperational() {
writeTx.put(LogicalDatastoreType.OPERATIONAL, path, data);
- verify(dataTreeModification).write(path, data);
+ verify(configSnapshot).write(path, data);
}
@Test(expected = IllegalStateException.class)
public void testOnFinishedTx() {
writeTx.submit();
writeTx.put(LogicalDatastoreType.CONFIGURATION, path, data);
- verify(dataTreeModification).write(path, data);
+ verify(configSnapshot).write(path, data);
}
@Test
public void testMerge() {
writeTx.merge(LogicalDatastoreType.CONFIGURATION, path, data);
- verify(dataTreeModification).merge(path, data);
+ verify(configSnapshot).merge(path, data);
}
@Test
@@ -100,19 +92,19 @@ public class WriteTransactionTest {
@Test
public void testDelete() {
writeTx.delete(LogicalDatastoreType.CONFIGURATION, path);
- verify(dataTreeModification).delete(path);
+ verify(configSnapshot).delete(path);
}
@Test
public void testSubmit() throws Exception {
writeTx.submit();
- verify(dataTreeModification).ready();
- verify(configDataTree).modify(dataTreeModification);
+ verify(configSnapshot).validate();
+ verify(configSnapshot).commit();
}
@Test
public void testSubmitFailed() throws Exception {
- doThrow(mock(DataValidationFailedException.class)).when(configDataTree).modify(dataTreeModification);
+ doThrow(mock(DataValidationFailedException.class)).when(configSnapshot).commit();
final CheckedFuture<Void, TransactionCommitFailedException> future = writeTx.submit();
try {
future.get();
diff --git a/v3po/impl/src/main/config/context-datatree-config.xml b/v3po/impl/src/main/config/context-datatree-config.xml
index c9f9902f3..13da9ec65 100644
--- a/v3po/impl/src/main/config/context-datatree-config.xml
+++ b/v3po/impl/src/main/config/context-datatree-config.xml
@@ -58,7 +58,40 @@
</schema-service>
<persist-file-path>etc/opendaylight/honeycomb/context.json</persist-file-path>
</module>
+
+ <!-- DOM Data Broker for context data -->
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:v3po:impl">prefix:honeycomb-context-dom-data-broker</type>
+ <name>honeycomb-context-data-broker</name>
+ <!-- With persistence -->
+ <context-data-tree>
+ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:data-tree</type>
+ <name>inmemory-persisted-context-data-tree</name>
+ </context-data-tree>
+ </module>
+
+ <!-- BA Data Broker for context data -->
+ <module>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-forwarded-data-broker</type>
+ <name>honeycomb-context-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>honeycomb-context-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>
</modules>
+
+
<services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
<service>
<type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:data-tree</type>
@@ -73,6 +106,22 @@
</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>honeycomb-context-data-broker</name>
+ <provider>/modules/module[type='honeycomb-context-dom-data-broker'][name='honeycomb-context-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>honeycomb-context-binding-data-broker</name>
+ <provider>/modules/module[type='binding-forwarded-data-broker'][name='honeycomb-context-binding-data-broker']</provider>
+ </instance>
+ </service>
</services>
</data>
</configuration>
diff --git a/v3po/impl/src/main/config/default-config.xml b/v3po/impl/src/main/config/default-config.xml
index 89e1f7ce2..7106c78ce 100644
--- a/v3po/impl/src/main/config/default-config.xml
+++ b/v3po/impl/src/main/config/default-config.xml
@@ -88,6 +88,10 @@
<type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-writer-registry</type>
<name>write-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>
<!-- FIXME workaround for: https://git.opendaylight.org/gerrit/#/c/37499/ Move to netconf-north-config-->
@@ -152,6 +156,10 @@
<type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
<name>netconf-inmemory-data-broker</name>
</netconf-monitoring-dom-data-broker>
+ <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 which provides transaction functionality for HC using BI format-->
@@ -233,6 +241,10 @@
<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>
diff --git a/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/ContextDataBrokerModule.java b/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/ContextDataBrokerModule.java
new file mode 100644
index 000000000..1d1fa5323
--- /dev/null
+++ b/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/ContextDataBrokerModule.java
@@ -0,0 +1,26 @@
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.impl.rev141210;
+
+import io.fd.honeycomb.v3po.data.impl.DataBroker;
+import io.fd.honeycomb.v3po.data.impl.ModifiableDataTreeManager;
+
+public class ContextDataBrokerModule extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.impl.rev141210.AbstractContextDataBrokerModule {
+
+ public ContextDataBrokerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public ContextDataBrokerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.impl.rev141210.ContextDataBrokerModule 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 DataBroker.create(new ModifiableDataTreeManager(getContextDataTreeDependency()));
+ }
+
+}
diff --git a/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/ContextDataBrokerModuleFactory.java b/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/ContextDataBrokerModuleFactory.java
new file mode 100644
index 000000000..360f5f472
--- /dev/null
+++ b/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/ContextDataBrokerModuleFactory.java
@@ -0,0 +1,13 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: v3po-impl yang module local name: honeycomb-context-dom-data-broker
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Mon May 16 15:27:12 CEST 2016
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.impl.rev141210;
+public class ContextDataBrokerModuleFactory extends org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.impl.rev141210.AbstractContextDataBrokerModuleFactory {
+
+}
diff --git a/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/DataBrokerModule.java b/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/DataBrokerModule.java
index 24e34c0a9..8aa3d64d9 100644
--- a/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/DataBrokerModule.java
+++ b/v3po/impl/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/v3po/impl/rev141210/DataBrokerModule.java
@@ -1,19 +1,6 @@
package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.impl.rev141210;
import io.fd.honeycomb.v3po.data.impl.DataBroker;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataChangeListener;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,63 +29,6 @@ public class DataBrokerModule extends
@Override
public java.lang.AutoCloseable createInstance() {
LOG.debug("DataBrokerModule.createInstance()");
- return new CloseableDataBroker(
- new DataBroker(getOperationalDataTreeDependency(), getConfigDataTreeDependency()));
- }
-
- private static final class CloseableDataBroker implements AutoCloseable, DOMDataBroker {
-
- private final DataBroker delegate;
-
- CloseableDataBroker(final DataBroker delegate) {
- this.delegate = delegate;
- }
-
- @Override
- public void close() throws Exception {
- LOG.debug("CloseableDataBroker.close()");
- // NOP
- }
-
- @Override
- public DOMDataReadOnlyTransaction newReadOnlyTransaction() {
- LOG.trace("CloseableDataBroker.newReadOnlyTransaction()");
- return delegate.newReadOnlyTransaction();
- }
-
- @Override
- public DOMDataReadWriteTransaction newReadWriteTransaction() {
- LOG.trace("CloseableDataBroker.newReadWriteTransaction()");
- return delegate.newReadWriteTransaction();
- }
-
- @Override
- public DOMDataWriteTransaction newWriteOnlyTransaction() {
- LOG.trace("CloseableDataBroker.newWriteOnlyTransaction()");
- return delegate.newWriteOnlyTransaction();
- }
-
- @Override
- public ListenerRegistration<DOMDataChangeListener> registerDataChangeListener(final LogicalDatastoreType store,
- final YangInstanceIdentifier path,
- final DOMDataChangeListener listener,
- final DataChangeScope triggeringScope) {
- LOG.trace("CloseableDataBroker.createTransactionChain store={}, path={}, listener={}, triggeringScope={}",
- store, path, listener, triggeringScope);
- return delegate.registerDataChangeListener(store, path, listener, triggeringScope);
- }
-
- @Override
- public DOMTransactionChain createTransactionChain(final TransactionChainListener listener) {
- LOG.trace("CloseableDataBroker.createTransactionChain listener={}", listener);
- return delegate.createTransactionChain(listener);
- }
-
- @Nonnull
- @Override
- public Map<Class<? extends DOMDataBrokerExtension>, DOMDataBrokerExtension> getSupportedExtensions() {
- LOG.trace("CloseableDataBroker.getSupportedExtensions()");
- return delegate.getSupportedExtensions();
- }
+ return DataBroker.create(getConfigDataTreeDependency(), getOperationalDataTreeDependency());
}
}
diff --git a/v3po/impl/src/main/yang/v3po-impl.yang b/v3po/impl/src/main/yang/v3po-impl.yang
index 30b70f342..3f7af6185 100644
--- a/v3po/impl/src/main/yang/v3po-impl.yang
+++ b/v3po/impl/src/main/yang/v3po-impl.yang
@@ -101,6 +101,28 @@ module v3po-impl {
}
}
+ identity honeycomb-context-dom-data-broker {
+ base config:module-type;
+ config:provided-service dom:dom-async-data-broker;
+ config:java-name-prefix ContextDataBroker;
+ description "DomBroker on top of context data-tree";
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case honeycomb-context-dom-data-broker {
+ when "/config:modules/config:module/config:type = 'honeycomb-context-dom-data-broker'";
+
+ container context-data-tree {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity dapi:data-tree;
+ }
+ }
+ }
+ }
+ }
+
identity netconf-monitoring-reader {
base config:module-type;
config:provided-service tapi:honeycomb-reader;
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/MappingContext.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/MappingContext.java
new file mode 100644
index 000000000..cff766e2a
--- /dev/null
+++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/MappingContext.java
@@ -0,0 +1,66 @@
+/*
+ * 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;
+
+import com.google.common.base.Optional;
+import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Mapping context is persisted storage where mapping matadata are stored.
+ * A snapshot is created for each transaction to provide consistent view over context data.
+ * After a transaction is successfully finished, objects added to this context are propagated to backing storage.
+ */
+public interface MappingContext extends AutoCloseable {
+
+ /**
+ * Read any mapping context data
+ *
+ * @param currentId Id of an object to read
+ *
+ * @return Relevant mapping context data
+ */
+ <T extends DataObject> Optional<T> read(@Nonnull final InstanceIdentifier<T> currentId);
+
+ /**
+ * Delete the node at specified path.
+ *
+ * @param path Node path
+ */
+ void delete(InstanceIdentifier<?> path);
+
+ /**
+ * Merge the specified data with the currently-present data
+ * at specified path.
+ *
+ * @param path Node path
+ * @param data Data to be merged
+ */
+ <T extends DataObject> void merge(InstanceIdentifier<T> path, T data);
+
+ /**
+ * Replace the data at specified path with supplied data.
+ *
+ * @param path Node path
+ * @param data New node data
+ */
+ <T extends DataObject> void put(InstanceIdentifier<T> path, T data);
+
+ @Override
+ void close();
+}
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/Context.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/ModificationCache.java
index b60963678..cb2d4fde0 100644
--- a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/Context.java
+++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/ModificationCache.java
@@ -22,11 +22,11 @@ import java.util.HashMap;
/**
* Simple context class that provides transient storage during one or more read/write operations
*/
-public class Context implements AutoCloseable {
+public class ModificationCache implements AutoCloseable {
protected final HashMap<Object, Object> map;
- public Context() {
+ public ModificationCache() {
map = Maps.newHashMap();
}
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/ModificationContext.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/ModificationContext.java
new file mode 100644
index 000000000..2c039aba0
--- /dev/null
+++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/ModificationContext.java
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+import javax.annotation.Nonnull;
+
+/**
+ * Common context for both writes and reads
+ */
+public interface ModificationContext extends AutoCloseable {
+
+ /**
+ * Get key value transient storage for customizers. Is cleared for each new transaction.
+ *
+ * @return Context for customizers
+ */
+ @Nonnull
+ ModificationCache getModificationCache();
+
+ /**
+ * Get persistent storage for mapping context. This context survives a modification.
+ *
+ * @return Mapping context accessor
+ */
+ @Nonnull
+ MappingContext getMappingContext();
+
+ @Override
+ void close();
+}
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ReadContext.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ReadContext.java
index 6b1473548..e3ddd420c 100644
--- a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ReadContext.java
+++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/read/ReadContext.java
@@ -16,22 +16,11 @@
package io.fd.honeycomb.v3po.translate.read;
-import io.fd.honeycomb.v3po.translate.Context;
-import javax.annotation.Nonnull;
+import io.fd.honeycomb.v3po.translate.ModificationContext;
/**
- * Read Context
+ * Context providing information about current state of DataTree to readers
*/
-public interface ReadContext extends AutoCloseable {
+public interface ReadContext extends ModificationContext {
- /**
- * Get key value storage for customizers
- *
- * @return Context for customizers
- */
- @Nonnull
- Context getContext();
-
- @Override
- void close();
}
diff --git a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriteContext.java b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriteContext.java
index bb0b33145..3433b3f34 100644
--- a/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriteContext.java
+++ b/v3po/translate-api/src/main/java/io/fd/honeycomb/v3po/translate/write/WriteContext.java
@@ -18,7 +18,7 @@ package io.fd.honeycomb.v3po.translate.write;
import com.google.common.annotations.Beta;
import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.ModificationContext;
import javax.annotation.Nonnull;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -27,34 +27,24 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
* Context providing information about current state of DataTree to writers
*/
@Beta
-public interface WriteContext extends AutoCloseable {
+public interface WriteContext extends ModificationContext {
/**
- * Read any data object before current modification was applied
+ * Read any config data object before current modification was applied
*
* @param currentId Id of an object to read
*
* @return Data before the modification was applied
*/
- Optional<DataObject> readBefore(@Nonnull final InstanceIdentifier<? extends DataObject> currentId);
+ <T extends DataObject> Optional<T> readBefore(@Nonnull final InstanceIdentifier<T> currentId);
/**
- * Read any data object from current modification
+ * Read any config data object from current modification
*
* @param currentId Id of an object to read
*
* @return Data from the modification
*/
- Optional<DataObject> readAfter(@Nonnull final InstanceIdentifier<? extends DataObject> currentId);
+ <T extends DataObject> Optional<T> readAfter(@Nonnull final InstanceIdentifier<T> currentId);
- /**
- * Get key value storage for customizers
- *
- * @return Context for customizers
- */
- @Nonnull
- Context getContext();
-
- @Override
- void close();
}
diff --git a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeChildReader.java b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeChildReader.java
index 1984cd86d..89f9f5675 100644
--- a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeChildReader.java
+++ b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeChildReader.java
@@ -93,7 +93,7 @@ public final class CompositeChildReader<C extends DataObject, B extends Builder<
*/
public CompositeChildReader(@Nonnull final Class<C> managedDataObjectType,
@Nonnull final ChildReaderCustomizer<C, B> customizer) {
- this(managedDataObjectType, RWUtils.<C>emptyChildReaderList(), RWUtils.<C>emptyAugReaderList(),
+ this(managedDataObjectType, RWUtils.emptyChildReaderList(), RWUtils.emptyAugReaderList(),
customizer);
}
@@ -112,7 +112,7 @@ public final class CompositeChildReader<C extends DataObject, B extends Builder<
protected void readCurrentAttributes(@Nonnull final InstanceIdentifier<C> id, @Nonnull final B builder,
@Nonnull final ReadContext ctx)
throws ReadFailedException {
- customizer.readCurrentAttributes(id, builder, ctx.getContext());
+ customizer.readCurrentAttributes(id, builder, ctx);
}
@Override
diff --git a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeListReader.java b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeListReader.java
index 4c84c3afe..7c438f669 100644
--- a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeListReader.java
+++ b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeListReader.java
@@ -124,7 +124,7 @@ public final class CompositeListReader<C extends DataObject & Identifiable<K>, K
public List<C> readList(@Nonnull final InstanceIdentifier<C> id,
@Nonnull final ReadContext ctx) throws ReadFailedException {
LOG.trace("{}: Reading all list entries", this);
- final List<K> allIds = customizer.getAllIds(id, ctx.getContext());
+ final List<K> allIds = customizer.getAllIds(id, ctx);
LOG.debug("{}: Reading list entries for: {}", this, allIds);
final ArrayList<C> allEntries = new ArrayList<>(allIds.size());
@@ -146,7 +146,7 @@ public final class CompositeListReader<C extends DataObject & Identifiable<K>, K
protected void readCurrentAttributes(@Nonnull final InstanceIdentifier<C> id, @Nonnull final B builder,
@Nonnull final ReadContext ctx)
throws ReadFailedException {
- customizer.readCurrentAttributes(id, builder, ctx.getContext());
+ customizer.readCurrentAttributes(id, builder, ctx);
}
@Override
diff --git a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeRootReader.java b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeRootReader.java
index 0abae70be..ea157aafd 100644
--- a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeRootReader.java
+++ b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/read/CompositeRootReader.java
@@ -99,7 +99,7 @@ public final class CompositeRootReader<C extends DataObject, B extends Builder<C
@Override
protected void readCurrentAttributes(@Nonnull final InstanceIdentifier<C> id, @Nonnull final B builder,
@Nonnull final ReadContext ctx) throws ReadFailedException {
- customizer.readCurrentAttributes(id, builder, ctx.getContext());
+ customizer.readCurrentAttributes(id, builder, ctx);
}
@Override
diff --git a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/AbstractCompositeWriter.java b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/AbstractCompositeWriter.java
index 580910e8c..8b42a6c6f 100644
--- a/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/AbstractCompositeWriter.java
+++ b/v3po/translate-impl/src/main/java/io/fd/honeycomb/v3po/translate/impl/write/AbstractCompositeWriter.java
@@ -232,7 +232,7 @@ public abstract class AbstractCompositeWriter<D extends DataObject> implements W
// If there's no dedicated writer, use write current
// But we need current data after to do so
final InstanceIdentifier<D> currentId = RWUtils.cutId(id, getManagedDataObjectType());
- Optional<DataObject> currentDataAfter = ctx.readAfter(currentId);
+ Optional<D> currentDataAfter = ctx.readAfter(currentId);
LOG.debug("{}: Dedicated subtree writer missing for: {}. Writing current.", this,
RWUtils.getNextId(id, getManagedDataObjectType()).getType(), currentDataAfter);
writeCurrent(currentId, castToManaged(currentDataAfter.get()), ctx);
@@ -260,8 +260,8 @@ public abstract class AbstractCompositeWriter<D extends DataObject> implements W
private void updateSubtreeFromCurrent(final InstanceIdentifier<? extends DataObject> id, final WriteContext ctx)
throws WriteFailedException {
final InstanceIdentifier<D> currentId = RWUtils.cutId(id, getManagedDataObjectType());
- Optional<DataObject> currentDataBefore = ctx.readBefore(currentId);
- Optional<DataObject> currentDataAfter = ctx.readAfter(currentId);
+ Optional<D> currentDataBefore = ctx.readBefore(currentId);
+ Optional<D> currentDataAfter = ctx.readAfter(currentId);
LOG.debug("{}: Dedicated subtree writer missing for: {}. Updating current without subtree", this,
RWUtils.getNextId(id, getManagedDataObjectType()).getType(), currentDataAfter);
updateCurrent((InstanceIdentifier<D>) id, castToManaged(currentDataBefore.orNull()),
diff --git a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ListReaderCustomizer.java b/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ListReaderCustomizer.java
index 857743e02..4a2e02cfb 100644
--- a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ListReaderCustomizer.java
+++ b/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/ListReaderCustomizer.java
@@ -17,7 +17,7 @@
package io.fd.honeycomb.v3po.translate.spi.read;
import com.google.common.annotations.Beta;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import java.util.List;
import javax.annotation.Nonnull;
@@ -46,7 +46,7 @@ public interface ListReaderCustomizer<C extends DataObject & Identifiable<K>, K
* @throws ReadFailedException if the list of IDs could not be read
*/
@Nonnull
- List<K> getAllIds(@Nonnull final InstanceIdentifier<C> id, @Nonnull final Context context) throws
+ List<K> getAllIds(@Nonnull final InstanceIdentifier<C> id, @Nonnull final ReadContext context) throws
ReadFailedException;
// TODO does it make sense with vpp APIs ? Should we replace it with a simple readAll ?
diff --git a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/RootReaderCustomizer.java b/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/RootReaderCustomizer.java
index da599eb58..f0cb76860 100644
--- a/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/RootReaderCustomizer.java
+++ b/v3po/translate-spi/src/main/java/io/fd/honeycomb/v3po/translate/spi/read/RootReaderCustomizer.java
@@ -17,8 +17,8 @@
package io.fd.honeycomb.v3po.translate.spi.read;
import com.google.common.annotations.Beta;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
-import io.fd.honeycomb.v3po.translate.Context;
import javax.annotation.Nonnull;
import org.opendaylight.yangtools.concepts.Builder;
import org.opendaylight.yangtools.yang.binding.DataObject;
@@ -45,8 +45,9 @@ public interface RootReaderCustomizer<C extends DataObject, B extends Builder<C>
*
* @param id id of current data object
* @param builder builder for creating read value
+ * @param ctx
* @throws ReadFailedException if read was unsuccessful
*/
void readCurrentAttributes(@Nonnull final InstanceIdentifier<C> id, @Nonnull final B builder,
- @Nonnull final Context ctx) throws ReadFailedException;
+ @Nonnull final ReadContext ctx) throws ReadFailedException;
}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/NoopReaderCustomizer.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/NoopReaderCustomizer.java
index 3b703da3f..cf494efbe 100644
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/NoopReaderCustomizer.java
+++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/read/NoopReaderCustomizer.java
@@ -16,7 +16,7 @@
package io.fd.honeycomb.v3po.translate.util.read;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
import org.opendaylight.yangtools.concepts.Builder;
@@ -27,7 +27,7 @@ public abstract class NoopReaderCustomizer<C extends DataObject, B extends Build
RootReaderCustomizer<C, B> {
@Override
- public void readCurrentAttributes(InstanceIdentifier<C> id, final B builder, final Context context) throws
+ public void readCurrentAttributes(InstanceIdentifier<C> id, final B builder, final ReadContext context) throws
ReadFailedException {
// Noop
}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionMappingContext.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionMappingContext.java
new file mode 100644
index 000000000..60f4282f5
--- /dev/null
+++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionMappingContext.java
@@ -0,0 +1,75 @@
+/*
+ * 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.write;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import io.fd.honeycomb.v3po.translate.MappingContext;
+import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Binding Transaction backed mapping context
+ */
+public class TransactionMappingContext implements MappingContext {
+
+ private final ReadWriteTransaction readWriteTransaction;
+
+ // TODO make async
+
+ public TransactionMappingContext(final ReadWriteTransaction readWriteTransaction) {
+ this.readWriteTransaction = readWriteTransaction;
+ }
+
+ @Override
+ public <T extends DataObject> Optional<T> read(@Nonnull final InstanceIdentifier<T> currentId) {
+ try {
+ return readWriteTransaction.read(LogicalDatastoreType.OPERATIONAL, currentId).checkedGet();
+ } catch (ReadFailedException e) {
+ throw new IllegalStateException("Unable to perform read", e);
+ }
+ }
+
+ @Override
+ public void delete(final InstanceIdentifier<?> path) {
+ readWriteTransaction.delete(LogicalDatastoreType.OPERATIONAL, path);
+ }
+
+ @Override
+ public <T extends DataObject> void merge(final InstanceIdentifier<T> path, T data) {
+ readWriteTransaction.merge(LogicalDatastoreType.OPERATIONAL, path, data, true);
+ }
+
+ @Override
+ public <T extends DataObject> void put(final InstanceIdentifier<T> path, T data) {
+ readWriteTransaction.put(LogicalDatastoreType.OPERATIONAL, path, data, true);
+ }
+
+ public CheckedFuture<Void, TransactionCommitFailedException> submit() {
+ return readWriteTransaction.submit();
+ }
+
+ @Override
+ public void close() {
+ readWriteTransaction.cancel();
+ }
+}
diff --git a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionWriteContext.java b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionWriteContext.java
index 37756d5b8..20bbf19e0 100644
--- a/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionWriteContext.java
+++ b/v3po/translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/util/write/TransactionWriteContext.java
@@ -16,9 +16,12 @@
package io.fd.honeycomb.v3po.translate.util.write;
+import static com.google.common.base.Preconditions.checkState;
+
import com.google.common.base.Optional;
import com.google.common.util.concurrent.CheckedFuture;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.MappingContext;
+import io.fd.honeycomb.v3po.translate.ModificationCache;
import io.fd.honeycomb.v3po.translate.write.WriteContext;
import java.util.Map;
import javax.annotation.Nonnull;
@@ -38,27 +41,37 @@ public final class TransactionWriteContext implements WriteContext {
private final DOMDataReadOnlyTransaction beforeTx;
private final DOMDataReadOnlyTransaction afterTx;
- private final Context ctx;
+ private final ModificationCache ctx;
private final BindingNormalizedNodeSerializer serializer;
+ private MappingContext mappingContext;
public TransactionWriteContext(final BindingNormalizedNodeSerializer serializer,
final DOMDataReadOnlyTransaction beforeTx,
- final DOMDataReadOnlyTransaction afterTx) {
+ final DOMDataReadOnlyTransaction afterTx,
+ final MappingContext mappingContext) {
this.serializer = serializer;
+ // TODO do we have a BA transaction adapter ? If so, use it here and don't pass serializer
this.beforeTx = beforeTx;
this.afterTx = afterTx;
- this.ctx = new Context();
+ this.mappingContext = mappingContext;
+ this.ctx = new ModificationCache();
}
// TODO make this asynchronous
@Override
- public Optional<DataObject> readBefore(@Nonnull final InstanceIdentifier<? extends DataObject> currentId) {
+ public <T extends DataObject> Optional<T> readBefore(@Nonnull final InstanceIdentifier<T> currentId) {
return read(currentId, beforeTx);
}
- private Optional<DataObject> read(final InstanceIdentifier<? extends DataObject> currentId,
- final DOMDataReadOnlyTransaction tx) {
+ @Override
+ public <T extends DataObject> Optional<T> readAfter(@Nonnull final InstanceIdentifier<T> currentId) {
+ return read(currentId, afterTx);
+ }
+
+
+ private <T extends DataObject> Optional<T> read(final InstanceIdentifier<T> currentId,
+ final DOMDataReadOnlyTransaction tx) {
final YangInstanceIdentifier path = serializer.toYangInstanceIdentifier(currentId);
final CheckedFuture<Optional<NormalizedNode<?, ?>>, ReadFailedException> read =
@@ -75,20 +88,25 @@ public final class TransactionWriteContext implements WriteContext {
final NormalizedNode<?, ?> data = optional.get();
final Map.Entry<InstanceIdentifier<?>, DataObject> entry = serializer.fromNormalizedNode(path, data);
- return Optional.of(entry.getValue());
+ final Class<T> targetType = currentId.getTargetType();
+ checkState(targetType.isAssignableFrom(entry.getValue().getClass()),
+ "Unexpected data object type, should be: %s, but was: %s", targetType, entry.getValue().getClass());
+ return Optional.of(targetType.cast(entry.getValue()));
} catch (ReadFailedException e) {
throw new IllegalStateException("Unable to perform read", e);
}
}
+ @Nonnull
@Override
- public Optional<DataObject> readAfter(@Nonnull final InstanceIdentifier<? extends DataObject> currentId) {
- return read(currentId, afterTx);
+ public ModificationCache getModificationCache() {
+ return ctx;
}
+ @Nonnull
@Override
- public Context getContext() {
- return ctx;
+ public MappingContext getMappingContext() {
+ return mappingContext;
}
/**
@@ -97,5 +115,7 @@ public final class TransactionWriteContext implements WriteContext {
@Override
public void close() {
ctx.close();
+ beforeTx.close();
+ afterTx.close();
}
}
diff --git a/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/impl/write/util/TransactionWriteContextTest.java b/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/impl/write/util/TransactionWriteContextTest.java
index 03dc0c200..8a3bfbdd9 100644
--- a/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/impl/write/util/TransactionWriteContextTest.java
+++ b/v3po/translate-utils/src/test/java/io/fd/honeycomb/v3po/translate/impl/write/util/TransactionWriteContextTest.java
@@ -29,7 +29,8 @@ import static org.mockito.MockitoAnnotations.initMocks;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.CheckedFuture;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.MappingContext;
+import io.fd.honeycomb.v3po.translate.ModificationCache;
import io.fd.honeycomb.v3po.translate.util.write.TransactionWriteContext;
import java.util.Map;
import org.junit.Before;
@@ -43,7 +44,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain;
import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer;
-import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -62,13 +62,15 @@ public class TransactionWriteContextTest {
private Optional<org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode<?, ?>> optional;
@Mock
private Map.Entry entry;
+ @Mock
+ private MappingContext contextBroker;
private TransactionWriteContext transactionWriteContext;
@Before
public void setUp() {
initMocks(this);
- transactionWriteContext = new TransactionWriteContext(serializer, beforeTx, afterTx);
+ transactionWriteContext = new TransactionWriteContext(serializer, beforeTx, afterTx, contextBroker);
}
@Test
@@ -80,7 +82,7 @@ public class TransactionWriteContextTest {
final InstanceIdentifier<BridgeDomain> instanceId =
InstanceIdentifier.create(Vpp.class).child(BridgeDomains.class).child(BridgeDomain.class);
- final Optional<DataObject> dataObjects = transactionWriteContext.readBefore(instanceId);
+ final Optional<BridgeDomain> dataObjects = transactionWriteContext.readBefore(instanceId);
assertNotNull(dataObjects);
assertFalse(dataObjects.isPresent());
@@ -101,9 +103,9 @@ public class TransactionWriteContextTest {
BridgeDomains.QNAME).node(BridgeDomain.QNAME).build();
when(serializer.toYangInstanceIdentifier(any(InstanceIdentifier.class))).thenReturn(yangId);
when(serializer.fromNormalizedNode(eq(yangId), any(NormalizedNode.class))).thenReturn(entry);
- when(entry.getValue()).thenReturn(mock(DataObject.class));
+ when(entry.getValue()).thenReturn(mock(BridgeDomain.class));
- final Optional<DataObject> dataObjects = transactionWriteContext.readBefore(instanceId);
+ final Optional<BridgeDomain> dataObjects = transactionWriteContext.readBefore(instanceId);
assertNotNull(dataObjects);
assertTrue(dataObjects.isPresent());
@@ -127,12 +129,12 @@ public class TransactionWriteContextTest {
@Test
public void testGetContext() throws Exception {
- assertNotNull(transactionWriteContext.getContext());
+ assertNotNull(transactionWriteContext.getModificationCache());
}
@Test
public void testClose() throws Exception {
- final Context context = transactionWriteContext.getContext();
+ final ModificationCache context = transactionWriteContext.getModificationCache();
transactionWriteContext.close();
// TODO verify context was closed
}
diff --git a/v3po/v3po2vpp/src/main/config/default-config.xml b/v3po/v3po2vpp/src/main/config/default-config.xml
index 02b0b7b89..be45a291b 100644
--- a/v3po/v3po2vpp/src/main/config/default-config.xml
+++ b/v3po/v3po2vpp/src/main/config/default-config.xml
@@ -32,19 +32,11 @@
<type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context-impl</type>
<name>interface-context</name>
<artificial-name-prefix>interface-</artificial-name-prefix>
- <context-data-tree>
- <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:data-tree</type>
- <name>inmemory-persisted-context-data-tree</name>
- </context-data-tree>
</module>
<module>
<type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:util">prefix:naming-context-impl</type>
<name>bridge-domain-context</name>
<artificial-name-prefix>bridge-domain-</artificial-name-prefix>
- <context-data-tree>
- <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:data-tree</type>
- <name>inmemory-persisted-context-data-tree</name>
- </context-data-tree>
</module>
<module>
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java
index e6ed62acf..eb6426241 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java
@@ -57,7 +57,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWri
throws WriteFailedException {
try {
- setInterface(id, dataAfter);
+ setInterface(id, dataAfter, writeContext);
} catch (VppApiInvocationException e) {
LOG.warn("Update of VppInterfaceAugment failed", e);
throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
@@ -72,7 +72,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWri
throws WriteFailedException.UpdateFailedException {
try {
- updateInterface(id, dataBefore, dataAfter);
+ updateInterface(id, dataBefore, dataAfter, writeContext);
} catch (VppApiInvocationException e) {
LOG.warn("Update of VppInterfaceAugment failed", e);
throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
@@ -95,25 +95,25 @@ public class InterfaceCustomizer extends FutureJVppCustomizer implements ListWri
}
- private void setInterface(final InstanceIdentifier<Interface> id, final Interface swIf)
+ private void setInterface(final InstanceIdentifier<Interface> id, final Interface swIf,
+ final WriteContext writeContext)
throws VppApiInvocationException, WriteFailedException {
LOG.debug("Setting interface: {} to: {}", id, swIf);
- setInterfaceAttributes(swIf, swIf.getName());
+ setInterfaceAttributes(swIf, swIf.getName(), writeContext);
}
- private void setInterfaceAttributes(final Interface swIf, final String swIfName)
+ private void setInterfaceAttributes(final Interface swIf, final String swIfName, final WriteContext writeContext)
throws VppApiInvocationException {
- setInterfaceFlags(swIfName, interfaceContext.getIndex(swIfName),
+ setInterfaceFlags(swIfName, interfaceContext.getIndex(swIfName, writeContext.getMappingContext()),
swIf.isEnabled() ? (byte) 1 : (byte) 0);
}
private void updateInterface(final InstanceIdentifier<Interface> id,
final Interface dataBefore,
- final Interface dataAfter) throws VppApiInvocationException {
+ final Interface dataAfter, final WriteContext writeContext) throws VppApiInvocationException {
LOG.debug("Updating interface:{} to: {}", id, dataAfter);
-
- setInterfaceAttributes(dataAfter, dataAfter.getName());
+ setInterfaceAttributes(dataAfter, dataAfter.getName(), writeContext);
}
private void setInterfaceFlags(final String swIfName, final int swIfIndex, final byte enabled)
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java
index fc43cdb7e..5aea5de2b 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java
@@ -69,9 +69,9 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCus
throws WriteFailedException {
final String ifcName = id.firstKeyOf(Interface.class).getName();
- final int swIfc = interfaceContext.getIndex(ifcName);
+ final int swIfc = interfaceContext.getIndex(ifcName, writeContext.getMappingContext());
try {
- setL2(id, swIfc, ifcName, dataAfter);
+ setL2(id, swIfc, ifcName, dataAfter, writeContext);
} catch (VppApiInvocationException e) {
LOG.warn("Write of L2 failed", e);
throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
@@ -84,10 +84,10 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCus
throws WriteFailedException {
final String ifcName = id.firstKeyOf(Interface.class).getName();
- final int swIfc = interfaceContext.getIndex(ifcName);
+ final int swIfc = interfaceContext.getIndex(ifcName, writeContext.getMappingContext());
// TODO handle update properly (if possible)
try {
- setL2(id, swIfc, ifcName, dataAfter);
+ setL2(id, swIfc, ifcName, dataAfter, writeContext);
} catch (VppApiInvocationException e) {
LOG.warn("Update of L2 failed", e);
throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
@@ -100,21 +100,22 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCus
// TODO implement delete (if possible)
}
- private void setL2(final InstanceIdentifier<L2> id, final int swIfIndex, final String ifcName, final L2 vppL2)
+ private void setL2(final InstanceIdentifier<L2> id, final int swIfIndex, final String ifcName, final L2 vppL2,
+ final WriteContext writeContext)
throws VppApiInvocationException, WriteFailedException {
LOG.debug("Setting L2 for interface: {}", ifcName);
// Nothing besides interconnection here
- setInterconnection(id, swIfIndex, ifcName, vppL2);
+ setInterconnection(id, swIfIndex, ifcName, vppL2, writeContext);
}
private void setInterconnection(final InstanceIdentifier<L2> id, final int swIfIndex, final String ifcName,
- final L2 vppL2)
+ final L2 vppL2, final WriteContext writeContext)
throws VppApiInvocationException, WriteFailedException {
Interconnection ic = vppL2.getInterconnection();
if (ic instanceof XconnectBased) {
- setXconnectBasedL2(swIfIndex, ifcName, (XconnectBased) ic);
+ setXconnectBasedL2(swIfIndex, ifcName, (XconnectBased) ic, writeContext);
} else if (ic instanceof BridgeBased) {
- setBridgeBasedL2(swIfIndex, ifcName, (BridgeBased) ic);
+ setBridgeBasedL2(swIfIndex, ifcName, (BridgeBased) ic, writeContext);
} else {
// FIXME how does choice extensibility work
// FIXME it is not even possible to create a dedicated customizer for Interconnection, since it's not a DataObject
@@ -125,7 +126,8 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCus
}
}
- private void setBridgeBasedL2(final int swIfIndex, final String ifcName, final BridgeBased bb)
+ private void setBridgeBasedL2(final int swIfIndex, final String ifcName, final BridgeBased bb,
+ final WriteContext writeContext)
throws VppApiInvocationException {
LOG.debug("Setting bridge based interconnection(bridge-domain={}) for interface: {}",
@@ -133,7 +135,7 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCus
String bdName = bb.getBridgeDomain();
- int bdId = bridgeDomainContext.getIndex(bdName);
+ int bdId = bridgeDomainContext.getIndex(bdName, writeContext.getMappingContext());
checkArgument(bdId > 0, "Unable to set Interconnection for Interface: %s, bridge domain: %s does not exist",
ifcName, bdName);
@@ -168,14 +170,15 @@ public class L2Customizer extends FutureJVppCustomizer implements ChildWriterCus
return swInterfaceSetL2Bridge;
}
- private void setXconnectBasedL2(final int swIfIndex, final String ifcName, final XconnectBased ic)
+ private void setXconnectBasedL2(final int swIfIndex, final String ifcName, final XconnectBased ic,
+ final WriteContext writeContext)
throws VppApiInvocationException {
String outSwIfName = ic.getXconnectOutgoingInterface();
LOG.debug("Setting xconnect based interconnection(outgoing ifc={}) for interface: {}", outSwIfName,
ifcName);
- int outSwIfIndex = interfaceContext.getIndex(outSwIfName);
+ int outSwIfIndex = interfaceContext.getIndex(outSwIfName, writeContext.getMappingContext());
checkArgument(outSwIfIndex > 0,
"Unable to set Interconnection for Interface: %s, outgoing interface: %s does not exist",
ifcName, outSwIfIndex);
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java
index 4d17ba098..bf355e479 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java
@@ -60,7 +60,7 @@ public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWrit
throws WriteFailedException.CreateFailedException {
try {
- setRouting(id.firstKeyOf(Interface.class).getName(), dataAfter);
+ setRouting(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext);
} catch (VppApiInvocationException e) {
LOG.warn("Update of Routing failed", e);
throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
@@ -75,7 +75,7 @@ public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWrit
try {
// TODO handle updates properly
- setRouting(id.firstKeyOf(Interface.class).getName(), dataAfter);
+ setRouting(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext);
} catch (VppApiInvocationException e) {
LOG.warn("Update of Routing failed", e);
throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
@@ -88,8 +88,8 @@ public class RoutingCustomizer extends FutureJVppCustomizer implements ChildWrit
// TODO implement delete
}
- private void setRouting(final String name, final Routing rt) throws VppApiInvocationException {
- final int swIfc = interfaceContext.getIndex(name);
+ private void setRouting(final String name, final Routing rt, final WriteContext writeContext) throws VppApiInvocationException {
+ final int swIfc = interfaceContext.getIndex(name, writeContext.getMappingContext());
LOG.debug("Setting routing for interface: {}, {}. Routing: {}", name, swIfc, rt);
int vrfId = (rt != null)
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java
index ecf2337e8..fb47b6a9f 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizer.java
@@ -75,15 +75,16 @@ public class SubInterfaceCustomizer extends AbstractInterfaceTypeCustomizer<SubI
@Nonnull final SubInterface dataAfter, @Nonnull final WriteContext writeContext)
throws WriteFailedException.CreateFailedException {
try {
- createSubInterface(id.firstKeyOf(Interface.class).getName(), dataAfter);
+ createSubInterface(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext);
} catch (VppApiInvocationException e) {
throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
}
}
- private void createSubInterface(final String swIfName, final SubInterface subInterface) throws VppApiInvocationException {
+ private void createSubInterface(final String swIfName, final SubInterface subInterface,
+ final WriteContext writeContext) throws VppApiInvocationException {
final String superIfName = subInterface.getSuperInterface();
- final int swIfIndex = interfaceContext.getIndex(superIfName);
+ final int swIfIndex = interfaceContext.getIndex(superIfName, writeContext.getMappingContext());
LOG.debug("Creating sub interface of {}(id={}): name={}, subInterface={}", superIfName, swIfIndex, swIfName, subInterface);
final CompletionStage<CreateSubifReply> createSubifReplyCompletionStage =
getFutureJVpp().createSubif(getCreateSubifRequest(subInterface, swIfIndex));
@@ -96,7 +97,7 @@ public class SubInterfaceCustomizer extends AbstractInterfaceTypeCustomizer<SubI
} else {
LOG.debug("Sub interface created successfully for: {}, subInterface: {}", swIfName, subInterface);
// Add new interface to our interface context
- interfaceContext.addName(reply.swIfIndex, swIfName);
+ interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext());
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizer.java
index 72679fe12..bafe788ad 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizer.java
@@ -69,7 +69,7 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer<Tap> {
@Nonnull final WriteContext writeContext)
throws WriteFailedException.CreateFailedException {
try {
- createTap(id.firstKeyOf(Interface.class).getName(), dataAfter);
+ createTap(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext);
} catch (VppApiInvocationException e) {
LOG.warn("Write of Tap failed", e);
throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
@@ -84,7 +84,7 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer<Tap> {
final int index;
try {
- index = interfaceContext.getIndex(ifcName);
+ index = interfaceContext.getIndex(ifcName, writeContext.getMappingContext());
} catch (IllegalArgumentException e) {
throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
}
@@ -105,20 +105,20 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer<Tap> {
final int index;
try {
- index = interfaceContext.getIndex(ifcName);
+ index = interfaceContext.getIndex(ifcName, writeContext.getMappingContext());
} catch (IllegalArgumentException e) {
throw new WriteFailedException.DeleteFailedException(id, e);
}
try {
- deleteTap(ifcName, index, dataBefore);
+ deleteTap(ifcName, index, dataBefore, writeContext);
} catch (VppApiInvocationException e) {
LOG.warn("Delete of Tap failed", e);
throw new WriteFailedException.DeleteFailedException(id, e);
}
}
- private void createTap(final String swIfName, final Tap tap) throws VppApiInvocationException {
+ private void createTap(final String swIfName, final Tap tap, final WriteContext writeContext) throws VppApiInvocationException {
LOG.debug("Setting tap interface: {}. Tap: {}", swIfName, tap);
final CompletionStage<TapConnectReply> tapConnectFuture =
getFutureJVpp().tapConnect(getTapConnectRequest(tap.getTapName(), tap.getMac(), tap.getDeviceInstance()));
@@ -130,7 +130,7 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer<Tap> {
} else {
LOG.debug("Tap set successfully for: {}, tap: {}", swIfName, tap);
// Add new interface to our interface context
- interfaceContext.addName(reply.swIfIndex, swIfName);
+ interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext());
}
}
@@ -148,7 +148,8 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer<Tap> {
}
}
- private void deleteTap(final String swIfName, final int index, final Tap dataBefore)
+ private void deleteTap(final String swIfName, final int index, final Tap dataBefore,
+ final WriteContext writeContext)
throws VppApiInvocationException {
LOG.debug("Deleting tap interface: {}. Tap: {}", swIfName, dataBefore);
final CompletionStage<TapDeleteReply> vxlanAddDelTunnelReplyCompletionStage =
@@ -161,7 +162,7 @@ public class TapCustomizer extends AbstractInterfaceTypeCustomizer<Tap> {
} else {
LOG.debug("Tap deleted successfully for: {}, tap: {}", swIfName, dataBefore);
// Remove deleted interface from interface context
- interfaceContext.removeName(swIfName);
+ interfaceContext.removeName(swIfName, writeContext.getMappingContext());
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizer.java
index ebefff34a..5f7d626e8 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizer.java
@@ -73,13 +73,13 @@ public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer<VhostUs
@Nonnull final VhostUser dataAfter, @Nonnull final WriteContext writeContext)
throws WriteFailedException.CreateFailedException {
try {
- createVhostUserIf(id.firstKeyOf(Interface.class).getName(), dataAfter);
+ createVhostUserIf(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext);
} catch (VppApiInvocationException | IllegalInterfaceTypeException e) {
throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
}
}
- private void createVhostUserIf(final String swIfName, final VhostUser vhostUser) throws VppApiInvocationException {
+ private void createVhostUserIf(final String swIfName, final VhostUser vhostUser, final WriteContext writeContext) throws VppApiInvocationException {
LOG.debug("Creating vhost user interface: name={}, vhostUser={}", swIfName, vhostUser);
final CompletionStage<CreateVhostUserIfReply> createVhostUserIfReplyCompletionStage =
getFutureJVpp().createVhostUserIf(getCreateVhostUserIfRequest(vhostUser));
@@ -92,7 +92,7 @@ public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer<VhostUs
} else {
LOG.debug("Vhost user interface created successfully for: {}, vhostUser: {}", swIfName, vhostUser);
// Add new interface to our interface context
- interfaceContext.addName(reply.swIfIndex, swIfName);
+ interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext());
}
}
@@ -118,17 +118,17 @@ public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer<VhostUs
}
try {
- modifyVhostUserIf(id.firstKeyOf(Interface.class).getName(), dataAfter);
+ modifyVhostUserIf(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext);
} catch (VppApiInvocationException e) {
throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
}
}
- private void modifyVhostUserIf(final String swIfName, final VhostUser vhostUser) throws VppApiInvocationException {
+ private void modifyVhostUserIf(final String swIfName, final VhostUser vhostUser, final WriteContext writeContext) throws VppApiInvocationException {
LOG.debug("Updating vhost user interface: name={}, vhostUser={}", swIfName, vhostUser);
final CompletionStage<ModifyVhostUserIfReply> modifyVhostUserIfReplyCompletionStage =
getFutureJVpp()
- .modifyVhostUserIf(getModifyVhostUserIfRequest(vhostUser, interfaceContext.getIndex(swIfName)));
+ .modifyVhostUserIf(getModifyVhostUserIfRequest(vhostUser, interfaceContext.getIndex(swIfName, writeContext.getMappingContext())));
final ModifyVhostUserIfReply reply =
V3poUtils.getReply(modifyVhostUserIfReplyCompletionStage.toCompletableFuture());
@@ -155,16 +155,16 @@ public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer<VhostUs
@Nonnull final VhostUser dataBefore, @Nonnull final WriteContext writeContext)
throws WriteFailedException.DeleteFailedException {
try {
- deleteVhostUserIf(id.firstKeyOf(Interface.class).getName(), dataBefore);
+ deleteVhostUserIf(id.firstKeyOf(Interface.class).getName(), dataBefore, writeContext);
} catch (VppApiInvocationException e) {
throw new WriteFailedException.DeleteFailedException(id, e);
}
}
- private void deleteVhostUserIf(final String swIfName, final VhostUser vhostUser) throws VppApiInvocationException {
+ private void deleteVhostUserIf(final String swIfName, final VhostUser vhostUser, final WriteContext writeContext) throws VppApiInvocationException {
LOG.debug("Deleting vhost user interface: name={}, vhostUser={}", swIfName, vhostUser);
final CompletionStage<DeleteVhostUserIfReply> deleteVhostUserIfReplyCompletionStage =
- getFutureJVpp().deleteVhostUserIf(getDeleteVhostUserIfRequest(interfaceContext.getIndex(swIfName)));
+ getFutureJVpp().deleteVhostUserIf(getDeleteVhostUserIfRequest(interfaceContext.getIndex(swIfName, writeContext.getMappingContext())));
final DeleteVhostUserIfReply reply =
V3poUtils.getReply(deleteVhostUserIfReplyCompletionStage.toCompletableFuture());
@@ -174,7 +174,7 @@ public class VhostUserCustomizer extends AbstractInterfaceTypeCustomizer<VhostUs
} else {
LOG.debug("Vhost user interface deleted successfully for: {}, vhostUser: {}", swIfName, vhostUser);
// Remove interface from our interface context
- interfaceContext.removeName(swIfName);
+ interfaceContext.removeName(swIfName, writeContext.getMappingContext());
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VlanTagRewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VlanTagRewriteCustomizer.java
index 7e7e319eb..d1e55a0a0 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VlanTagRewriteCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VlanTagRewriteCustomizer.java
@@ -70,14 +70,15 @@ public class VlanTagRewriteCustomizer extends FutureJVppCustomizer implements Ch
@Nonnull final VlanTagRewrite dataAfter, @Nonnull final WriteContext writeContext)
throws WriteFailedException.CreateFailedException {
try {
- setTagRewrite(id.firstKeyOf(Interface.class).getName(), dataAfter);
+ setTagRewrite(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext);
} catch (VppApiInvocationException e) {
throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
}
}
- private void setTagRewrite(final String ifname, final VlanTagRewrite cfg) throws VppApiInvocationException {
- final int swIfIndex = interfaceContext.getIndex(ifname);
+ private void setTagRewrite(final String ifname, final VlanTagRewrite cfg, final WriteContext writeContext)
+ throws VppApiInvocationException {
+ final int swIfIndex = interfaceContext.getIndex(ifname, writeContext.getMappingContext());
LOG.debug("Setting tag rewrite for interface {}(id=): {}", ifname, swIfIndex, cfg);
final CompletionStage<L2InterfaceVlanTagRewriteReply> replyCompletionStage =
@@ -121,7 +122,7 @@ public class VlanTagRewriteCustomizer extends FutureJVppCustomizer implements Ch
return;
}
try {
- setTagRewrite(id.firstKeyOf(Interface.class).getName(), dataAfter);
+ setTagRewrite(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext);
} catch (VppApiInvocationException e) {
throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
}
@@ -135,7 +136,7 @@ public class VlanTagRewriteCustomizer extends FutureJVppCustomizer implements Ch
// disable tag rewrite
final VlanTagRewriteBuilder builder = new VlanTagRewriteBuilder();
builder.setRewriteOperation(TagRewriteOperation.Disabled);
- setTagRewrite(id.firstKeyOf(Interface.class).getName(), builder.build());
+ setTagRewrite(id.firstKeyOf(Interface.class).getName(), builder.build(), writeContext);
} catch (VppApiInvocationException e) {
throw new WriteFailedException.DeleteFailedException(id, e);
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java
index 9d11b59b1..3edd531c6 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java
@@ -71,7 +71,7 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> {
@Nonnull final WriteContext writeContext)
throws WriteFailedException.CreateFailedException {
try {
- createVxlanTunnel(id.firstKeyOf(Interface.class).getName(), dataAfter);
+ createVxlanTunnel(id.firstKeyOf(Interface.class).getName(), dataAfter, writeContext);
} catch (VppApiInvocationException | IllegalInterfaceTypeException e) {
LOG.warn("Write of Vxlan failed", e);
throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
@@ -95,14 +95,14 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> {
@Nonnull final WriteContext writeContext)
throws WriteFailedException.DeleteFailedException {
try {
- deleteVxlanTunnel(id.firstKeyOf(Interface.class).getName(), dataBefore);
+ deleteVxlanTunnel(id.firstKeyOf(Interface.class).getName(), dataBefore, writeContext);
} catch (VppApiInvocationException e) {
LOG.warn("Delete of Vxlan tunnel failed", e);
throw new WriteFailedException.DeleteFailedException(id, e);
}
}
- private void createVxlanTunnel(final String swIfName, final Vxlan vxlan) throws VppApiInvocationException {
+ private void createVxlanTunnel(final String swIfName, final Vxlan vxlan, final WriteContext writeContext) throws VppApiInvocationException {
final byte isIpv6 = (byte) (isIpv6(vxlan) ? 1 : 0);
final InetAddress srcAddress = InetAddresses.forString(getAddressString(vxlan.getSrc()));
final InetAddress dstAddress = InetAddresses.forString(getAddressString(vxlan.getDst()));
@@ -123,7 +123,7 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> {
} else {
LOG.debug("Vxlan tunnel set successfully for: {}, vxlan: {}", swIfName, vxlan);
// Add new interface to our interface context
- interfaceContext.addName(reply.swIfIndex, swIfName);
+ interfaceContext.addName(reply.swIfIndex, swIfName, writeContext.getMappingContext());
}
}
@@ -143,7 +143,7 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> {
return addr.getIpv4Address() == null ? addr.getIpv6Address().getValue() : addr.getIpv4Address().getValue();
}
- private void deleteVxlanTunnel(final String swIfName, final Vxlan vxlan) throws VppApiInvocationException {
+ private void deleteVxlanTunnel(final String swIfName, final Vxlan vxlan, final WriteContext writeContext) throws VppApiInvocationException {
final byte isIpv6 = (byte) (isIpv6(vxlan) ? 1 : 0);
final InetAddress srcAddress = InetAddresses.forString(getAddressString(vxlan.getSrc()));
final InetAddress dstAddress = InetAddresses.forString(getAddressString(vxlan.getDst()));
@@ -164,7 +164,7 @@ public class VxlanCustomizer extends AbstractInterfaceTypeCustomizer<Vxlan> {
} else {
LOG.debug("Vxlan tunnel deleted successfully for: {}, vxlan: {}", swIfName, vxlan);
// Remove interface from our interface context
- interfaceContext.removeName(swIfName);
+ interfaceContext.removeName(swIfName, writeContext.getMappingContext());
}
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java
index a54f6c5e3..4deb38f52 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java
@@ -68,7 +68,7 @@ public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterC
throws WriteFailedException {
try {
final String ifcName = id.firstKeyOf(Interface.class).getName();
- setIpv4(id, ifcName, dataAfter);
+ setIpv4(id, ifcName, dataAfter, writeContext);
} catch (VppApiInvocationException e) {
LOG.warn("Create of Ipv4 failed", e);
throw new WriteFailedException.CreateFailedException(id, dataAfter, e);
@@ -84,7 +84,7 @@ public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterC
// TODO handle update in a better way
try {
- setIpv4(id, ifcName, dataAfter);
+ setIpv4(id, ifcName, dataAfter, writeContext);
} catch (VppApiInvocationException e) {
LOG.warn("Update of Ipv4 failed", e);
throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
@@ -97,9 +97,10 @@ public class Ipv4Customizer extends FutureJVppCustomizer implements ChildWriterC
// TODO implement delete
}
- private void setIpv4(final InstanceIdentifier<Ipv4> id, final String name, final Ipv4 ipv4)
+ private void setIpv4(final InstanceIdentifier<Ipv4> id, final String name, final Ipv4 ipv4,
+ final WriteContext writeContext)
throws WriteFailedException, VppApiInvocationException {
- final int swIfc = interfaceContext.getIndex(name);
+ final int swIfc = interfaceContext.getIndex(name, writeContext.getMappingContext());
for (Address ipv4Addr : ipv4.getAddress()) {
Subnet subnet = ipv4Addr.getSubnet();
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java
index 74ea45c11..8173b67ba 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/EthernetCustomizer.java
@@ -16,7 +16,9 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
-import io.fd.honeycomb.v3po.translate.Context;
+import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCustomizer.getCachedInterfaceDump;
+
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
@@ -64,11 +66,11 @@ public class EthernetCustomizer extends FutureJVppCustomizer
@Override
public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Ethernet> id,
@Nonnull final EthernetBuilder builder,
- @Nonnull final Context ctx) throws ReadFailedException {
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
final InterfaceKey key = id.firstKeyOf(Interface.class);
final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key,
- interfaceContext.getIndex(key.getName()), ctx);
+ interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache());
builder.setMtu((int) iface.linkMtu);
switch (iface.linkDuplex) {
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java
index 51d4022d7..87c62f48f 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizer.java
@@ -16,7 +16,8 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.ModificationCache;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
@@ -69,13 +70,13 @@ public class InterfaceCustomizer extends FutureJVppCustomizer
@Override
public void readCurrentAttributes(@Nonnull InstanceIdentifier<Interface> id, @Nonnull InterfaceBuilder builder,
- @Nonnull Context ctx) throws ReadFailedException {
+ @Nonnull ReadContext ctx) throws ReadFailedException {
LOG.debug("Reading attributes for interface: {}", id);
final InterfaceKey key = id.firstKeyOf(id.getTargetType());
// Pass cached details from getAllIds to getDetails to avoid additional dumps
final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key,
- interfaceContext.getIndex(key.getName()), ctx);
+ interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache());
LOG.debug("Interface details for interface: {}, details: {}", key.getName(), iface);
builder.setName(key.getName());
@@ -94,7 +95,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer
@Nonnull
@SuppressWarnings("unchecked")
- public static Map<Integer, SwInterfaceDetails> getCachedInterfaceDump(final @Nonnull Context ctx) {
+ public static Map<Integer, SwInterfaceDetails> getCachedInterfaceDump(final @Nonnull ModificationCache ctx) {
return ctx.get(DUMPED_IFCS_CONTEXT_KEY) == null
? new HashMap<>() // allow customizers to update the cache
: (Map<Integer, SwInterfaceDetails>) ctx.get(DUMPED_IFCS_CONTEXT_KEY);
@@ -103,7 +104,7 @@ public class InterfaceCustomizer extends FutureJVppCustomizer
@Nonnull
@Override
public List<InterfaceKey> getAllIds(@Nonnull final InstanceIdentifier<Interface> id,
- @Nonnull final Context context) throws ReadFailedException {
+ @Nonnull final ReadContext context) throws ReadFailedException {
LOG.trace("Dumping all interfaces to get all IDs");
final SwInterfaceDump request = new SwInterfaceDump();
@@ -120,20 +121,20 @@ public class InterfaceCustomizer extends FutureJVppCustomizer
}
// Cache interfaces dump in per-tx context to later be used in readCurrentAttributes
- context.put(DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream()
+ context.getModificationCache().put(DUMPED_IFCS_CONTEXT_KEY, ifaces.swInterfaceDetails.stream()
.collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails)));
final List<InterfaceKey> interfacesKeys = ifaces.swInterfaceDetails.stream()
.filter(elt -> elt != null)
.map((elt) -> {
// Store interface name from VPP in context if not yet present
- if (!interfaceContext.containsName(elt.swIfIndex)) {
- interfaceContext.addName(elt.swIfIndex, V3poUtils.toString(elt.interfaceName));
+ if (!interfaceContext.containsName(elt.swIfIndex, context.getMappingContext())) {
+ interfaceContext.addName(elt.swIfIndex, V3poUtils.toString(elt.interfaceName), context.getMappingContext());
}
LOG.trace("Interface with name: {}, VPP name: {} and index: {} found in VPP",
- interfaceContext.getName(elt.swIfIndex), elt.interfaceName, elt.swIfIndex);
+ interfaceContext.getName(elt.swIfIndex, context.getMappingContext()), elt.interfaceName, elt.swIfIndex);
- return new InterfaceKey(interfaceContext.getName(elt.swIfIndex));
+ return new InterfaceKey(interfaceContext.getName(elt.swIfIndex, context.getMappingContext()));
})
.collect(Collectors.toList());
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
index a6c887336..ee66aef1f 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceUtils.java
@@ -21,7 +21,7 @@ import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCusto
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.ModificationCache;
import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
import java.math.BigInteger;
import java.util.Map;
@@ -158,7 +158,7 @@ public final class InterfaceUtils {
@Nonnull
public static SwInterfaceDetails getVppInterfaceDetails(@Nonnull final FutureJVpp futureJvpp,
@Nonnull InterfaceKey key, final int index,
- @Nonnull final Context ctx) {
+ @Nonnull final ModificationCache ctx) {
final SwInterfaceDump request = new SwInterfaceDump();
request.nameFilter = key.getName().getBytes();
request.nameFilterValid = 1;
@@ -225,7 +225,7 @@ public final class InterfaceUtils {
return EthernetCsmacd.class;
}
- static boolean isInterfaceOfType(final Context ctx, final int index,
+ static boolean isInterfaceOfType(final ModificationCache ctx, final int index,
final Class<? extends InterfaceType> ifcType) {
final SwInterfaceDetails cachedDetails =
checkNotNull(getCachedInterfaceDump(ctx).get(index),
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java
index 099d4c195..1bc9c2b3a 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2Customizer.java
@@ -17,7 +17,7 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
import com.google.common.base.Preconditions;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
@@ -74,20 +74,20 @@ public class L2Customizer extends FutureJVppCustomizer
@Override
public void readCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2Builder builder,
- @Nonnull final Context ctx) throws ReadFailedException {
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
LOG.debug("Reading attributes for L2: {}", id);
final InterfaceKey key = id.firstKeyOf(Interface.class);
- final int ifaceId = interfaceContext.getIndex(key.getName());
+ final int ifaceId = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key,
- ifaceId, ctx);
+ ifaceId, ctx.getModificationCache());
LOG.debug("Interface details for interface: {}, details: {}", key.getName(), iface);
final Optional<BridgeDomainSwIfDetails> bdForInterface = getBridgeDomainForInterface(ifaceId);
if (bdForInterface.isPresent()) {
final BridgeDomainSwIfDetails bdSwIfDetails = bdForInterface.get();
final BridgeBasedBuilder bbBuilder = new BridgeBasedBuilder();
- bbBuilder.setBridgeDomain(bridgeDomainContext.getName(bdSwIfDetails.bdId));
+ bbBuilder.setBridgeDomain(bridgeDomainContext.getName(bdSwIfDetails.bdId, ctx.getMappingContext()));
// bbBuilder.setBridgedVirtualInterface // TODO where to find that value?
if (bdSwIfDetails.shg != 0) {
bbBuilder.setSplitHorizonGroup((short)bdSwIfDetails.shg);
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizer.java
index b68acbfa3..ebd1cff40 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizer.java
@@ -19,7 +19,7 @@ package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType;
import com.google.common.base.Preconditions;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
@@ -70,18 +70,18 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer
@Override
public void readCurrentAttributes(@Nonnull final InstanceIdentifier<SubInterface> id,
- @Nonnull final SubInterfaceBuilder builder, @Nonnull final Context ctx)
+ @Nonnull final SubInterfaceBuilder builder, @Nonnull final ReadContext ctx)
throws ReadFailedException {
final InterfaceKey key = id.firstKeyOf(Interface.class);
// Relying here that parent InterfaceCustomizer was invoked first (PREORDER)
// to fill in the context with initial ifc mapping
- final int index = interfaceContext.getIndex(key.getName());
- if (!isInterfaceOfType(ctx, index, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.SubInterface.class)) {
+ final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
+ if (!isInterfaceOfType(ctx.getModificationCache(), index, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.SubInterface.class)) {
return;
}
LOG.debug("Reading attributes for sub interface: {}", id);
- final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key, index, ctx);
+ final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key, index, ctx.getModificationCache());
LOG.debug("VPP interface details: {}", ReflectionToStringBuilder.toString(iface));
if (iface.subId == 0) {
@@ -90,7 +90,7 @@ public class SubInterfaceCustomizer extends FutureJVppCustomizer
}
builder.setIdentifier(Long.valueOf(iface.subId));
- builder.setSuperInterface(interfaceContext.getName(iface.supSwIfIndex));
+ builder.setSuperInterface(interfaceContext.getName(iface.supSwIfIndex, ctx.getMappingContext()));
builder.setNumberOfTags(Short.valueOf(iface.subNumberOfTags));
builder.setVlanType(iface.subDot1Ad == 1 ? VlanType._802dot1q : VlanType._802dot1ad);
if (iface.subExactMatch == 1) {
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java
index e7cd560bb..358e9149a 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/TapCustomizer.java
@@ -18,7 +18,7 @@ package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
@@ -72,12 +72,12 @@ public class TapCustomizer extends FutureJVppCustomizer
@Override
public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Tap> id,
@Nonnull final TapBuilder builder,
- @Nonnull final Context ctx) throws ReadFailedException {
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
final InterfaceKey key = id.firstKeyOf(Interface.class);
// Relying here that parent InterfaceCustomizer was invoked first (PREORDER)
// to fill in the context with initial ifc mapping
- final int index = interfaceContext.getIndex(key.getName());
- if (!isInterfaceOfType(ctx, index, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap.class)) {
+ final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
+ if (!isInterfaceOfType(ctx.getModificationCache(), index, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap.class)) {
return;
}
@@ -85,7 +85,7 @@ public class TapCustomizer extends FutureJVppCustomizer
@SuppressWarnings("unchecked")
Map<Integer, SwInterfaceTapDetails> mappedTaps =
- (Map<Integer, SwInterfaceTapDetails>) ctx.get(DUMPED_TAPS_CONTEXT_KEY);
+ (Map<Integer, SwInterfaceTapDetails>) ctx.getModificationCache().get(DUMPED_TAPS_CONTEXT_KEY);
if(mappedTaps == null) {
// Full Tap dump has to be performed here, no filter or anything is here to help so at least we cache it
@@ -104,7 +104,7 @@ public class TapCustomizer extends FutureJVppCustomizer
.collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails));
}
- ctx.put(DUMPED_TAPS_CONTEXT_KEY, mappedTaps);
+ ctx.getModificationCache().put(DUMPED_TAPS_CONTEXT_KEY, mappedTaps);
}
final SwInterfaceTapDetails swInterfaceTapDetails = mappedTaps.get(index);
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java
index 70a6da1cc..d5ae8faf3 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VhostUserCustomizer.java
@@ -18,7 +18,7 @@ package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.isInterfaceOfType;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
@@ -74,12 +74,12 @@ public class VhostUserCustomizer extends FutureJVppCustomizer
@Override
public void readCurrentAttributes(@Nonnull final InstanceIdentifier<VhostUser> id,
@Nonnull final VhostUserBuilder builder,
- @Nonnull final Context ctx) throws ReadFailedException {
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
final InterfaceKey key = id.firstKeyOf(Interface.class);
// Relying here that parent InterfaceCustomizer was invoked first (PREORDER)
// to fill in the context with initial ifc mapping
- final int index = interfaceContext.getIndex(key.getName());
- if (!isInterfaceOfType(ctx, index, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser.class)) {
+ final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
+ if (!isInterfaceOfType(ctx.getModificationCache(), index, org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser.class)) {
return;
}
@@ -87,7 +87,7 @@ public class VhostUserCustomizer extends FutureJVppCustomizer
@SuppressWarnings("unchecked")
Map<Integer, SwInterfaceVhostUserDetails> mappedVhostUsers =
- (Map<Integer, SwInterfaceVhostUserDetails>) ctx.get(DUMPED_VHOST_USERS_CONTEXT_KEY);
+ (Map<Integer, SwInterfaceVhostUserDetails>) ctx.getModificationCache().get(DUMPED_VHOST_USERS_CONTEXT_KEY);
if(mappedVhostUsers == null) {
// Full VhostUser dump has to be performed here, no filter or anything is here to help so at least we cache it
@@ -106,7 +106,7 @@ public class VhostUserCustomizer extends FutureJVppCustomizer
.collect(Collectors.toMap(t -> t.swIfIndex, swInterfaceDetails -> swInterfaceDetails));
}
- ctx.put(DUMPED_VHOST_USERS_CONTEXT_KEY, mappedVhostUsers);
+ ctx.getModificationCache().put(DUMPED_VHOST_USERS_CONTEXT_KEY, mappedVhostUsers);
}
// Relying here that parent InterfaceCustomizer was invoked first to fill in the context with initial ifc mapping
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VlanTagRewriteCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VlanTagRewriteCustomizer.java
index d7404e6d5..d05e089a2 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VlanTagRewriteCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VlanTagRewriteCustomizer.java
@@ -17,7 +17,7 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
import com.google.common.base.Preconditions;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
@@ -68,13 +68,13 @@ public class VlanTagRewriteCustomizer extends FutureJVppCustomizer
@Override
public void readCurrentAttributes(@Nonnull final InstanceIdentifier<VlanTagRewrite> id,
- @Nonnull final VlanTagRewriteBuilder builder, @Nonnull final Context ctx)
+ @Nonnull final VlanTagRewriteBuilder builder, @Nonnull final ReadContext ctx)
throws ReadFailedException {
LOG.debug("Reading attributes for sub interface: {}", id);
final InterfaceKey key = id.firstKeyOf(Interface.class);
final SwInterfaceDetails iface = InterfaceUtils.getVppInterfaceDetails(getFutureJVpp(), key,
- interfaceContext.getIndex(key.getName()), ctx);
+ interfaceContext.getIndex(key.getName(), ctx.getMappingContext()), ctx.getModificationCache());
builder.setFirstPushed(iface.subDot1Ad == 1 ? VlanType._802dot1q : VlanType._802dot1ad);
builder.setRewriteOperation(TagRewriteOperation.forValue(iface.vtrOp));
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java
index 829416034..81ba34062 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizer.java
@@ -18,7 +18,7 @@ package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
import static com.google.common.base.Preconditions.checkState;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
@@ -74,12 +74,12 @@ public class VxlanCustomizer extends FutureJVppCustomizer
@Override
public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Vxlan> id,
@Nonnull final VxlanBuilder builder,
- @Nonnull final Context ctx) throws ReadFailedException {
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
final InterfaceKey key = id.firstKeyOf(Interface.class);
// Relying here that parent InterfaceCustomizer was invoked first (PREORDER)
// to fill in the context with initial ifc mapping
- final int index = interfaceContext.getIndex(key.getName());
- if (!InterfaceUtils.isInterfaceOfType(ctx, index, VxlanTunnel.class)) {
+ final int index = interfaceContext.getIndex(key.getName(), ctx.getMappingContext());
+ if (!InterfaceUtils.isInterfaceOfType(ctx.getModificationCache(), index, VxlanTunnel.class)) {
return;
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java
index 672a05f4e..6e94461a6 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java
@@ -96,11 +96,11 @@ public class BridgeDomainCustomizer
// FIXME we need the bd index to be returned by VPP or we should have a counter field (maybe in context similar to artificial name)
// Here we assign the next available ID from bdContext's perspective
int index = 1;
- while(bdContext.containsName(index)) {
+ while(bdContext.containsName(index, ctx.getMappingContext())) {
index++;
}
addOrUpdateBridgeDomain(index, dataBefore);
- bdContext.addName(index, bdName);
+ bdContext.addName(index, bdName, ctx.getMappingContext());
} catch (VppApiInvocationException e) {
LOG.warn("Failed to create bridge domain", e);
throw new WriteFailedException.CreateFailedException(id, dataBefore, e);
@@ -120,7 +120,7 @@ public class BridgeDomainCustomizer
LOG.debug("deleteCurrentAttributes: id={}, dataBefore={}, ctx={}", id, dataBefore, ctx);
final String bdName = id.firstKeyOf(BridgeDomain.class).getName();
- int bdId = bdContext.getIndex(bdName);
+ int bdId = bdContext.getIndex(bdName, ctx.getMappingContext());
final BridgeDomainAddDel request = new BridgeDomainAddDel();
request.bdId = bdId;
@@ -154,7 +154,7 @@ public class BridgeDomainCustomizer
"BridgeDomain name changed. It should be deleted and then created.");
try {
- addOrUpdateBridgeDomain(bdContext.getIndex(bdName), dataAfter);
+ addOrUpdateBridgeDomain(bdContext.getIndex(bdName, ctx.getMappingContext()), dataAfter);
} catch (VppApiInvocationException e) {
LOG.warn("Failed to create bridge domain", e);
throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e);
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizer.java
index 1a3855ced..ac16c610f 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizer.java
@@ -20,7 +20,7 @@ import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.primitives.Longs;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ListReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
@@ -70,7 +70,7 @@ public final class BridgeDomainCustomizer extends FutureJVppCustomizer
@Override
public void readCurrentAttributes(@Nonnull final InstanceIdentifier<BridgeDomain> id,
- @Nonnull final BridgeDomainBuilder builder, @Nonnull final Context context)
+ @Nonnull final BridgeDomainBuilder builder, @Nonnull final ReadContext context)
throws ReadFailedException {
LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: id={}, builderbuilder={}, context={}",
id, builder, context);
@@ -78,13 +78,13 @@ public final class BridgeDomainCustomizer extends FutureJVppCustomizer
final BridgeDomainKey key = id.firstKeyOf(id.getTargetType());
LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: key={}", key);
- final int bdId = bdContext.getIndex(key.getName());
+ final int bdId = bdContext.getIndex(key.getName(), context.getMappingContext());
LOG.debug("vppstate.BridgeDomainCustomizer.readCurrentAttributes: bdId={}", bdId);
BridgeDomainDetailsReplyDump reply;
BridgeDomainDetails bridgeDomainDetails;
final BridgeDomainDump request = new BridgeDomainDump();
- request.bdId = bdContext.getIndex(key.getName());
+ request.bdId = bdContext.getIndex(key.getName(), context.getMappingContext());
try {
reply = getFutureJVpp().bridgeDomainDump(request).toCompletableFuture().get();
bridgeDomainDetails = Iterables.getOnlyElement(reply.bridgeDomainDetails);
@@ -102,7 +102,7 @@ public final class BridgeDomainCustomizer extends FutureJVppCustomizer
builder.setLearn(byteToBoolean(bridgeDomainDetails.learn));
builder.setUnknownUnicastFlood(byteToBoolean(bridgeDomainDetails.uuFlood));
- builder.setInterface(getIfcs(bridgeDomainDetails, reply.bridgeDomainSwIfDetails));
+ builder.setInterface(getIfcs(bridgeDomainDetails, reply.bridgeDomainSwIfDetails, context));
final L2FibTableDump l2FibRequest = new L2FibTableDump();
l2FibRequest.bdId = bdId;
@@ -124,7 +124,7 @@ public final class BridgeDomainCustomizer extends FutureJVppCustomizer
? L2Fib.Action.Filter
: L2Fib.Action.Forward))
.setBridgedVirtualInterface(byteToBoolean(entry.bviMac))
- .setOutgoingInterface(interfaceContext.getName(entry.swIfIndex))
+ .setOutgoingInterface(interfaceContext.getName(entry.swIfIndex, context.getMappingContext()))
.setStaticConfig(byteToBoolean(entry.staticMac))
.setPhysAddress(address)
.setKey(new L2FibKey(address))
@@ -175,10 +175,11 @@ public final class BridgeDomainCustomizer extends FutureJVppCustomizer
}
private List<Interface> getIfcs(final BridgeDomainDetails bridgeDomainDetails,
- final List<BridgeDomainSwIfDetails> bridgeDomainSwIfDetails) {
+ final List<BridgeDomainSwIfDetails> bridgeDomainSwIfDetails,
+ final ReadContext context) {
final List<Interface> ifcs = new ArrayList<>(bridgeDomainSwIfDetails.size());
for (BridgeDomainSwIfDetails anInterface : bridgeDomainSwIfDetails) {
- final String interfaceName = interfaceContext.getName(anInterface.swIfIndex);
+ final String interfaceName = interfaceContext.getName(anInterface.swIfIndex, context.getMappingContext());
if (anInterface.bdId == bridgeDomainDetails.bdId) {
ifcs.add(new InterfaceBuilder()
.setBridgedVirtualInterface(bridgeDomainDetails.bviSwIfIndex == anInterface.swIfIndex)
@@ -202,7 +203,7 @@ public final class BridgeDomainCustomizer extends FutureJVppCustomizer
@Nonnull
@Override
public List<BridgeDomainKey> getAllIds(@Nonnull final InstanceIdentifier<BridgeDomain> id,
- @Nonnull final Context context) {
+ @Nonnull final ReadContext context) {
final BridgeDomainDump request = new BridgeDomainDump();
request.bdId = -1; // dump call
@@ -228,7 +229,7 @@ public final class BridgeDomainCustomizer extends FutureJVppCustomizer
for (BridgeDomainDetails detail : reply.bridgeDomainDetails) {
logBridgeDomainDetails(detail);
- final String bName = bdContext.getName(detail.bdId);
+ final String bName = bdContext.getName(detail.bdId, context.getMappingContext());
LOG.debug("vppstate.BridgeDomainCustomizer.getAllIds: bName={}", bName);
allIds.add(new BridgeDomainKey(bName));
}
diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java
index 1db8217f9..4ad4a6e91 100644
--- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java
+++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VersionCustomizer.java
@@ -16,7 +16,7 @@
package io.fd.honeycomb.v3po.translate.v3po.vppstate;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.util.FutureJVppCustomizer;
@@ -53,7 +53,7 @@ public final class VersionCustomizer
@Override
public void readCurrentAttributes(@Nonnull InstanceIdentifier<Version> id, @Nonnull final VersionBuilder builder,
- @Nonnull final Context context) throws ReadFailedException {
+ @Nonnull final ReadContext context) throws ReadFailedException {
ShowVersionReply reply;
try {
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/ContextTestUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/ContextTestUtils.java
new file mode 100644
index 000000000..5c731bcb5
--- /dev/null
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/ContextTestUtils.java
@@ -0,0 +1,40 @@
+/*
+ * 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.v3po;
+
+import com.google.common.base.Optional;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.Contexts;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContextKey;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.MappingBuilder;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.MappingKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+
+public class ContextTestUtils {
+
+ public static Optional<Mapping> getMapping(final String name, final int index) {
+ return Optional.of(new MappingBuilder().setName(name).setIndex(index).build());
+ }
+
+ public static KeyedInstanceIdentifier<Mapping, MappingKey> getMappingIid(final String name, final String namingContextName) {
+ return InstanceIdentifier.create(Contexts.class).child(
+ org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContext.class,
+ new NamingContextKey(namingContextName)).child(Mappings.class).child(Mapping.class, new MappingKey(name));
+ }
+}
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceTypeTestUtils.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceTypeTestUtils.java
index ff96131b1..fbb47b5d4 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceTypeTestUtils.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceTypeTestUtils.java
@@ -19,21 +19,29 @@ package io.fd.honeycomb.v3po.translate.v3po.interfaces;
import static org.mockito.Mockito.doReturn;
import com.google.common.base.Optional;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.ModificationCache;
import io.fd.honeycomb.v3po.translate.write.WriteContext;
import org.mockito.Matchers;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.Contexts;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContextKey;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.MappingBuilder;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.MappingKey;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
final class InterfaceTypeTestUtils {
private InterfaceTypeTestUtils() {}
static void setupWriteContext(final WriteContext writeContext, final Class<? extends InterfaceType> ifcType) {
- doReturn(new Context()).when(writeContext).getContext();
+ doReturn(new ModificationCache()).when(writeContext).getModificationCache();
doReturn(Optional.of(new InterfaceBuilder()
.setType(ifcType)
.build())).when(writeContext).readAfter(Matchers.any(InstanceIdentifier.class));
}
+
}
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizerTest.java
index d70654655..31ab3aab5 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/SubInterfaceCustomizerTest.java
@@ -16,15 +16,18 @@
package io.fd.honeycomb.v3po.translate.v3po.interfaces;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMapping;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMappingIid;
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.Matchers.eq;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.MockitoAnnotations.initMocks;
+import io.fd.honeycomb.v3po.translate.MappingContext;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
import io.fd.honeycomb.v3po.translate.write.WriteContext;
@@ -54,6 +57,8 @@ public class SubInterfaceCustomizerTest {
private FutureJVpp api;
@Mock
private WriteContext writeContext;
+ @Mock
+ private MappingContext mappingContext;
private NamingContext namingContext;
private SubInterfaceCustomizer customizer;
@@ -65,10 +70,11 @@ public class SubInterfaceCustomizerTest {
initMocks(this);
InterfaceTypeTestUtils.setupWriteContext(writeContext,
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.SubInterface.class);
- namingContext = new NamingContext("generatedSubInterfaceName");
+ namingContext = new NamingContext("generatedSubInterfaceName", "test-instance");
+ doReturn(mappingContext).when(writeContext).getMappingContext();
// TODO create base class for tests using vppApi
customizer = new SubInterfaceCustomizer(api, namingContext);
- namingContext.addName(SUPER_IF_ID, SUPER_IF_NAME);
+ doReturn(getMapping(SUPER_IF_NAME, SUPER_IF_ID)).when(mappingContext).read(getMappingIid(SUPER_IF_NAME, "test-instance"));
}
private SubInterface generateSubInterface(final String superIfName) {
@@ -145,7 +151,7 @@ public class SubInterfaceCustomizerTest {
customizer.writeCurrentAttributes(id, subInterface, writeContext);
verifyCreateSubifWasInvoked(generateSubInterfaceRequest(SUPER_IF_ID));
- assertTrue(namingContext.containsIndex(subIfaceName));
+ verify(mappingContext).put(eq(getMappingIid(subIfaceName, "test-instance")), eq(getMapping(subIfaceName, 0).get()));
}
@Test
@@ -161,7 +167,9 @@ public class SubInterfaceCustomizerTest {
} catch (WriteFailedException.CreateFailedException e) {
assertEquals(VppApiInvocationException.class, e.getCause().getClass());
verifyCreateSubifWasInvoked(generateSubInterfaceRequest(SUPER_IF_ID));
- assertFalse(namingContext.containsIndex(subIfaceName));
+ verify(mappingContext, times(0)).put(
+ eq(getMappingIid(subIfaceName, "test-instance")),
+ eq(getMapping(subIfaceName, 0).get()));
return;
}
fail("WriteFailedException.CreateFailedException was expected");
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizerTest.java
index 8ae04f017..e717ec504 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/TapCustomizerTest.java
@@ -16,14 +16,17 @@
package io.fd.honeycomb.v3po.translate.v3po.interfaces;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMapping;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMappingIid;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import io.fd.honeycomb.v3po.translate.MappingContext;
+import io.fd.honeycomb.v3po.translate.ModificationCache;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
import io.fd.honeycomb.v3po.translate.write.WriteContext;
import java.util.concurrent.CompletableFuture;
@@ -55,8 +58,9 @@ public class TapCustomizerTest {
private FutureJVpp vppApi;
@Mock
private WriteContext writeContext;
+ @Mock
+ private MappingContext mappingContext;
- private NamingContext ctx;
private TapCustomizer tapCustomizer;
@Before
@@ -64,7 +68,11 @@ public class TapCustomizerTest {
MockitoAnnotations.initMocks(this);
InterfaceTypeTestUtils.setupWriteContext(writeContext,
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap.class);
- ctx = new NamingContext("ifcintest");
+ final NamingContext ctx = new NamingContext("ifcintest", "test-instance");
+ final ModificationCache toBeReturned = new ModificationCache();
+ doReturn(toBeReturned).when(writeContext).getModificationCache();
+ doReturn(mappingContext).when(writeContext).getMappingContext();
+
tapCustomizer = new TapCustomizer(vppApi, ctx);
}
@@ -89,8 +97,8 @@ public class TapCustomizerTest {
tapCustomizer.writeCurrentAttributes(getTapId("tap2"), getTapData("tap2", "ff:ff:ff:ff:ff:ff"), writeContext);
verify(vppApi, times(2)).tapConnect(any(TapConnect.class));
- assertTrue(ctx.containsIndex("tap"));
- assertTrue(ctx.containsIndex("tap2"));
+ verify(mappingContext).put(eq(getMappingIid("tap", "test-instance")), eq(getMapping("tap", 0).get()));
+ verify(mappingContext).put(eq(getMappingIid("tap2", "test-instance")), eq(getMapping("tap2", 1).get()));
}
@Test
@@ -109,12 +117,13 @@ public class TapCustomizerTest {
doReturn(replyModif).when(vppApi).tapModify(any(TapModify.class));
tapCustomizer.writeCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), writeContext);
+ doReturn(getMapping("tap", 1)).when(mappingContext).read(getMappingIid("tap", "test-instance"));
tapCustomizer.updateCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), getTapData("tap", "ff:ff:ff:ff:ff:f1"), writeContext);
verify(vppApi).tapConnect(any(TapConnect.class));
verify(vppApi).tapModify(any(TapModify.class));
- assertTrue(ctx.containsIndex("tap"));
- assertFalse(ctx.containsIndex("tap2"));
+
+ verify(mappingContext).put(eq(getMappingIid("tap", "test-instance")), eq(getMapping("tap", 0).get()));
}
@Test
@@ -132,11 +141,12 @@ public class TapCustomizerTest {
doReturn(replyDelete).when(vppApi).tapDelete(any(TapDelete.class));
tapCustomizer.writeCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), writeContext);
+ doReturn(getMapping("tap", 1)).when(mappingContext).read(getMappingIid("tap", "test-instance"));
tapCustomizer.deleteCurrentAttributes(getTapId("tap"), getTapData("tap", "ff:ff:ff:ff:ff:ff"), writeContext);
verify(vppApi).tapConnect(any(TapConnect.class));
verify(vppApi).tapDelete(any(TapDelete.class));
- assertFalse(ctx.containsIndex("tap"));
+ verify(mappingContext).delete(eq(getMappingIid("tap", "test-instance")));
}
private InstanceIdentifier<Tap> getTapId(final String tap) {
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizerTest.java
index 15b2a75c1..1015f24c0 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VhostUserCustomizerTest.java
@@ -16,19 +16,25 @@
package io.fd.honeycomb.v3po.translate.v3po.interfaces;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMapping;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMappingIid;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
+import io.fd.honeycomb.v3po.translate.MappingContext;
+import io.fd.honeycomb.v3po.translate.ModificationCache;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils;
@@ -63,8 +69,9 @@ public class VhostUserCustomizerTest {
private FutureJVpp api;
@Mock
private WriteContext writeContext;
+ @Mock
+ private MappingContext mappingContext;
- private NamingContext namingContext;
private VhostUserCustomizer customizer;
private static final int IFACE_ID = 1;
private static final String IFACE_NAME = "eth0";
@@ -77,7 +84,11 @@ public class VhostUserCustomizerTest {
initMocks(this);
InterfaceTypeTestUtils.setupWriteContext(writeContext,
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser.class);
- namingContext = new NamingContext("generatedInterfaceName");
+ final NamingContext namingContext = new NamingContext("generatedInterfaceName", "test-instance");
+ final ModificationCache toBeReturned = new ModificationCache();
+ doReturn(toBeReturned).when(writeContext).getModificationCache();
+ doReturn(mappingContext).when(writeContext).getMappingContext();
+
// TODO create base class for tests using vppApi
customizer = new VhostUserCustomizer(api, namingContext);
}
@@ -186,7 +197,7 @@ public class VhostUserCustomizerTest {
customizer.writeCurrentAttributes(ID, vhostUser, writeContext);
verifyCreateVhostUserIfWasInvoked(vhostUser);
- assertTrue(namingContext.containsIndex(IFACE_NAME));
+ verify(mappingContext).put(eq(getMappingIid(IFACE_NAME, "test-instance")), eq(getMapping(IFACE_NAME, 0).get()));
}
@Test
@@ -200,7 +211,7 @@ public class VhostUserCustomizerTest {
} catch (WriteFailedException.CreateFailedException e) {
assertEquals(VppApiInvocationException.class, e.getCause().getClass());
verifyCreateVhostUserIfWasInvoked(vhostUser);
- assertFalse(namingContext.containsIndex(IFACE_NAME));
+ verifyZeroInteractions(mappingContext);
return;
}
fail("WriteFailedException.CreateFailedException was expected");
@@ -210,7 +221,7 @@ public class VhostUserCustomizerTest {
public void testUpdateCurrentAttributes() throws Exception {
final VhostUser vhostUserBefore = generateVhostUser(VhostUserRole.Client, "socketName0");
final VhostUser vhostUserAfter = generateVhostUser(VhostUserRole.Server, "socketName1");
- namingContext.addName(IFACE_ID, IFACE_NAME);
+ doReturn(getMapping(IFACE_NAME, IFACE_ID)).when(mappingContext).read(getMappingIid(IFACE_NAME, "test-instance"));
whenModifyVhostUserIfThenSuccess();
@@ -230,7 +241,7 @@ public class VhostUserCustomizerTest {
public void testUpdateCurrentAttributesFailed() throws Exception {
final VhostUser vhostUserBefore = generateVhostUser(VhostUserRole.Client, "socketName0");
final VhostUser vhostUserAfter = generateVhostUser(VhostUserRole.Server, "socketName1");
- namingContext.addName(IFACE_ID, IFACE_NAME);
+ doReturn(getMapping(IFACE_NAME, IFACE_ID)).when(mappingContext).read(getMappingIid(IFACE_NAME, "test-instance"));
whenModifyVhostUserIfThenFailure();
@@ -247,19 +258,19 @@ public class VhostUserCustomizerTest {
@Test
public void testDeleteCurrentAttributes() throws Exception {
final VhostUser vhostUser = generateVhostUser(VhostUserRole.Client, "socketName");
- namingContext.addName(IFACE_ID, IFACE_NAME);
+ doReturn(getMapping(IFACE_NAME, IFACE_ID)).when(mappingContext).read(getMappingIid(IFACE_NAME, "test-instance"));
whenDeleteVhostUserIfThenSuccess();
customizer.deleteCurrentAttributes(ID, vhostUser, writeContext);
verifyDeleteVhostUserIfWasInvoked(IFACE_ID);
- assertFalse(namingContext.containsIndex(IFACE_NAME));
+ verify(mappingContext).delete(eq(getMappingIid(IFACE_NAME, "test-instance")));
}
@Test
public void testDeleteCurrentAttributesFailed() throws Exception {
final VhostUser vhostUser = generateVhostUser(VhostUserRole.Client, "socketName");
- namingContext.addName(IFACE_ID, IFACE_NAME);
+ doReturn(getMapping(IFACE_NAME, IFACE_ID)).when(mappingContext).read(getMappingIid(IFACE_NAME, "test-instance"));
whenDeleteVhostUserIfThenFailure();
@@ -268,7 +279,9 @@ public class VhostUserCustomizerTest {
} catch (WriteFailedException.DeleteFailedException e) {
assertEquals(VppApiInvocationException.class, e.getCause().getClass());
verifyDeleteVhostUserIfWasInvoked(IFACE_ID);
- assertTrue(namingContext.containsIndex(IFACE_NAME));
+ // Delete from context not invoked if delete from VPP failed
+ verify(mappingContext, times(0)).delete(eq(getMappingIid(IFACE_NAME, "test-instance")));
+ verify(mappingContext).read(eq(getMappingIid(IFACE_NAME, "test-instance")));
return;
}
fail("WriteFailedException.DeleteFailedException was expected");
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VlanTagRewriteCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VlanTagRewriteCustomizerTest.java
index ae768145a..39a9823b5 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VlanTagRewriteCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VlanTagRewriteCustomizerTest.java
@@ -16,6 +16,8 @@
package io.fd.honeycomb.v3po.translate.v3po.interfaces;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMapping;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMappingIid;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
@@ -24,6 +26,7 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.MockitoAnnotations.initMocks;
+import io.fd.honeycomb.v3po.translate.MappingContext;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
import io.fd.honeycomb.v3po.translate.write.WriteContext;
@@ -55,6 +58,8 @@ public class VlanTagRewriteCustomizerTest {
private FutureJVpp api;
@Mock
private WriteContext writeContext;
+ @Mock
+ private MappingContext mappingContext;
private NamingContext namingContext;
private VlanTagRewriteCustomizer customizer;
@@ -65,9 +70,10 @@ public class VlanTagRewriteCustomizerTest {
@Before
public void setUp() throws Exception {
initMocks(this);
- namingContext = new NamingContext("generatedSubInterfaceName");
+ namingContext = new NamingContext("generatedSubInterfaceName", "test-instance");
+ doReturn(mappingContext).when(writeContext).getMappingContext();
customizer = new VlanTagRewriteCustomizer(api, namingContext);
- namingContext.addName(VLAN_IF_ID, VLAN_IF_NAME);
+ doReturn(getMapping(VLAN_IF_NAME, VLAN_IF_ID)).when(mappingContext).read(getMappingIid(VLAN_IF_NAME, "test-instance"));
}
private InstanceIdentifier<VlanTagRewrite> getVlanTagRewriteId(final String name) {
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizerTest.java
index af7b4df17..a5103b178 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizerTest.java
@@ -16,19 +16,24 @@
package io.fd.honeycomb.v3po.translate.v3po.interfaces;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMapping;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMappingIid;
import static org.junit.Assert.assertArrayEquals;
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.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import com.google.common.net.InetAddresses;
+import io.fd.honeycomb.v3po.translate.MappingContext;
+import io.fd.honeycomb.v3po.translate.ModificationCache;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException;
import io.fd.honeycomb.v3po.translate.write.WriteContext;
@@ -63,9 +68,10 @@ public class VxlanCustomizerTest {
private FutureJVpp api;
@Mock
private WriteContext writeContext;
+ @Mock
+ private MappingContext mappingContext;
private VxlanCustomizer customizer;
- private NamingContext namingContext;
private String ifaceName;
private InstanceIdentifier<Vxlan> id;
@@ -75,7 +81,11 @@ public class VxlanCustomizerTest {
InterfaceTypeTestUtils.setupWriteContext(writeContext,
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel.class);
// TODO create base class for tests using vppApi
- namingContext = new NamingContext("generateInterfaceNAme");
+ NamingContext namingContext = new NamingContext("generateInterfaceNAme", "test-instance");
+ final ModificationCache toBeReturned = new ModificationCache();
+ doReturn(toBeReturned).when(writeContext).getModificationCache();
+ doReturn(mappingContext).when(writeContext).getMappingContext();
+
customizer = new VxlanCustomizer(api, namingContext);
ifaceName = "eth0";
@@ -144,7 +154,7 @@ public class VxlanCustomizerTest {
customizer.writeCurrentAttributes(id, vxlan, writeContext);
verifyVxlanAddWasInvoked(vxlan);
- assertTrue(namingContext.containsIndex(ifaceName));
+ verify(mappingContext).put(eq(getMappingIid(ifaceName, "test-instance")), eq(getMapping(ifaceName, 0).get()));
}
@Test
@@ -158,7 +168,8 @@ public class VxlanCustomizerTest {
} catch (WriteFailedException.CreateFailedException e) {
assertEquals(VppApiInvocationException.class, e.getCause().getClass());
verifyVxlanAddWasInvoked(vxlan);
- assertFalse(namingContext.containsIndex(ifaceName));
+ // Mapping not stored due to failure
+ verify(mappingContext, times(0)).put(eq(getMappingIid(ifaceName, "test-instance")), eq(getMapping(ifaceName, 0).get()));
return;
}
fail("WriteFailedException.CreateFailedException was expected");
@@ -186,11 +197,11 @@ public class VxlanCustomizerTest {
final Vxlan vxlan = generateVxlan();
whenVxlanAddDelTunnelThenSuccess();
- namingContext.addName(1, ifaceName);
+ doReturn(getMapping(ifaceName, 1)).when(mappingContext).read(getMappingIid(ifaceName, "test-instance"));
customizer.deleteCurrentAttributes(id, vxlan, writeContext);
verifyVxlanDeleteWasInvoked(vxlan);
- assertFalse(namingContext.containsIndex(ifaceName));
+ verify(mappingContext).delete(eq(getMappingIid(ifaceName, "test-instance")));
}
@Test
@@ -198,14 +209,14 @@ public class VxlanCustomizerTest {
final Vxlan vxlan = generateVxlan();
whenVxlanAddDelTunnelThenFailure();
- namingContext.addName(1, ifaceName);
+ doReturn(getMapping(ifaceName, 1)).when(mappingContext).read(getMappingIid(ifaceName, "test-instance"));
try {
customizer.deleteCurrentAttributes(id, vxlan, writeContext);
} catch (WriteFailedException.DeleteFailedException e) {
assertEquals(VppApiInvocationException.class, e.getCause().getClass());
verifyVxlanDeleteWasInvoked(vxlan);
- assertTrue(namingContext.containsIndex(ifaceName));
+ verify(mappingContext, times(0)).delete(eq(getMappingIid(ifaceName, "test-instance")));
return;
}
fail("WriteFailedException.DeleteFailedException was expected");
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java
index 3f33d141f..822b16c2b 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/InterfaceCustomizerTest.java
@@ -16,16 +16,21 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMapping;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMappingIid;
import static io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceUtils.yangIfIndexToVpp;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.test.ListReaderCustomizerTest;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
@@ -37,12 +42,17 @@ import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.MappingsBuilder;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.MappingKey;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesStateBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.openvpp.jvpp.dto.SwInterfaceDetails;
import org.openvpp.jvpp.dto.SwInterfaceDetailsReplyDump;
import org.openvpp.jvpp.dto.SwInterfaceDump;
@@ -58,13 +68,23 @@ public class InterfaceCustomizerTest extends
@Override
public void setUpBefore() {
- interfacesContext = new NamingContext("generatedIfaceName");
+ interfacesContext = new NamingContext("generatedIfaceName", "test-instance");
}
@Override
protected RootReaderCustomizer<Interface, InterfaceBuilder> initCustomizer() {
- interfacesContext.addName(0, "eth0");
- interfacesContext.addName(1, "eth1");
+ final KeyedInstanceIdentifier<Mapping, MappingKey> eth0Id = getMappingIid("eth0", "test-instance");
+ final KeyedInstanceIdentifier<Mapping, MappingKey> eth1Id = getMappingIid("eth1", "test-instance");
+ final Optional<Mapping> eth0 = getMapping("eth0", 0);
+ final Optional<Mapping> eth1 = getMapping("eth1", 1);
+
+ final List<Mapping> allMappings = Lists.newArrayList(getMapping("eth0", 0).get(), getMapping("eth1", 1).get());
+ final Mappings allMappingsBaObject = new MappingsBuilder().setMapping(allMappings).build();
+ doReturn(Optional.of(allMappingsBaObject)).when(mappingContext).read(eth0Id.firstIdentifierOf(Mappings.class));
+
+ doReturn(eth0).when(mappingContext).read(eth0Id);
+ doReturn(eth1).when(mappingContext).read(eth1Id);
+
return new InterfaceCustomizer(api, interfacesContext);
}
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2CustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2CustomizerTest.java
index b454446dc..b09381584 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2CustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/L2CustomizerTest.java
@@ -16,12 +16,16 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMapping;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMappingIid;
import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import io.fd.honeycomb.v3po.translate.Context;
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.test.ChildReaderCustomizerTest;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
@@ -33,6 +37,10 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.MappingsBuilder;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.MappingKey;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
@@ -43,6 +51,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.l2.Interconnection;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.l2.interconnection.BridgeBasedBuilder;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.openvpp.jvpp.dto.BridgeDomainDetailsReplyDump;
import org.openvpp.jvpp.dto.BridgeDomainDump;
import org.openvpp.jvpp.dto.BridgeDomainSwIfDetails;
@@ -59,8 +68,8 @@ public class L2CustomizerTest extends ChildReaderCustomizerTest<L2, L2Builder> {
@Override
public void setUpBefore() {
- interfaceContext = new NamingContext("generatedIfaceName");
- bridgeDomainContext = new NamingContext("generatedBDName");
+ interfaceContext = new NamingContext("generatedIfaceName", "ifc-test-instance");
+ bridgeDomainContext = new NamingContext("generatedBDName", "bd-test-instance");
}
@Override
@@ -111,19 +120,28 @@ public class L2CustomizerTest extends ChildReaderCustomizerTest<L2, L2Builder> {
@Test
public void testRead() throws Exception {
- final Context ctx = new Context();
final Map<Integer, SwInterfaceDetails> cachedInterfaceDump = new HashMap<>();
final int ifId = 1;
final int bdId = 1;
final String bdName = "bd001";
final String ifName = "eth0.sub0";
- interfaceContext.addName(ifId, ifName);
- bridgeDomainContext.addName(bdId, bdName);
+ final KeyedInstanceIdentifier<Mapping, MappingKey> ifcIid = getMappingIid(ifName, "ifc-test-instance");
+ doReturn(getMapping(ifName, ifId)).when(mappingContext).read(ifcIid);
+ final KeyedInstanceIdentifier<Mapping, MappingKey> bdIid = getMappingIid(bdName, "bd-test-instance");
+ doReturn(getMapping(bdName, bdId)).when(mappingContext).read(bdIid);
+
+ List<Mapping> allMappings = Lists.newArrayList(getMapping(ifName, ifId).get());
+ Mappings allMappingsBaObject = new MappingsBuilder().setMapping(allMappings).build();
+ doReturn(Optional.of(allMappingsBaObject)).when(mappingContext).read(ifcIid.firstIdentifierOf(Mappings.class));
+
+ allMappings = Lists.newArrayList(getMapping(bdName, bdId).get());
+ allMappingsBaObject = new MappingsBuilder().setMapping(allMappings).build();
+ doReturn(Optional.of(allMappingsBaObject)).when(mappingContext).read(bdIid.firstIdentifierOf(Mappings.class));
final SwInterfaceDetails ifaceDetails = new SwInterfaceDetails();
ifaceDetails.subId = ifId;
cachedInterfaceDump.put(ifId, ifaceDetails);
- ctx.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, cachedInterfaceDump);
+ cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, cachedInterfaceDump);
whenBridgeDomainSwIfDumpThenReturn(Collections.singletonList(generateBdSwIfDetails(ifId, bdId)));
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizerTest.java
index 8ed35e01b..4f6857b47 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizerTest.java
@@ -16,19 +16,29 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMapping;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMappingIid;
import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import io.fd.honeycomb.v3po.translate.Context;
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.ChildReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.test.ChildReaderCustomizerTest;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.MappingsBuilder;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.MappingKey;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey;
@@ -38,6 +48,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.SubInterface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces.state._interface.SubInterfaceBuilder;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.openvpp.jvpp.dto.SwInterfaceDetails;
public class SubInterfaceCustomizerTest extends ChildReaderCustomizerTest<SubInterface, SubInterfaceBuilder> {
@@ -55,7 +66,7 @@ public class SubInterfaceCustomizerTest extends ChildReaderCustomizerTest<SubInt
@Override
public void setUpBefore() {
- interfacesContext = new NamingContext("generatedIfaceName");
+ interfacesContext = new NamingContext("generatedIfaceName", "test-instance");
}
private InstanceIdentifier<SubInterface> getSubInterfaceId(final String name) {
@@ -74,21 +85,30 @@ public class SubInterfaceCustomizerTest extends ChildReaderCustomizerTest<SubInt
@Test
public void testRead() throws ReadFailedException {
- final Context ctx = new Context();
final Map<Integer, SwInterfaceDetails> cachedInterfaceDump = new HashMap<>();
final int ifId = 1;
final String ifName = "eth0.sub0";
- interfacesContext.addName(ifId, ifName);
+
+ final KeyedInstanceIdentifier<Mapping, MappingKey> ifcIid = getMappingIid(ifName, "test-instance");
+ doReturn(getMapping(ifName, ifId)).when(mappingContext).read(ifcIid);
+ final KeyedInstanceIdentifier<Mapping, MappingKey> superIfcIid = getMappingIid("super", "test-instance");
+ doReturn(getMapping("super", 0)).when(mappingContext).read(superIfcIid);
+
+ final List<Mapping> allMappings = Lists.newArrayList(getMapping(ifName, ifId).get(), getMapping("super", 0).get());
+ final Mappings allMappingsBaObject = new MappingsBuilder().setMapping(allMappings).build();
+ doReturn(Optional.of(allMappingsBaObject)).when(mappingContext).read(ifcIid.firstIdentifierOf(Mappings.class));
+
final SwInterfaceDetails ifaceDetails = new SwInterfaceDetails();
ifaceDetails.subId = ifId;
ifaceDetails.interfaceName = ifName.getBytes();
cachedInterfaceDump.put(ifId, ifaceDetails);
- ctx.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, cachedInterfaceDump);
+ cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, cachedInterfaceDump);
final SubInterfaceBuilder builder = mock(SubInterfaceBuilder.class);
getCustomizer().readCurrentAttributes(getSubInterfaceId(ifName), builder, ctx);
verify(builder).setIdentifier((long)ifId);
+ verify(builder).setSuperInterface(anyString());
verify(builder).setNumberOfTags((short)0);
verify(builder).setVlanType(VlanType._802dot1ad);
verify(builder, never()).setExactMatch(any());
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VlanTagRewriteCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VlanTagRewriteCustomizerTest.java
index 2263160e3..d00745ec1 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VlanTagRewriteCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VlanTagRewriteCustomizerTest.java
@@ -16,12 +16,14 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMapping;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMappingIid;
import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
-import io.fd.honeycomb.v3po.translate.Context;
import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.test.ChildReaderCustomizerTest;
@@ -52,7 +54,7 @@ public class VlanTagRewriteCustomizerTest extends ChildReaderCustomizerTest<Vlan
@Override
public void setUpBefore() {
- interfacesContext = new NamingContext("generatedIfaceName");
+ interfacesContext = new NamingContext("generatedIfaceName", "test-instance");
}
@@ -76,15 +78,15 @@ public class VlanTagRewriteCustomizerTest extends ChildReaderCustomizerTest<Vlan
@Test
public void testRead() throws ReadFailedException {
- final Context ctx = new Context();
final Map<Integer, SwInterfaceDetails> cachedInterfaceDump = new HashMap<>();
final int ifId = 1;
final String ifName = "eth0.sub0";
- interfacesContext.addName(ifId, ifName);
+ doReturn(getMapping(ifName, ifId)).when(mappingContext).read(getMappingIid(ifName, "test-instance"));
+
final SwInterfaceDetails ifaceDetails = new SwInterfaceDetails();
ifaceDetails.subId = ifId;
cachedInterfaceDump.put(ifId, ifaceDetails);
- ctx.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, cachedInterfaceDump);
+ cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, cachedInterfaceDump);
final VlanTagRewriteBuilder builder = mock(VlanTagRewriteBuilder.class);
getCustomizer().readCurrentAttributes(getVlanTagRewriteId(ifName), builder, ctx);
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizerTest.java
index 760e85b26..db92ebf17 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/VxlanCustomizerTest.java
@@ -16,6 +16,8 @@
package io.fd.honeycomb.v3po.translate.v3po.interfacesstate;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMapping;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMappingIid;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -25,7 +27,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import com.google.common.collect.Lists;
-import io.fd.honeycomb.v3po.translate.Context;
import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
import io.fd.honeycomb.v3po.translate.v3po.test.ChildReaderCustomizerTest;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
@@ -50,7 +51,6 @@ import org.openvpp.jvpp.dto.VxlanTunnelDump;
public class VxlanCustomizerTest extends ChildReaderCustomizerTest<Vxlan, VxlanBuilder> {
private NamingContext interfacesContext;
- private Context ctx;
static final InstanceIdentifier<Vxlan> IID =
InstanceIdentifier.create(InterfacesState.class).child(Interface.class, new InterfaceKey("ifc1"))
.augmentation(VppInterfaceStateAugmentation.class).child(Vxlan.class);
@@ -61,15 +61,14 @@ public class VxlanCustomizerTest extends ChildReaderCustomizerTest<Vxlan, VxlanB
@Override
public void setUpBefore() {
- interfacesContext = new NamingContext("vxlan-tunnel");
- interfacesContext.addName(0, "ifc1");
+ interfacesContext = new NamingContext("vxlan-tunnel", "test-instance");
+ doReturn(getMapping("ifc1", 0)).when(mappingContext).read(getMappingIid("ifc1", "test-instance"));
- ctx = new Context();
final SwInterfaceDetails v = new SwInterfaceDetails();
v.interfaceName = "vxlan-tunnel4".getBytes();
final Map<Integer, SwInterfaceDetails> map = new HashMap<>();
map.put(0, v);
- ctx.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, map);
+ cache.put(InterfaceCustomizer.DUMPED_IFCS_CONTEXT_KEY, map);
}
@Override
@@ -114,7 +113,7 @@ public class VxlanCustomizerTest extends ChildReaderCustomizerTest<Vxlan, VxlanB
@Test(expected = NullPointerException.class)
public void testReadCurrentAttributesVppNameNotCached() throws Exception {
- InterfaceCustomizer.getCachedInterfaceDump(ctx).remove(0);
+ InterfaceCustomizer.getCachedInterfaceDump(cache).remove(0);
final VxlanBuilder builder = getCustomizer().getBuilder(IID);
getCustomizer().readCurrentAttributes(IID, builder, ctx);
@@ -124,7 +123,7 @@ public class VxlanCustomizerTest extends ChildReaderCustomizerTest<Vxlan, VxlanB
public void testReadCurrentAttributesWrongType() throws Exception {
final SwInterfaceDetails v = new SwInterfaceDetails();
v.interfaceName = "tap-2".getBytes();
- InterfaceCustomizer.getCachedInterfaceDump(ctx).put(0, v);
+ InterfaceCustomizer.getCachedInterfaceDump(cache).put(0, v);
final VxlanBuilder builder = getCustomizer().getBuilder(IID);
getCustomizer().readCurrentAttributes(IID, builder, ctx);
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/RootReaderCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/RootReaderCustomizerTest.java
index 19d307ec9..8500acece 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/RootReaderCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/test/RootReaderCustomizerTest.java
@@ -17,9 +17,12 @@
package io.fd.honeycomb.v3po.translate.v3po.test;
import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.MockitoAnnotations.initMocks;
-import io.fd.honeycomb.v3po.translate.Context;
+import io.fd.honeycomb.v3po.translate.MappingContext;
+import io.fd.honeycomb.v3po.translate.ModificationCache;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
import io.fd.honeycomb.v3po.translate.spi.read.RootReaderCustomizer;
import org.junit.Before;
import org.junit.Test;
@@ -39,8 +42,11 @@ public abstract class RootReaderCustomizerTest<D extends DataObject, B extends B
@Mock
protected FutureJVpp api;
+ protected ModificationCache cache;
@Mock
- protected Context ctx;
+ protected ReadContext ctx;
+ @Mock
+ protected MappingContext mappingContext;
protected final Class<D> dataObjectClass;
private RootReaderCustomizer<D, B> customizer;
@@ -52,6 +58,10 @@ public abstract class RootReaderCustomizerTest<D extends DataObject, B extends B
@Before
public void setUpParent() throws Exception {
initMocks(this);
+ cache = new ModificationCache();
+ doReturn(cache).when(ctx).getModificationCache();
+ doReturn(mappingContext).when(ctx).getMappingContext();
+
setUpBefore();
customizer = initCustomizer();
setUpAfter();
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java
index f5b19a7be..7436c9cf3 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizerTest.java
@@ -15,15 +15,21 @@
*/
package io.fd.honeycomb.v3po.translate.v3po.vpp;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMapping;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMappingIid;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
+import com.google.common.base.Optional;
+import io.fd.honeycomb.v3po.translate.MappingContext;
+import io.fd.honeycomb.v3po.translate.ModificationCache;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
import io.fd.honeycomb.v3po.translate.write.WriteContext;
import io.fd.honeycomb.v3po.translate.write.WriteFailedException;
@@ -34,6 +40,7 @@ import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainBuilder;
import org.openvpp.jvpp.dto.BridgeDomainAddDel;
@@ -47,18 +54,22 @@ public class BridgeDomainCustomizerTest {
@Mock
private FutureJVpp api;
-
@Mock
private WriteContext ctx;
+ @Mock
+ private MappingContext mappingContext;
private BridgeDomainCustomizer customizer;
- private NamingContext namingContext;
@Before
public void setUp() throws Exception {
initMocks(this);
// TODO create base class for tests using vppApi
- namingContext = new NamingContext("generatedBDName");
+ NamingContext namingContext = new NamingContext("generatedBDName", "test-instance");
+ final ModificationCache toBeReturned = new ModificationCache();
+ doReturn(toBeReturned).when(ctx).getModificationCache();
+ doReturn(mappingContext).when(ctx).getMappingContext();
+
customizer = new BridgeDomainCustomizer(api, namingContext);
}
@@ -139,12 +150,14 @@ public class BridgeDomainCustomizerTest {
final int bdId = 1;
final String bdName = "bd1";
final BridgeDomain bd = generateBridgeDomain(bdName);
+ doReturn(Optional.absent()).when(mappingContext).read(getMappingIid(bdName, "test-instance").firstIdentifierOf(Mappings.class));
whenBridgeDomainAddDelThenSuccess();
customizer.writeCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
verifyBridgeDomainAddOrUpdateWasInvoked(bd, bdId);
+ verify(mappingContext).put(getMappingIid(bdName, "test-instance"), getMapping(bdName, bdId).get());
}
@Test
@@ -153,6 +166,9 @@ public class BridgeDomainCustomizerTest {
final String bdName = "bd1";
final BridgeDomain bd = generateBridgeDomain(bdName);
+ // Returning no Mappings for "test-instance" makes bdContext.containsName() return false
+ doReturn(Optional.absent()).when(mappingContext).read(getMappingIid(bdName, "test-instance").firstIdentifierOf(Mappings.class));
+
whenBridgeDomainAddDelThenFailure();
try {
@@ -169,7 +185,7 @@ public class BridgeDomainCustomizerTest {
final int bdId = 1;
final String bdName = "bd1";
final BridgeDomain bd = generateBridgeDomain(bdName);
- namingContext.addName(bdId, bdName);
+ doReturn(getMapping(bdName, bdId)).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
whenBridgeDomainAddDelThenSuccess();
@@ -182,6 +198,7 @@ public class BridgeDomainCustomizerTest {
public void testDeleteUnknownBridgeDomain() throws Exception {
final String bdName = "bd1";
final BridgeDomain bd = generateBridgeDomain("bd1");
+ doReturn(Optional.absent()).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
try {
customizer.deleteCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bd, ctx);
@@ -197,7 +214,7 @@ public class BridgeDomainCustomizerTest {
final int bdId = 1;
final String bdName = "bd1";
final BridgeDomain bd = generateBridgeDomain(bdName);
- namingContext.addName(bdId, bdName);
+ doReturn(getMapping(bdName, bdId)).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
whenBridgeDomainAddDelThenFailure();
@@ -215,7 +232,7 @@ public class BridgeDomainCustomizerTest {
public void testUpdateBridgeDomain() throws Exception {
final int bdId = 1;
final String bdName = "bd1";
- namingContext.addName(bdId, bdName);
+ doReturn(getMapping(bdName, bdId)).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
final byte arpTermBefore = 1;
final byte floodBefore = 1;
@@ -241,6 +258,7 @@ public class BridgeDomainCustomizerTest {
final String bdName = "bd1";
final BridgeDomain bdBefore = generateBridgeDomain(bdName, 0, 1, 0 ,1, 0);
final BridgeDomain bdAfter = generateBridgeDomain(bdName, 1, 1, 0 ,1, 0);
+ doReturn(Optional.absent()).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
try {
customizer.updateCurrentAttributes(BridgeDomainTestUtils.bdIdentifierForName(bdName), bdBefore, bdAfter, ctx);
@@ -257,7 +275,7 @@ public class BridgeDomainCustomizerTest {
final String bdName = "bd1";
final BridgeDomain bdBefore = generateBridgeDomain(bdName, 0, 1, 0 ,1, 0);
final BridgeDomain bdAfter = generateBridgeDomain(bdName, 1, 1, 0 ,1, 0);
- namingContext.addName(bdId, bdName);
+ doReturn(getMapping(bdName, bdId)).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
whenBridgeDomainAddDelThenFailure();
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppTest.java
index 820cf0555..1b30fdde7 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vpp/VppTest.java
@@ -16,15 +16,21 @@
package io.fd.honeycomb.v3po.translate.v3po.vpp;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMapping;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMappingIid;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
+import com.google.common.base.Optional;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
+import io.fd.honeycomb.v3po.translate.MappingContext;
+import io.fd.honeycomb.v3po.translate.ModificationCache;
import io.fd.honeycomb.v3po.translate.impl.write.CompositeRootWriter;
import io.fd.honeycomb.v3po.translate.util.write.DelegatingWriterRegistry;
import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
@@ -38,6 +44,9 @@ import java.util.concurrent.ExecutionException;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Vpp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains;
@@ -54,17 +63,24 @@ public class VppTest {
private static final byte ADD_OR_UPDATE_BD = 1;
private static final byte ZERO = 0;
+ @Mock
private FutureJVpp api;
+ @Mock
+ private WriteContext ctx;
+ @Mock
+ private MappingContext mappingContext;
+
private DelegatingWriterRegistry rootRegistry;
private CompositeRootWriter<Vpp> vppWriter;
- private WriteContext ctx;
- private NamingContext bdContext;
@Before
public void setUp() throws Exception {
- api = mock(FutureJVpp.class);
- ctx = mock(WriteContext.class);
- bdContext = new NamingContext("generatedBdName");
+ MockitoAnnotations.initMocks(this);
+ NamingContext bdContext = new NamingContext("generatedBdName", "test-instance");
+ final ModificationCache toBeReturned = new ModificationCache();
+ doReturn(toBeReturned).when(ctx).getModificationCache();
+ doReturn(mappingContext).when(ctx).getMappingContext();
+
vppWriter = VppUtils.getVppWriter(api, bdContext);
rootRegistry = new DelegatingWriterRegistry(
Collections.<Writer<? extends DataObject>>singletonList(vppWriter));
@@ -134,6 +150,8 @@ public class VppTest {
final int bdId = 1;
final BridgeDomains bdn1 = getBridgeDomains("bdn1");
whenBridgeDomainAddDelThen(0);
+ doReturn(Optional
+ .absent()).when(mappingContext).read(getMappingIid("bdn1", "test-instance").firstIdentifierOf(Mappings.class));
rootRegistry.update(
InstanceIdentifier.create(Vpp.class),
@@ -149,6 +167,8 @@ public class VppTest {
final int bdId = 1;
final BridgeDomains bdn1 = getBridgeDomains("bdn1");
whenBridgeDomainAddDelThen(0);
+ doReturn(Optional
+ .absent()).when(mappingContext).read(getMappingIid("bdn1", "test-instance").firstIdentifierOf(Mappings.class));
vppWriter.update(InstanceIdentifier.create(Vpp.class),
null,
@@ -156,6 +176,7 @@ public class VppTest {
ctx);
verifyBridgeDomainAddDel(Iterators.getOnlyElement(bdn1.getBridgeDomain().iterator()), bdId);
+ verify(mappingContext).put(getMappingIid("bdn1", "test-instance"), getMapping("bdn1", 1).get());
}
@Test
@@ -163,9 +184,11 @@ public class VppTest {
final BridgeDomains bdn1 = getBridgeDomains("bdn1");
final int bdId = 1;
final Vpp vpp = new VppBuilder().setBridgeDomains(bdn1).build();
+ doReturn(Optional
+ .absent()).when(mappingContext).read(getMappingIid("bdn1", "test-instance").firstIdentifierOf(Mappings.class));
whenBridgeDomainAddDelThen(0);
- rootRegistry.update(Collections.<InstanceIdentifier<?>, DataObject>emptyMap(),
+ rootRegistry.update(Collections.emptyMap(),
Collections.<InstanceIdentifier<?>, DataObject>singletonMap(InstanceIdentifier.create(Vpp.class),
vpp), ctx);
@@ -178,7 +201,7 @@ public class VppTest {
final BridgeDomains bdn1 = getBridgeDomains(bdName);
final int bdId = 1;
whenBridgeDomainAddDelThen(0);
- bdContext.addName(bdId, bdName);
+ doReturn(getMapping(bdName, bdId)).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
rootRegistry.update(
InstanceIdentifier.create(Vpp.class),
@@ -204,7 +227,8 @@ public class VppTest {
public void writeUpdate() throws Exception {
final String bdName = "bdn1";
final int bdn1Id = 1;
- bdContext.addName(bdn1Id, bdName);
+ doReturn(getMapping(bdName, bdn1Id)).when(mappingContext).read(getMappingIid(bdName, "test-instance"));
+
final BridgeDomains domainsBefore = getBridgeDomains(bdName);
final BridgeDomain bdn1Before = domainsBefore.getBridgeDomain().get(0);
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java
index c482c4485..369038687 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/BridgeDomainCustomizerTest.java
@@ -40,8 +40,8 @@ public class BridgeDomainCustomizerTest extends ListReaderCustomizerTest<BridgeD
@Override
public void setUpBefore() {
- bdContext = new NamingContext("generatedBdName");
- interfacesContext = new NamingContext("generatedIfaceName");
+ bdContext = new NamingContext("generatedBdName", "bd-test-instance");
+ interfacesContext = new NamingContext("generatedIfaceName", "ifc-test-instance");
}
@Test
diff --git a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java
index bf1d12152..3d75d09e2 100644
--- a/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java
+++ b/v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/vppstate/VppStateTest.java
@@ -16,18 +16,24 @@
package io.fd.honeycomb.v3po.translate.v3po.vppstate;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMapping;
+import static io.fd.honeycomb.v3po.translate.v3po.ContextTestUtils.getMappingIid;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import com.google.common.base.Optional;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
+import io.fd.honeycomb.v3po.translate.MappingContext;
+import io.fd.honeycomb.v3po.translate.ModificationCache;
import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader;
import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader;
import io.fd.honeycomb.v3po.translate.read.ReadContext;
@@ -43,6 +49,9 @@ import java.util.concurrent.ExecutionException;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.MappingsBuilder;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder;
@@ -72,6 +81,8 @@ public class VppStateTest {
private FutureJVpp api;
@Mock
private ReadContext ctx;
+ @Mock
+ private MappingContext mappingContext;
private NamingContext bdContext;
private NamingContext interfaceContext;
@@ -82,9 +93,12 @@ public class VppStateTest {
@Before
public void setUp() throws Exception {
initMocks(this);
+ final ModificationCache cache = new ModificationCache();
+ doReturn(cache).when(ctx).getModificationCache();
+ doReturn(mappingContext).when(ctx).getMappingContext();
- bdContext = new NamingContext("generatedBdName");
- interfaceContext = new NamingContext("generatedInterfaceName");
+ bdContext = new NamingContext("generatedBdName", "bd-test-instance");
+ interfaceContext = new NamingContext("generatedIfaceName", "ifc-test-instance");
vppStateReader = VppStateTestUtils.getVppStateReader(api, bdContext, interfaceContext);
readerRegistry = new DelegatingReaderRegistry(Collections.<Reader<? extends DataObject>>singletonList(vppStateReader));
}
@@ -146,7 +160,14 @@ public class VppStateTest {
final Version version = getVersion();
whenShowVersionThenReturn(0, version);
- final List<BridgeDomainDetails> bdList = Arrays.asList(new BridgeDomainDetails(), new BridgeDomainDetails());
+ final BridgeDomainDetails bridgeDomainDetails = new BridgeDomainDetails();
+ final BridgeDomainDetails bridgeDomainDetails2 = new BridgeDomainDetails();
+ bridgeDomainDetails2.bdId = 1;
+
+ final List<BridgeDomainDetails> bdList = Arrays.asList(bridgeDomainDetails, bridgeDomainDetails2);
+ mockBdMapping(bridgeDomainDetails, "bd1");
+ mockBdMapping(bridgeDomainDetails2, "bd2");
+
whenBridgeDomainDumpThenReturn(bdList);
final Multimap<InstanceIdentifier<? extends DataObject>, ? extends DataObject> dataObjects = readerRegistry.readAll(ctx);
@@ -171,8 +192,10 @@ public class VppStateTest {
public void testReadBridgeDomains() throws Exception {
final Version version = getVersion();
whenShowVersionThenReturn(0, version);
- whenBridgeDomainDumpThenReturn(Collections.singletonList(new BridgeDomainDetails()));
+ final BridgeDomainDetails details = new BridgeDomainDetails();
+ whenBridgeDomainDumpThenReturn(Collections.singletonList(details));
+ mockBdMapping(details, "bdn1");
VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
Optional<? extends DataObject> read =
@@ -189,7 +212,9 @@ public class VppStateTest {
final BridgeDomainDetails bd = new BridgeDomainDetails();
bd.bdId = 0;
final String bdName = "bdn1";
- bdContext.addName(bd.bdId, bdName);
+ mockBdMapping(bd, bdName);
+ mockMapping("eth1", 0, "ifc-test-instance");
+
whenBridgeDomainDumpThenReturn(Collections.singletonList(bd));
final L2FibTableEntry l2FibEntry = new L2FibTableEntry();
l2FibEntry.bdId = 0;
@@ -204,18 +229,44 @@ public class VppStateTest {
assertTrue(read.isPresent());
// non existing l2fib
- read =
- readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
+ read = readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
BridgeDomain.class, new BridgeDomainKey("bdn1"))
.child(L2Fib.class, new L2FibKey(new PhysAddress("FF:FF:FF:04:05:06"))), ctx);
assertFalse(read.isPresent());
}
+ private void mockBdMapping(final BridgeDomainDetails bd, final String bdName) {
+ mockMapping(bdName, bd.bdId, "bd-test-instance");
+ }
+
+ private void mockMapping(final String name, final int id, final String namingContextName) {
+ final InstanceIdentifier<Mappings> mappingsIid = getMappingIid(name, namingContextName).firstIdentifierOf(Mappings.class);
+
+ final Optional<Mapping> singleMapping = getMapping(name, id);
+ final Optional<Mappings> previousMappings = mappingContext.read(mappingsIid);
+
+ final MappingsBuilder mappingsBuilder;
+ if(previousMappings != null && previousMappings.isPresent()) {
+ mappingsBuilder = new MappingsBuilder(previousMappings.get());
+ } else {
+ mappingsBuilder = new MappingsBuilder();
+ mappingsBuilder.setMapping(Lists.newArrayList());
+ }
+
+ final List<Mapping> mappingList = mappingsBuilder.getMapping();
+ mappingList.add(singleMapping.get());
+ doReturn(Optional.of(mappingsBuilder.setMapping(mappingList).build()))
+ .when(mappingContext).read(mappingsIid);
+ doReturn(singleMapping).when(mappingContext).read(getMappingIid(name, namingContextName));
+ }
+
@Test
public void testReadBridgeDomainAll() throws Exception {
final Version version = getVersion();
whenShowVersionThenReturn(0, version);
- whenBridgeDomainDumpThenReturn(Collections.singletonList(new BridgeDomainDetails()));
+ final BridgeDomainDetails details = new BridgeDomainDetails();
+ whenBridgeDomainDumpThenReturn(Collections.singletonList(details));
+ mockBdMapping(details, "bd2");
VppState readRoot = (VppState) readerRegistry.read(InstanceIdentifier.create(VppState.class), ctx).get();
@@ -234,7 +285,8 @@ public class VppStateTest {
final BridgeDomainDetails bd = new BridgeDomainDetails();
bd.bdId = 0;
final String bdName = "bdn1";
- bdContext.addName(bd.bdId, bdName);
+ mockBdMapping(bd, bdName);
+
whenBridgeDomainDumpThenReturn(Collections.singletonList(bd));
whenShowVersionThenReturn(0, getVersion());
@@ -245,12 +297,15 @@ public class VppStateTest {
BridgeDomain.class, new BridgeDomainKey(bdName)), ctx);
assertTrue(read.isPresent());
- assertEquals(Iterables.find(readRoot.getBridgeDomains().getBridgeDomain(),
- input -> input.getKey().getName().equals(bdName)), read.get());
+ assertEquals(readRoot.getBridgeDomains().getBridgeDomain().stream().filter(
+ input -> input.getKey().getName().equals(bdName)).findFirst().get(),
+ read.get());
}
@Test(expected = IllegalArgumentException.class)
public void testReadBridgeDomainNotExisting() throws Exception {
+ doReturn(Optional.absent()).when(mappingContext).read(getMappingIid("NOT EXISTING", "bd-test-instance"));
+
final Optional<? extends DataObject> read =
readerRegistry.read(InstanceIdentifier.create(VppState.class).child(BridgeDomains.class).child(
BridgeDomain.class, new BridgeDomainKey("NOT EXISTING")), ctx);
diff --git a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java
index 45ac193cf..e1a5bf2bc 100644
--- a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java
+++ b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/AbstractInterfaceTypeCustomizer.java
@@ -45,17 +45,17 @@ public abstract class AbstractInterfaceTypeCustomizer<D extends DataObject>
}
private void checkProperInterfaceType(@Nonnull final WriteContext writeContext,
- @Nonnull final InstanceIdentifier<D> id) {
+ @Nonnull final InstanceIdentifier<D> id) {
final InstanceIdentifier<Interface> ifcTypeFromIid = id.firstIdentifierOf(Interface.class);
checkArgument(ifcTypeFromIid != null, "Instance identifier does not contain {} type", Interface.class);
checkArgument(id.firstKeyOf(Interface.class) != null, "Instance identifier does not contain keyed {} type",
Interface.class);
- final Optional<DataObject> interfaceConfigOperational = writeContext.readAfter(ifcTypeFromIid);
- checkState(interfaceConfigOperational.isPresent(),
- "Unable to get Interface configuration for an interface being updated under ID");
+ final Optional<Interface> interfaceConfig = writeContext.readAfter(ifcTypeFromIid);
+ checkState(interfaceConfig.isPresent(),
+ "Unable to get Interface configuration for an interface: %s currently being updated", ifcTypeFromIid);
IllegalInterfaceTypeException
- .checkInterfaceType((Interface) interfaceConfigOperational.get(), getExpectedInterfaceType());
+ .checkInterfaceType(interfaceConfig.get(), getExpectedInterfaceType());
}
protected abstract Class<? extends InterfaceType> getExpectedInterfaceType();
diff --git a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/DataTreeNamingContext.java b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/DataTreeNamingContext.java
deleted file mode 100644
index 3b20b2876..000000000
--- a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/DataTreeNamingContext.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * 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.v3po.util;
-
-import com.google.common.collect.Lists;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import javax.annotation.Nonnull;
-import javax.annotation.concurrent.ThreadSafe;
-import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.Contexts;
-import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings;
-import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping;
-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.api.schema.tree.DataTree;
-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.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Naming context keeping a mapping between int index and string name.
- * Provides artificial names to unknown indices.
- */
-@ThreadSafe
-public class DataTreeNamingContext extends NamingContext {
-
- // FIXME this has to be accessed by readers/writers in a transactional manner and the transaction will only be committed once
- // the Read or Write operation finishes successfully
- // Context datatree has to become a first class citizen of Honeycomb, and Honeycomb needs to create and provide
- // context read write transaction as part of context to read/write customizers
- // This will then become just a utility writer relying on transaction provided by the infrastructure
- // Btw. the context transaction needs to disable commit/submit when being passed to customizers
-
- private static final Logger LOG = LoggerFactory.getLogger(DataTreeNamingContext.class);
-
- private static final QName NAME_KEY_QNAME = QName.create(Contexts.QNAME, "name");
- private static final QName INDEX_QNAME = QName.create(Contexts.QNAME, "index");
-
- private final String instanceName;
- private final DataTree contextDataTree;
-
- private final YangInstanceIdentifier.NodeIdentifierWithPredicates namingContextNodeId;
- private final YangInstanceIdentifier namingContextIid;
-
- public DataTreeNamingContext(final String artificialNamePrefix, final String instanceName,
- final DataTree contextDataTree) {
- super(artificialNamePrefix);
- this.instanceName = instanceName;
- this.contextDataTree = contextDataTree;
-
- namingContextNodeId = getNodeId(
- org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContext.QNAME,
- Collections.singletonMap(NAME_KEY_QNAME, instanceName));
- namingContextIid = YangInstanceIdentifier.create(
- getNodeId(Contexts.QNAME),
- getNodeId(org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContext.QNAME),
- namingContextNodeId);
-
- // FIXME read current mappings and initialize map
- mergeNewContextInDataTree(instanceName);
- }
-
- // TODO move the data tree aspect into a dedicated class
- private void mergeNewContextInDataTree(final String instanceName) {
- final DataTreeModification dataTreeModification = getModification();
-
- final YangInstanceIdentifier.NodeIdentifier namingContextsNodeIdForMapNode = getNodeId(
- org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContext.QNAME);
-
- final ContainerNode newMapping = Builders.containerBuilder()
- .withNodeIdentifier(getNodeId(Contexts.QNAME))
- .withChild(Builders.mapBuilder()
- .withNodeIdentifier(namingContextsNodeIdForMapNode)
- .withChild(Builders.mapEntryBuilder()
- .withNodeIdentifier(namingContextNodeId)
- .withChild(ImmutableNodes.leafNode(NAME_KEY_QNAME, instanceName))
- .withChild(Builders.containerBuilder()
- .withNodeIdentifier(getNodeId(Mappings.QNAME))
- .withChild(Builders.mapBuilder()
- .withNodeIdentifier(getNodeId(Mapping.QNAME))
- .build())
- .build())
- .build())
- .build())
- .build();
-
- // FIXME add logs or debug to resolve:
-// 2016-05-13 15:48:52,401 | WARN | config-pusher | DataTreeNamingContext | 240 - io.fd.honeycomb.v3po.vpp-translate-utils - 1.0.0.SNAPSHOT | Unable to update context: interface-context in context data tree
-// org.opendaylight.yangtools.yang.data.api.schema.tree.ModifiedNodeDoesNotExistException: Node /(urn:honeycomb:params:xml:ns:yang:naming:context?revision=2016-05-13)contexts/naming-context/naming-context[{(urn:honeycomb:params:xml:ns:yang:naming:context?revision=2016-05-13)name=interface-context}] does not exist. Cannot apply modification to its children.
-// at org.opendaylight.yangtools.yang.data.impl.schema.tree.AbstractNodeContainerModificationStrategy.checkTouchApplicable(AbstractNodeContainerModificationStrategy.java:276)[55:org.opendaylight.yangtools.yang-data-impl:0.8.0.Beryllium]
- // FIXME looks like a timing issue, did not occur when debugging
-
- dataTreeModification.merge(YangInstanceIdentifier.create(getNodeId(Contexts.QNAME)), newMapping);
-
- commitModification(dataTreeModification);
- }
-
- private void commitModification(final DataTreeModification dataTreeModification) {
- try {
- dataTreeModification.ready();
- contextDataTree.validate(dataTreeModification);
- contextDataTree.commit(contextDataTree.prepare(dataTreeModification));
- } catch (DataValidationFailedException e) {
- LOG.warn("Unable to update context: {} in context data tree", instanceName, e);
- throw new IllegalStateException("Unable to update context in context data tree", e);
- }
- }
-
- private DataTreeModification getModification() {
- final DataTreeSnapshot dataTreeSnapshot = contextDataTree.takeSnapshot();
- return dataTreeSnapshot.newModification();
- }
-
- private static YangInstanceIdentifier.NodeIdentifierWithPredicates getNodeId(@Nonnull final QName qName,
- @Nonnull final Map<QName, Object> keys) {
- return new YangInstanceIdentifier.NodeIdentifierWithPredicates(qName, keys);
- }
-
- private static YangInstanceIdentifier.NodeIdentifier getNodeId(@Nonnull final QName qName) {
- return new YangInstanceIdentifier.NodeIdentifier(qName);
- }
-
- public synchronized void addName(final int index, final String name) {
- addMappingToDataTree(name, index);
- super.addName(index, name);
- }
-
- private void addMappingToDataTree(final String name, final int index) {
- final DataTreeModification dataTreeModification = getModification();
-
- final YangInstanceIdentifier.NodeIdentifierWithPredicates mappingNodeId = getNodeId(Mapping.QNAME,
- Collections.singletonMap(NAME_KEY_QNAME, name));
-
- final List<YangInstanceIdentifier.PathArgument> pathArguments = namingContextIid.getPathArguments();
- final ArrayList<YangInstanceIdentifier.PathArgument> newPathArgs = Lists.newArrayList(pathArguments);
- newPathArgs.add(getNodeId(Mappings.QNAME));
- newPathArgs.add(getNodeId(Mapping.QNAME));
- newPathArgs.add(mappingNodeId);
-
- final YangInstanceIdentifier identifier = YangInstanceIdentifier.create(newPathArgs);
-
- final NormalizedNode<?, ?> newMapping = Builders.mapEntryBuilder()
- .withNodeIdentifier(mappingNodeId)
- .withChild(ImmutableNodes.leafNode(NAME_KEY_QNAME, name))
- .withChild(ImmutableNodes.leafNode(INDEX_QNAME, index))
- .build();
-
- dataTreeModification.write(identifier, newMapping);
-
- commitModification(dataTreeModification);
- }
-
- public synchronized int removeName(@Nonnull final String name) {
- removeMappingFromDataTree(name);
- return super.removeName(name);
- }
-
- private void removeMappingFromDataTree(final String name) {
- final DataTreeModification dataTreeModification = getModification();
-
- final YangInstanceIdentifier.NodeIdentifierWithPredicates mappingNodeId = getNodeId(Mapping.QNAME,
- Collections.singletonMap(NAME_KEY_QNAME, name));
-
- final YangInstanceIdentifier identifier = YangInstanceIdentifier.create(
- namingContextIid.getLastPathArgument(), getNodeId(Mappings.QNAME), getNodeId(Mapping.QNAME), mappingNodeId);
-
- dataTreeModification.delete(identifier);
-
- commitModification(dataTreeModification);
- }
-}
diff --git a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/NamingContext.java b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/NamingContext.java
index 9affd0695..d32f27203 100644
--- a/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/NamingContext.java
+++ b/v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/NamingContext.java
@@ -17,48 +17,88 @@
package io.fd.honeycomb.v3po.translate.v3po.util;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
-import com.google.common.collect.BiMap;
-import com.google.common.collect.HashBiMap;
+import com.google.common.base.Optional;
+import io.fd.honeycomb.v3po.translate.MappingContext;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.Contexts;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContextKey;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.Mappings;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.Mapping;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.MappingBuilder;
+import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.naming.context.mappings.MappingKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * Naming context keeping a mapping between int index and string name.
- * Provides artificial names to unknown indices.
+ * Utility adapter on top of {@link MappingContext}
*/
-public class NamingContext implements AutoCloseable {
+public final class NamingContext implements AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(NamingContext.class);
- private final BiMap<String, Integer> nameMapping = HashBiMap.create();
private final String artificialNamePrefix;
+ private KeyedInstanceIdentifier<org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContext, NamingContextKey>
+ namingContextIid;
- public NamingContext(final String artificialNamePrefix) {
+ /**
+ * Collector expecting only a single resulting item from a stream
+ */
+ private static final Collector<Mapping, ?, Mapping> SINGLE_ITEM_COLLECTOR = Collectors.collectingAndThen(
+ Collectors.toList(),
+ list -> {
+ if (list.size() != 1) {
+ throw new IllegalStateException("Unexpected size of list: " + list + ". Single item expected");
+ }
+ return list.get(0);
+ });
+
+ public NamingContext(final String artificialNamePrefix, final String instanceName) {
this.artificialNamePrefix = artificialNamePrefix;
+ namingContextIid = InstanceIdentifier.create(Contexts.class).child(
+ org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.contexts.NamingContext.class,
+ new NamingContextKey(instanceName));
}
@Nonnull
- public synchronized String getName(final int index) {
- if(!nameMapping.inverse().containsKey(index)) {
+ public synchronized String getName(final int index, final MappingContext mappingContext) {
+ if (!containsName(index, mappingContext)) {
final String artificialName = getArtificialName(index);
LOG.info("Assigning artificial name: {} for index: {}", artificialName, index);
- addName(index, artificialName);
+ addName(index, artificialName, mappingContext);
}
- return nameMapping.inverse().get(index);
+
+ final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class));
+ checkState(read.isPresent(), "Mapping for index: %s is not present. But should be", index);
+
+ return read.get().getMapping().stream()
+ .filter(mapping -> mapping.getIndex().equals(index))
+ .collect(SINGLE_ITEM_COLLECTOR).getName();
+ }
+
+ public synchronized boolean containsName(final int index, final MappingContext mappingContext) {
+ final Optional<Mappings> read = mappingContext.read(namingContextIid.child(Mappings.class));
+ return read.isPresent()
+ ? read.get().getMapping().stream().anyMatch(mapping -> mapping.getIndex().equals(index))
+ : false;
}
- public synchronized boolean containsName(final int index) {
- return nameMapping.inverse().containsKey(index);
+ public synchronized void addName(final int index, final String name, final MappingContext mappingContext) {
+ final KeyedInstanceIdentifier<Mapping, MappingKey> mappingIid = getMappingIid(name);
+ mappingContext.put(mappingIid, new MappingBuilder().setIndex(index).setName(name).build());
}
- public synchronized void addName(final int index, final String name) {
- nameMapping.put(name, index);
+ private KeyedInstanceIdentifier<Mapping, MappingKey> getMappingIid(final String name) {
+ return namingContextIid.child(Mappings.class).child(Mapping.class, new MappingKey(name));
}
- public synchronized int removeName(final String name) {
- return nameMapping.remove(name);
+ public synchronized void removeName(final String name, final MappingContext mappingContext) {
+ mappingContext.delete(getMappingIid(name));
}
/**
@@ -68,14 +108,15 @@ public class NamingContext implements AutoCloseable {
* @return integer index value matching supplied name
* @throws IllegalArgumentException if name was not found
*/
- public synchronized int getIndex(String name) {
- checkArgument(nameMapping.containsKey(name), "Name %s not found. Known names: %s",
- name, nameMapping);
- return nameMapping.get(name);
+ public synchronized int getIndex(final String name, final MappingContext mappingContext) {
+ final Optional<Mapping> read = mappingContext.read(getMappingIid(name));
+ checkArgument(read.isPresent(), "No mapping stored for name: %s", name);
+ return read.get().getIndex();
+
}
- public synchronized boolean containsIndex(String interfaceName) {
- return nameMapping.containsKey(interfaceName);
+ public synchronized boolean containsIndex(final String name, final MappingContext mappingContext) {
+ return mappingContext.read(getMappingIid(name)).isPresent();
}
private String getArtificialName(final int index) {
@@ -84,6 +125,6 @@ public class NamingContext implements AutoCloseable {
@Override
public void close() throws Exception {
- nameMapping.clear();
+ /// Not removing the mapping from backing storage
}
}
diff --git a/v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModule.java b/v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModule.java
index 50b577a25..60a816d89 100644
--- a/v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModule.java
+++ b/v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModule.java
@@ -1,6 +1,6 @@
package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.util.rev160406;
-import io.fd.honeycomb.v3po.translate.v3po.util.DataTreeNamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.NamingContext;
public class NamingContextImplModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.vpp.util.rev160406.AbstractNamingContextImplModule {
public NamingContextImplModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -18,10 +18,9 @@ public class NamingContextImplModule extends org.opendaylight.yang.gen.v1.urn.ho
@Override
public java.lang.AutoCloseable createInstance() {
- return new DataTreeNamingContext(
+ return new NamingContext(
getArtificialNamePrefix(),
- getIdentifier().getInstanceName(),
- getContextDataTreeDependency());
+ getIdentifier().getInstanceName());
}
}
diff --git a/v3po/vpp-translate-utils/src/main/yang/vpp-util.yang b/v3po/vpp-translate-utils/src/main/yang/vpp-util.yang
index bd903848c..23615d09e 100644
--- a/v3po/vpp-translate-utils/src/main/yang/vpp-util.yang
+++ b/v3po/vpp-translate-utils/src/main/yang/vpp-util.yang
@@ -31,15 +31,6 @@ module vpp-util {
leaf artificial-name-prefix {
type string;
}
-
- container context-data-tree {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity dapi:data-tree;
- }
- }
- }
}
}