HONEYCOMB-61: Add context data tree
authorMaros Marsalek <[email protected]>
Mon, 16 May 2016 08:43:29 +0000 (10:43 +0200)
committerMaros Marsalek <[email protected]>
Mon, 23 May 2016 09:23:58 +0000 (09:23 +0000)
For storing mapping related context necessary for the plugins
Add naming context adapter to store naming contexts in the data tree

+ Enable persistence for context data tree

Change-Id: I2ac531e80e71a48d313b065997d134da2ae7ee12
Signed-off-by: Maros Marsalek <[email protected]>
15 files changed:
v3po/data-api/src/main/yang/data-api.yang
v3po/data-impl/src/main/yang/data-impl.yang
v3po/features/pom.xml
v3po/features/src/main/features/features.xml
v3po/impl/pom.xml
v3po/impl/src/main/config/context-datatree-config.xml [new file with mode: 0644]
v3po/impl/src/main/config/default-config.xml
v3po/v3po2vpp/src/main/config/default-config.xml
v3po/v3po2vpp/src/test/java/io/fd/honeycomb/v3po/translate/v3po/interfacesstate/SubInterfaceCustomizerTest.java
v3po/vpp-translate-utils/pom.xml
v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/DataTreeNamingContext.java [new file with mode: 0644]
v3po/vpp-translate-utils/src/main/java/io/fd/honeycomb/v3po/translate/v3po/util/NamingContext.java
v3po/vpp-translate-utils/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/vpp/util/rev160406/NamingContextImplModule.java
v3po/vpp-translate-utils/src/main/yang/naming-context.yang [new file with mode: 0644]
v3po/vpp-translate-utils/src/main/yang/vpp-util.yang

index 0a01a42..92def4b 100644 (file)
@@ -14,6 +14,11 @@ module data-api {
             "Initial revision.";
     }
 
+    identity data-tree {
+        base "config:service-type";
+        config:java-class org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
+    }
+
     identity honeycomb-readable-data-tree {
         base "config:service-type";
         config:java-class io.fd.honeycomb.v3po.data.ReadableDataTree;
index da1c023..454e99a 100644 (file)
@@ -18,14 +18,9 @@ module data-impl {
             "Initial revision.";
     }
 
-    identity data-tree {
-        base "config:service-type";
-        config:java-class org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree;
-    }
-
     identity inmemory-data-tree {
         base config:module-type;
-        config:provided-service data-tree;
+        config:provided-service dapi:data-tree;
         config:java-name-prefix InMemoryDataTree;
     }
 
@@ -57,7 +52,7 @@ module data-impl {
 
     identity persisting-data-tree-adapter {
         base config:module-type;
-        config:provided-service data-tree;
+        config:provided-service dapi:data-tree;
         config:java-name-prefix PersistingDataTreeAdapter;
     }
 
@@ -69,7 +64,7 @@ module data-impl {
                 uses config:service-ref {
                     refine type {
                         mandatory true;
-                        config:required-identity data-tree;
+                        config:required-identity dapi:data-tree;
                     }
                 }
             }
@@ -103,7 +98,7 @@ module data-impl {
                 uses config:service-ref {
                     refine type {
                         mandatory true;
-                        config:required-identity data-tree;
+                        config:required-identity dapi:data-tree;
                     }
                 }
             }
index c413c6c..1233f7d 100644 (file)
       <type>xml</type>
       <classifier>netconf</classifier>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>v3po-impl</artifactId>
+      <version>${project.version}</version>
+      <type>xml</type>
+      <classifier>context</classifier>
+    </dependency>
     <dependency>
       <groupId>${project.groupId}</groupId>
       <artifactId>v3po-impl</artifactId>
index f46e552..66e57fc 100644 (file)
@@ -47,6 +47,7 @@
     <bundle>mvn:io.fd.honeycomb.v3po/v3po2vpp/${project.version}</bundle>
     <bundle>mvn:io.fd.honeycomb.v3po/vpp-cfg-init/${project.version}</bundle>
     <configfile finalname="${configfile.directory}/vpp-jvpp.xml">mvn:io.fd.honeycomb.v3po/vpp-jvpp-cfg/${project.version}/xml/config</configfile>
+    <configfile finalname="${configfile.directory}/v3po-context.xml">mvn:io.fd.honeycomb.v3po/v3po-impl/${project.version}/xml/context</configfile>
     <configfile finalname="${configfile.directory}/v3po.xml">mvn:io.fd.honeycomb.v3po/v3po-impl/${project.version}/xml/config</configfile>
     <configfile finalname="${configfile.directory}/v3po-netconf.xml">mvn:io.fd.honeycomb.v3po/v3po-impl/${project.version}/xml/netconf</configfile>
     <configfile finalname="${configfile.directory}/v3po-restconf.xml">mvn:io.fd.honeycomb.v3po/v3po-impl/${project.version}/xml/restconf</configfile>
index 053e0ff..6db420b 100644 (file)
                   <type>xml</type>
                   <classifier>netconf</classifier>
                 </artifact>
+                <artifact>
+                  <file>src/main/config/context-datatree-config.xml</file>
+                  <type>xml</type>
+                  <classifier>context</classifier>
+                </artifact>
                 <artifact>
                   <file>src/main/config/restconf-north-config.xml</file>
                   <type>xml</type>
diff --git a/v3po/impl/src/main/config/context-datatree-config.xml b/v3po/impl/src/main/config/context-datatree-config.xml
new file mode 100644 (file)
index 0000000..c9f9902
--- /dev/null
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright (c) 2016 Cisco and/or its affiliates.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at:
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+
+<snapshot>
+  <required-capabilities>
+      <capability>urn:opendaylight:params:xml:ns:yang:v3po:impl?module=v3po-impl&amp;revision=2014-12-10</capability>
+      <capability>urn:honeycomb:params:xml:ns:yang:translate:utils?module=translate-utils&amp;revision=2016-04-06</capability>
+      <capability>urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg?module=vpp-jvpp-cfg&amp;revision=2016-04-06</capability>
+      <capability>urn:honeycomb:params:xml:ns:yang:vpp:data:init?module=vpp-cfg-init&amp;revision=2016-04-07</capability>
+      <capability>urn:honeycomb:params:xml:ns:yang:data:api?module=data-api&amp;revision=2016-04-11</capability>
+      <capability>urn:honeycomb:params:xml:ns:yang:data:impl?module=data-impl&amp;revision=2016-04-11</capability>
+      <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
+  </required-capabilities>
+  <configuration>
+
+    <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+      <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+
+        <!-- TODO provide information stored in context data-tree to users as part of operational data -->
+        <!-- In-memory data tree for context(special data required for YANG <-> VPP mapping) data -->
+        <module>
+          <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:impl">prefix:inmemory-data-tree</type>
+          <name>inmemory-context-data-tree</name>
+          <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>
+          <type xmlns="urn:honeycomb:params:xml:ns:yang:data:impl">oper</type>
+        </module>
+
+        <!-- DataTree adapter with persistence for context DT -->
+        <module>
+          <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:impl">prefix:persisting-data-tree-adapter</type>
+          <name>inmemory-persisted-context-data-tree</name>
+          <delegate>
+            <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:data-tree</type>
+            <name>inmemory-context-data-tree</name>
+          </delegate>
+          <schema-service>
+            <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
+            <name>yang-schema-service</name>
+          </schema-service>
+          <persist-file-path>etc/opendaylight/honeycomb/context.json</persist-file-path>
+        </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>
+          <instance>
+            <name>inmemory-context-data-tree</name>
+            <provider>/modules/module[type='inmemory-data-tree'][name='inmemory-context-data-tree']
+            </provider>
+          </instance>
+          <instance>
+            <name>inmemory-persisted-context-data-tree</name>
+            <provider>/modules/module[type='persisting-data-tree-adapter'][name='inmemory-persisted-context-data-tree']
+            </provider>
+          </instance>
+        </service>
+      </services>
+    </data>
+  </configuration>
+</snapshot>
index 61fe1c6..89e1f7c 100644 (file)
@@ -20,6 +20,7 @@
       <capability>urn:honeycomb:params:xml:ns:yang:translate:utils?module=translate-utils&amp;revision=2016-04-06</capability>
       <capability>urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg?module=vpp-jvpp-cfg&amp;revision=2016-04-06</capability>
       <capability>urn:honeycomb:params:xml:ns:yang:vpp:data:init?module=vpp-cfg-init&amp;revision=2016-04-07</capability>
+      <capability>urn:honeycomb:params:xml:ns:yang:data:api?module=data-api&amp;revision=2016-04-11</capability>
       <capability>urn:honeycomb:params:xml:ns:yang:data:impl?module=data-impl&amp;revision=2016-04-11</capability>
       <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&amp;revision=2013-10-28</capability>
   </required-capabilities>
@@ -53,7 +54,7 @@
           <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:impl">prefix:persisting-data-tree-adapter</type>
           <name>inmemory-persisted-config-data-tree</name>
           <delegate>
-            <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:impl">prefix:data-tree</type>
+            <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:data-tree</type>
             <name>inmemory-config-data-tree</name>
           </delegate>
           <schema-service>
@@ -75,7 +76,7 @@
           <!--</data-tree>-->
           <!-- With persistence -->
           <data-tree>
-            <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:impl">prefix:data-tree</type>
+            <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:data-tree</type>
             <name>inmemory-persisted-config-data-tree</name>
           </data-tree>
 
           <!--</data-tree>-->
           <!-- With persistence -->
           <data-tree>
-            <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:impl">prefix:data-tree</type>
+            <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:data-tree</type>
             <name>inmemory-persisted-config-data-tree</name>
           </data-tree>
 
         </service>
 
         <service>
-          <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:impl">prefix:data-tree</type>
+          <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:data:api">prefix:data-tree</type>
           <instance>
             <name>inmemory-config-data-tree</name>
             <provider>/modules/module[type='inmemory-data-tree'][name='inmemory-config-data-tree']
index cd736ed..02b0b7b 100644 (file)
@@ -21,6 +21,7 @@
     <required-capabilities>
         <capability>urn:honeycomb:params:xml:ns:yang:vpp:jvpp:cfg?module=vpp-jvpp-cfg&amp;revision=2016-04-06</capability>
         <capability>urn:honeycomb:params:xml:ns:yang:v3po2vpp?module=v3po2vpp&amp;revision=2016-04-06</capability>
+        <capability>urn:honeycomb:params:xml:ns:yang:data:api?module=data-api&amp;revision=2016-04-11</capability>
         <capability>urn:honeycomb:params:xml:ns:yang:vpp:util?module=vpp-util&amp;revision=2016-04-06</capability>
     </required-capabilities>
     <configuration>
                     <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>
index 211f818..8ed35e0 100644 (file)
@@ -89,7 +89,6 @@ public class SubInterfaceCustomizerTest extends ChildReaderCustomizerTest<SubInt
         getCustomizer().readCurrentAttributes(getSubInterfaceId(ifName), builder, ctx);
 
         verify(builder).setIdentifier((long)ifId);
-        verify(builder).setSuperInterface(interfacesContext.getArtificialName(0));
         verify(builder).setNumberOfTags((short)0);
         verify(builder).setVlanType(VlanType._802dot1ad);
         verify(builder, never()).setExactMatch(any());
index 5a96950..ee931c5 100644 (file)
             <groupId>org.opendaylight.mdsal.model</groupId>
             <artifactId>ietf-interfaces</artifactId>
         </dependency>
+        <dependency>
+            <groupId>io.fd.honeycomb.v3po</groupId>
+            <artifactId>data-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
 
         <!-- Testing Dependencies -->
         <dependency>
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
new file mode 100644 (file)
index 0000000..3b20b28
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * 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);
+    }
+}
index 96d908e..9affd06 100644 (file)
@@ -28,7 +28,7 @@ import org.slf4j.LoggerFactory;
  * Naming context keeping a mapping between int index and string name.
  * Provides artificial names to unknown indices.
  */
-public final class NamingContext implements AutoCloseable {
+public class NamingContext implements AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(NamingContext.class);
 
@@ -49,17 +49,14 @@ public final class NamingContext implements AutoCloseable {
         return nameMapping.inverse().get(index);
     }
 
-    @Nonnull
     public synchronized boolean containsName(final int index) {
         return nameMapping.inverse().containsKey(index);
     }
 
-    @Nonnull
     public synchronized void addName(final int index, final String name) {
         nameMapping.put(name, index);
     }
 
-    @Nonnull
     public synchronized int removeName(final String name) {
         return nameMapping.remove(name);
     }
@@ -71,19 +68,17 @@ public final class NamingContext implements AutoCloseable {
      * @return integer index value matching supplied name
      * @throws IllegalArgumentException if name was not found
      */
-    @Nonnull
     public synchronized int getIndex(String name) {
         checkArgument(nameMapping.containsKey(name), "Name %s not found. Known names: %s",
                 name, nameMapping);
         return nameMapping.get(name);
     }
 
-    @Nonnull
     public synchronized boolean containsIndex(String interfaceName) {
         return nameMapping.containsKey(interfaceName);
     }
 
-    public String getArtificialName(final int index) {
+    private String getArtificialName(final int index) {
         return artificialNamePrefix + index;
     }
 
index 81cecb1..50b577a 100644 (file)
@@ -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.NamingContext;
+import io.fd.honeycomb.v3po.translate.v3po.util.DataTreeNamingContext;
 
 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,7 +18,10 @@ public class NamingContextImplModule extends org.opendaylight.yang.gen.v1.urn.ho
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        return new NamingContext(getArtificialNamePrefix());
+        return new DataTreeNamingContext(
+            getArtificialNamePrefix(),
+            getIdentifier().getInstanceName(),
+            getContextDataTreeDependency());
     }
 
 }
diff --git a/v3po/vpp-translate-utils/src/main/yang/naming-context.yang b/v3po/vpp-translate-utils/src/main/yang/naming-context.yang
new file mode 100644 (file)
index 0000000..0bcfc09
--- /dev/null
@@ -0,0 +1,42 @@
+module naming-context {
+    yang-version 1;
+    namespace "urn:honeycomb:params:xml:ns:yang:naming:context";
+    prefix "vpp-u";
+
+    description
+        "This module contains data definition for naming mapping context";
+
+    revision "2016-05-13" {
+        description
+            "Initial revision.";
+    }
+
+    // TODO This should become part of v3po-api as operational-only data
+    container contexts {
+
+        list naming-context {
+
+            key "name";
+
+            leaf name {
+                type string;
+            }
+
+            container mappings {
+                list mapping {
+
+                    key "name";
+
+                    leaf name {
+                        type string;
+                    }
+
+                    leaf index {
+                        type int32;
+                    }
+                }
+            }
+        }
+    }
+
+}
\ No newline at end of file
index 01e759d..bd90384 100644 (file)
@@ -4,6 +4,7 @@ module vpp-util {
     prefix "vpp-u";
 
     import config { prefix config; revision-date 2013-04-05; }
+    import data-api { prefix dapi; revision-date 2016-04-11; }
 
     description
         "This module contains utilities for vpp readers/writers";
@@ -31,6 +32,14 @@ module vpp-util {
                 type string;
             }
 
+            container context-data-tree {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity dapi:data-tree;
+                    }
+                }
+            }
         }
     }