Merge "BUG-832 Add initial configuration for controller self mount"
authorTony Tkacik <ttkacik@cisco.com>
Fri, 25 Apr 2014 08:02:04 +0000 (08:02 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Fri, 25 Apr 2014 08:02:04 +0000 (08:02 +0000)
21 files changed:
opendaylight/commons/opendaylight/pom.xml
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/md/sal/binding/impl/AbstractForwardedTransaction.java
opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/md/sal/binding/data/ConcurrentImplicitCreateTest.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMDataBrokerImpl.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/compat/BackwardsCompatibleTransaction.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/MutableDataTree.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/OperationWithModification.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/ResolveDataChangeEventsTask.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SchemaAwareApplyOperation.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/ModificationType.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/tree/NodeModification.java
opendaylight/md-sal/sal-dom-spi/src/main/java/org/opendaylight/controller/sal/core/spi/data/DOMStoreWriteTransaction.java
opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/handler/NetconfMessageToEXIEncoder.java
opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/EXILibTest.java [deleted file]
opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java
third-party/org.openexi/nagasena-rta/nagasena-rta-0000.0002.0038.0.jar [moved from third-party/org.openexi/nagasena-rta/nagasena-rta-0000.0002.0035.0.jar with 85% similarity]
third-party/org.openexi/nagasena-rta/pom.xml
third-party/org.openexi/nagasena/nagasena-0000.0002.0038.0.jar [moved from third-party/org.openexi/nagasena/nagasena-0000.0002.0035.0.jar with 80% similarity]
third-party/org.openexi/nagasena/pom.xml
third-party/org.openexi/pom.xml

index 3839d5b2cb527373e4509f73094991dc8a7c520c..4a7a395693e76b3ff31018ee2b218ca5047f62d7 100644 (file)
@@ -40,7 +40,7 @@
     <exam.version>3.0.0</exam.version>
 
     <!-- OpenEXI third party lib for netconf-->
-    <exi.nagasena.version>0000.0002.0035.0-SNAPSHOT</exi.nagasena.version>
+    <exi.nagasena.version>0000.0002.0038.0-SNAPSHOT</exi.nagasena.version>
     <failsafe.version>2.15</failsafe.version>
     <forwarding.staticrouting>0.5.2-SNAPSHOT</forwarding.staticrouting>
     <forwardingrulesmanager.version>0.6.0-SNAPSHOT</forwardingrulesmanager.version>
index 6334457fd4961ae34d913fb9138a8313f6eb30b1..6bd6e6aaf52294ed0ada1b2809995ea1b7877260 100644 (file)
@@ -132,7 +132,7 @@ public class AbstractForwardedTransaction<T extends AsyncTransaction<org.openday
             }
 
             if (!d.isPresent() && iterator.hasNext()) {
-                writeTransaction.put(store, currentPath, currentOp.createDefault(currentArg));
+                writeTransaction.merge(store, currentPath, currentOp.createDefault(currentArg));
             }
         }
         //LOG .info("Tx: {} : Putting data {}",getDelegate().getIdentifier(),normalized.getKey());
diff --git a/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/md/sal/binding/data/ConcurrentImplicitCreateTest.java b/opendaylight/md-sal/sal-binding-dom-it/src/test/java/org/opendaylight/controller/md/sal/binding/data/ConcurrentImplicitCreateTest.java
new file mode 100644 (file)
index 0000000..61a73d6
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.md.sal.binding.data;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.controller.sal.binding.test.AbstractDataServiceTest;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+public class ConcurrentImplicitCreateTest extends AbstractDataServiceTest {
+
+    private static final NodeKey NODE_FOO_KEY = new NodeKey(new NodeId("foo"));
+    private static final NodeKey NODE_BAR_KEY = new NodeKey(new NodeId("foo"));
+    private static InstanceIdentifier<Nodes> NODES_PATH = InstanceIdentifier.builder(Nodes.class).build();
+    private static InstanceIdentifier<Node> NODE_FOO_PATH = InstanceIdentifier.builder(NODES_PATH)
+            .child(Node.class, NODE_FOO_KEY).build();
+    private static InstanceIdentifier<Node> NODE_BAR_PATH = InstanceIdentifier.builder(NODES_PATH)
+            .child(Node.class, NODE_FOO_KEY).build();
+
+    @Test
+    public void testConcurrentCreate() throws InterruptedException, ExecutionException {
+
+        DataModificationTransaction fooTx = baDataService.beginTransaction();
+        DataModificationTransaction barTx = baDataService.beginTransaction();
+
+        fooTx.putOperationalData(NODE_FOO_PATH, new NodeBuilder().setKey(NODE_FOO_KEY).build());
+        barTx.putOperationalData(NODE_BAR_PATH, new NodeBuilder().setKey(NODE_BAR_KEY).build());
+
+        Future<RpcResult<TransactionStatus>> fooFuture = fooTx.commit();
+        Future<RpcResult<TransactionStatus>> barFuture = barTx.commit();
+
+        RpcResult<TransactionStatus> fooResult = fooFuture.get();
+        RpcResult<TransactionStatus> barResult = barFuture.get();
+
+        assertTrue(fooResult.isSuccessful());
+        assertTrue(barResult.isSuccessful());
+
+        assertEquals(TransactionStatus.COMMITED, fooResult.getResult());
+        assertEquals(TransactionStatus.COMMITED, barResult.getResult());
+
+    }
+}
index 64a5606e3fb613a04a70a76cff65a83759cdd589..608ac9bc68d120c39d96b0389bbed324ba01652e 100644 (file)
@@ -217,8 +217,7 @@ public class DOMDataBrokerImpl implements DOMDataBroker, AutoCloseable {
         @Override
         public void merge(final LogicalDatastoreType store, final InstanceIdentifier path,
                 final NormalizedNode<?, ?> data) {
-            // TODO Auto-generated method stub
-            throw new UnsupportedOperationException("Not implemented yet.");
+            getSubtransaction(store).merge(path,data);
         }
 
         @Override
@@ -251,12 +250,6 @@ public class DOMDataBrokerImpl implements DOMDataBroker, AutoCloseable {
                 final InstanceIdentifier path) {
             return getSubtransaction(store).read(path);
         }
-
-        @Override
-        public void merge(final LogicalDatastoreType store, final InstanceIdentifier path,
-                final NormalizedNode<?, ?> data) {
-
-        }
     }
 
     private final class CommitCoordination implements Callable<RpcResult<TransactionStatus>> {
index b905d2f673d77e01a4b8ee56cd0ca09ffddc14c8..29f2af511e8b8bb03ab0921837b8acae80aa59a7 100644 (file)
@@ -32,21 +32,13 @@ import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
 import com.google.common.util.concurrent.ListenableFuture;
 
 public abstract class BackwardsCompatibleTransaction<T extends DOMDataReadTransaction> implements
@@ -249,7 +241,7 @@ public abstract class BackwardsCompatibleTransaction<T extends DOMDataReadTransa
                 InstanceIdentifier currentPath = new InstanceIdentifier(currentArguments);
                 boolean isPresent = getDelegate().read(store, currentPath).get().isPresent();
                 if(isPresent == false && iterator.hasNext()) {
-                    getDelegate().put(store, currentPath, currentOp.createDefault(currentArg));
+                    getDelegate().merge(store, currentPath, currentOp.createDefault(currentArg));
                 }
             }
             } catch (InterruptedException | ExecutionException e) {
@@ -259,48 +251,6 @@ public abstract class BackwardsCompatibleTransaction<T extends DOMDataReadTransa
             getDelegate().put(store, normalizedPath, normalizedData);
         }
 
-        private boolean isAugmentationChild(final InstanceIdentifier normalizedPath) {
-            List<PathArgument> parentArgs = parentPath(normalizedPath).getPath();
-            if(parentArgs.isEmpty()) {
-                return false;
-            }
-            return Iterables.getLast(parentArgs) instanceof AugmentationIdentifier;
-        }
-
-        private void ensureParentNode(final LogicalDatastoreType store, final InstanceIdentifier normalizedPath,
-                final NormalizedNode<?, ?> normalizedData) {
-            InstanceIdentifier parentPath = parentPath(normalizedPath);
-            PathArgument parentType = Iterables.getLast(parentPath.getPath());
-            if(parentType instanceof AugmentationIdentifier) {
-                AugmentationNode node = Builders.augmentationBuilder()
-                        .withNodeIdentifier((AugmentationIdentifier) parentType)
-                        .build();
-                getDelegate().put(store, parentPath, node);
-            }
-            if(normalizedData instanceof MapEntryNode) {
-                MapNode mapNode = Builders.mapBuilder().withNodeIdentifier(new NodeIdentifier(normalizedData.getNodeType())).build();
-                getDelegate().put(store, parentPath, mapNode);
-            } else if (normalizedData instanceof LeafSetNode<?>){
-                LeafSetNode<Object> leafNode = Builders.leafSetBuilder().withNodeIdentifier(new NodeIdentifier(normalizedData.getNodeType())).build();
-                getDelegate().put(store, parentPath, leafNode);
-            }
-
-
-        }
-
-        private InstanceIdentifier parentPath(final InstanceIdentifier normalizedPath) {
-            List<PathArgument> childArgs = normalizedPath.getPath();
-            return new InstanceIdentifier(childArgs.subList(0, childArgs.size() -1));
-        }
-
-        private boolean parentNodeDoesNotExists(final LogicalDatastoreType store, final InstanceIdentifier normalizedPath) {
-            try {
-                return !getDelegate().read(store, parentPath(normalizedPath)).get().isPresent();
-            } catch (InterruptedException | ExecutionException e) {
-                throw new IllegalStateException(e);
-            }
-        }
-
         @Override
         public void removeConfigurationData(final InstanceIdentifier legacyPath) {
             checkNotNull(legacyPath, "Path MUST NOT be null.");
index 6c0e5823a49f885520f902cea0647499e715482b..9bbba1e24d8600f196f23df145105d1b787e9c6e 100644 (file)
@@ -258,6 +258,18 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, Sch
             }
         }
 
+        @Override
+        public void merge(final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
+            checkNotReady();
+            try {
+                LOG.trace("Tx: {} Merge: {}:{}",getIdentifier(),path,data);
+                mutableTree.merge(path, data);
+              // FIXME: Add checked exception
+            } catch (Exception e) {
+                LOG.error("Tx: {}, failed to write {}:{} in {}",getIdentifier(),path,data,mutableTree,e);
+            }
+        }
+
         @Override
         public void delete(final InstanceIdentifier path) {
             checkNotReady();
index bc7fe7a2c7aa69dc6bf6979497abd480d147863c..b711163b465d3ca07914da3d3472347ab854533e 100644 (file)
@@ -18,6 +18,7 @@ import org.opendaylight.controller.md.sal.dom.store.impl.tree.TreeNodeUtils;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -47,6 +48,24 @@ class MutableDataTree {
         resolveModificationFor(path).write(value);
     }
 
+    public void merge(final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        checkSealed();
+        mergeImpl(resolveModificationFor(path),data);
+    }
+
+    private void mergeImpl(final OperationWithModification op,final NormalizedNode<?,?> data) {
+
+        if(data instanceof NormalizedNodeContainer<?,?,?>) {
+            @SuppressWarnings({ "rawtypes", "unchecked" })
+            NormalizedNodeContainer<?,?,NormalizedNode<PathArgument, ?>> dataContainer = (NormalizedNodeContainer) data;
+            for(NormalizedNode<PathArgument, ?> child : dataContainer.getValue()) {
+                PathArgument childId = child.getIdentifier();
+                mergeImpl(op.forChild(childId), child);
+            }
+        }
+        op.merge(data);
+    }
+
     public void delete(final InstanceIdentifier path) {
         checkSealed();
         resolveModificationFor(path).delete();
index eaf01aeecda8d60e0cb7913678b1747665876ce1..35864b6bc29cfeed97f35690f5548b5bb2c9ad48 100644 (file)
@@ -2,6 +2,7 @@ package org.opendaylight.controller.md.sal.dom.store.impl;
 
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.NodeModification;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.StoreMetadataNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import com.google.common.base.Optional;
@@ -10,6 +11,7 @@ import com.google.common.primitives.UnsignedLong;
 public class OperationWithModification {
 
     private final NodeModification modification;
+
     private final ModificationApplyOperation applyOperation;
 
     private OperationWithModification(final ModificationApplyOperation op, final NodeModification mod) {
@@ -28,6 +30,14 @@ public class OperationWithModification {
         return this;
     }
 
+    public NodeModification getModification() {
+        return modification;
+    }
+
+    public ModificationApplyOperation getApplyOperation() {
+        return applyOperation;
+    }
+
     public boolean isApplicable(final Optional<StoreMetadataNode> data) {
         return applyOperation.isApplicable(modification, data);
     }
@@ -41,4 +51,16 @@ public class OperationWithModification {
         return new OperationWithModification(operation, modification);
 
     }
+
+    public void merge(final NormalizedNode<?, ?> data) {
+        modification.merge(data);
+        applyOperation.verifyStructure(modification);
+
+    }
+
+    public OperationWithModification forChild(final PathArgument childId) {
+        NodeModification childMod = modification.modifyChild(childId);
+        Optional<ModificationApplyOperation> childOp = applyOperation.getChild(childId);
+        return from(childOp.get(),childMod);
+    }
 }
\ No newline at end of file
index 520bd1ba1de3d9407718db6a6df64ce128fd1509..c62c27dea8908f8043b05561685b7db5ac555adc 100644 (file)
@@ -308,6 +308,7 @@ public class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeList
         switch (modification.getModificationType()) {
         case SUBTREE_MODIFIED:
             return resolveSubtreeChangeEvent(path, listeners, modification, before.get(), after.get());
+        case MERGE:
         case WRITE:
             if (before.isPresent()) {
                 return resolveReplacedEvent(path, listeners, before.get().getData(), after.get().getData());
@@ -487,6 +488,7 @@ public class ResolveDataChangeEventsTask implements Callable<Iterable<ChangeList
 
             switch (childMod.getModificationType()) {
             case WRITE:
+            case MERGE:
             case DELETE:
                 one.merge(resolveAnyChangeEvent(childPath, childListeners, childMod, childBefore, childAfter));
                 break;
index b9b1ab035e09f2dfc8325a39535a5a30bfc6c570..a5c9b7983a92f93a9a2e2049688e0d33eaed1c8b 100644 (file)
@@ -131,6 +131,8 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
             return isSubtreeModificationApplicable(modification, current);
         case WRITE:
             return isWriteApplicable(modification, current);
+        case MERGE:
+            return isMergeApplicable(modification,current);
         case UNMODIFIED:
             return true;
         default:
@@ -138,6 +140,16 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
         }
     }
 
+    private boolean isMergeApplicable(final NodeModification modification, final Optional<StoreMetadataNode> current) {
+        Optional<StoreMetadataNode> original = modification.getOriginal();
+        if (original.isPresent() && current.isPresent()) {
+            return isNotConflicting(original.get(), current.get());
+        } else if (current.isPresent()) {
+            return true;
+        }
+        return true;
+    }
+
     protected boolean isWriteApplicable(final NodeModification modification, final Optional<StoreMetadataNode> current) {
         Optional<StoreMetadataNode> original = modification.getOriginal();
         if (original.isPresent() && current.isPresent()) {
@@ -174,6 +186,10 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
                     modification);
             return modification.storeSnapshot(Optional.of(applySubtreeChange(modification, currentMeta.get(),
                     subtreeVersion)));
+        case MERGE:
+            if(currentMeta.isPresent()) {
+                return modification.storeSnapshot(Optional.of(applyMerge(modification,currentMeta.get(),subtreeVersion)));
+            } // Fallback to write is intentional - if node is not preexisting merge is same as write
         case WRITE:
             return modification.storeSnapshot(Optional.of(applyWrite(modification, currentMeta, subtreeVersion)));
         case UNMODIFIED:
@@ -183,6 +199,9 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
         }
     }
 
+    protected abstract StoreMetadataNode applyMerge(NodeModification modification,
+            StoreMetadataNode currentMeta, UnsignedLong subtreeVersion);
+
     protected abstract StoreMetadataNode applyWrite(NodeModification modification,
             Optional<StoreMetadataNode> currentMeta, UnsignedLong subtreeVersion);
 
@@ -219,14 +238,16 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
                     + "is leaf type node. Subtree change is not allowed.");
         }
 
+        @Override
+        protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta,
+                final UnsignedLong subtreeVersion) {
+            return applyWrite(modification, Optional.of(currentMeta), subtreeVersion);
+        }
+
         @Override
         protected StoreMetadataNode applyWrite(final NodeModification modification,
                 final Optional<StoreMetadataNode> currentMeta, final UnsignedLong subtreeVersion) {
             UnsignedLong nodeVersion = subtreeVersion;
-            if (currentMeta.isPresent()) {
-                nodeVersion = StoreUtils.increase(currentMeta.get().getNodeVersion());
-            }
-
             return StoreMetadataNode.builder().setNodeVersion(nodeVersion).setSubtreeVersion(subtreeVersion)
                     .setData(modification.getWritenValue()).build();
         }
@@ -314,6 +335,13 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
 
         }
 
+        @Override
+        protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta,
+                final UnsignedLong subtreeVersion) {
+            // For Node Containers - merge is same as subtree change - we only replace children.
+            return applySubtreeChange(modification, currentMeta, subtreeVersion);
+        }
+
         @Override
         public StoreMetadataNode applySubtreeChange(final NodeModification modification,
                 final StoreMetadataNode currentMeta, final UnsignedLong subtreeVersion) {
@@ -569,7 +597,11 @@ public abstract class SchemaAwareApplyOperation implements ModificationApplyOper
             entryStrategy = Optional.<ModificationApplyOperation> of(new UnkeyedListItemModificationStrategy(schema));
         }
 
-
+        @Override
+        protected StoreMetadataNode applyMerge(final NodeModification modification, final StoreMetadataNode currentMeta,
+                final UnsignedLong subtreeVersion) {
+            return applyWrite(modification, Optional.of(currentMeta), subtreeVersion);
+        }
 
         @Override
         protected StoreMetadataNode applySubtreeChange(final NodeModification modification,
index 199d90252ea8a2399baf9cad41e88dd02f561548..b16e907120ac098ee81a3f9fec4dd83469971f69 100644 (file)
@@ -32,5 +32,12 @@ public enum ModificationType {
      * Tree node is to be deleted.
      *
      */
-    DELETE
+    DELETE,
+
+    /**
+     *
+     * Tree node is to be merged with existing one.
+     *
+     */
+    MERGE
 }
index 04fb3b7c6c50499ad0b96b220c2685b597bdcb9d..4f650c171107abdbffd552a11f7e5531a1f1f8b8 100644 (file)
@@ -20,7 +20,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 import com.google.common.base.Optional;
 import com.google.common.base.Predicate;
-import com.google.common.primitives.UnsignedLong;
 
 /**
  * Node Modification Node and Tree
@@ -37,7 +36,9 @@ public class NodeModification implements StoreTreeNode<NodeModification>, Identi
     public static final Predicate<NodeModification> IS_TERMINAL_PREDICATE = new Predicate<NodeModification>() {
         @Override
         public boolean apply(final NodeModification input) {
-            return input.getModificationType() == ModificationType.WRITE || input.getModificationType() == ModificationType.DELETE;
+            return input.getModificationType() == ModificationType.WRITE //
+                    || input.getModificationType() == ModificationType.DELETE //
+                    || input.getModificationType() == ModificationType.MERGE;
         }
     };
     private final PathArgument identifier;
@@ -48,7 +49,6 @@ public class NodeModification implements StoreTreeNode<NodeModification>, Identi
 
     private NormalizedNode<?, ?> value;
 
-    private UnsignedLong subtreeVersion;
     private Optional<StoreMetadataNode> snapshotCache;
 
     private final Map<PathArgument, NodeModification> childModification;
@@ -176,6 +176,14 @@ public class NodeModification implements StoreTreeNode<NodeModification>, Identi
         this.value = value;
     }
 
+    public synchronized void merge(final NormalizedNode<?, ?> data) {
+        checkSealed();
+        clearSnapshot();
+        updateModificationType(ModificationType.MERGE);
+        // FIXME: Probably merge with previous value.
+        this.value = data;
+    }
+
     @GuardedBy("this")
     private void checkSealed() {
         checkState(!sealed, "Node Modification is sealed. No further changes allowed.");
index 6761bc1968778a8894c1a475176b66c054ce92ed..ddabbc6c030f3f8ef098d207b2b250f737288ddc 100644 (file)
@@ -33,6 +33,25 @@ public interface DOMStoreWriteTransaction extends DOMStoreTransaction {
      */
     void write(InstanceIdentifier path, NormalizedNode<?, ?> data);
 
+    /**
+     * Store a provided data at specified path. This acts as a add / replace
+     * operation, which is to say that whole subtree will be replaced by
+     * specified path.
+     *
+     * If you need add or merge of current object with specified use
+     * {@link #merge(LogicalDatastoreType, Path, Object)}
+     *
+     *
+     * @param path
+     * @param data
+     *            Data object to be written
+     *
+     * @throws IllegalStateException
+     *             if the client code already sealed transaction and invoked
+     *             {@link #ready()}
+     */
+    void merge(InstanceIdentifier path, NormalizedNode<?, ?> data);
+
     /**
      *
      * Deletes data and whole subtree located at provided path.
index 5edec0d1bdae2fb252b185057bc46ca4f6079e67..8425ce07794a922b62b88911245a619af8643557 100644 (file)
@@ -7,28 +7,27 @@
  */
 package org.opendaylight.controller.netconf.util.handler;
 
-import java.io.ByteArrayInputStream;
+import com.google.common.base.Preconditions;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufOutputStream;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToByteEncoder;
 import java.io.OutputStream;
-
+import javax.xml.transform.Transformer;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.sax.SAXResult;
+import javax.xml.transform.sax.SAXTransformerFactory;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.openexi.sax.Transmogrifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.xml.sax.InputSource;
-
-import com.google.common.base.Preconditions;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufOutputStream;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.handler.codec.MessageToByteEncoder;
 
 public final class NetconfMessageToEXIEncoder extends MessageToByteEncoder<NetconfMessage> {
 
     private static final Logger LOG = LoggerFactory.getLogger(NetconfMessageToEXIEncoder.class);
 
-    //private static final SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
+    private static final SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
     private final NetconfEXICodec codec;
 
     public NetconfMessageToEXIEncoder(final NetconfEXICodec codec) {
@@ -43,10 +42,8 @@ public final class NetconfMessageToEXIEncoder extends MessageToByteEncoder<Netco
             final Transmogrifier transmogrifier = codec.getTransmogrifier();
             transmogrifier.setOutputStream(os);
 
-            // FIXME transformer not working, see EXILibTest
-            transmogrifier.encode(new InputSource(new ByteArrayInputStream(XmlUtil.toString(msg.getDocument()).getBytes())));
-            //final Transformer transformer = saxTransformerFactory.newTransformer();
-            //transformer.transform(new DOMSource(msg.getDocument()), new SAXResult(transmogrifier.getSAXTransmogrifier()));
+            final Transformer transformer = saxTransformerFactory.newTransformer();
+            transformer.transform(new DOMSource(msg.getDocument()), new SAXResult(transmogrifier.getSAXTransmogrifier()));
         }
     }
 }
diff --git a/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/EXILibTest.java b/opendaylight/netconf/netconf-util/src/test/java/org/opendaylight/controller/netconf/util/EXILibTest.java
deleted file mode 100644 (file)
index 360e812..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.util;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.StringWriter;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
-import javax.xml.transform.dom.DOMResult;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.sax.SAXResult;
-import javax.xml.transform.sax.SAXTransformerFactory;
-import javax.xml.transform.sax.TransformerHandler;
-import javax.xml.transform.stream.StreamResult;
-
-import org.junit.Ignore;
-import org.junit.Test;
-import org.openexi.proc.common.AlignmentType;
-import org.openexi.proc.common.GrammarOptions;
-import org.openexi.proc.grammars.GrammarCache;
-import org.openexi.sax.EXIReader;
-import org.openexi.sax.Transmogrifier;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.xml.sax.InputSource;
-
-/**
- * This test case tests nagasena library used for exi encode/decode.
- *
- * This library does not work correctly, since it is impossible to encode and then decode DOM xml.
- * Encoding DOM using sax Transformer produces invalid xml, that cannot be decoded (Problem seems to be the namespace handling).
- *
- */
-@Ignore
-public class EXILibTest {
-
-    public static final AlignmentType ALIGNMENT_TYPE = AlignmentType.preCompress;
-
-    @Test
-    public void testExiLibWithSaxTransformer() throws Exception {
-        final byte[] encode = encodeEXI(getDom2());
-        final byte[] encodeWithTransformer = encodeEXITransformer(getDom2());
-
-        // System.err.println(Arrays.toString(encode));
-        // System.err.println(Arrays.toString(encodeWithTransformer));
-
-        // This works fine (encoded from string)
-        decodeEXI(encode);
-        // Error, encoded from Dom with Transformer cannot be decoded, Exception is thrown
-        //
-        // either:
-        // org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces.
-        //
-        // or:
-        // java.lang.NullPointerException
-        //
-        // depends on GrammarOptions.addNS(go); option set
-        decodeEXI(encodeWithTransformer);
-    }
-
-    private static final SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
-
-    public static byte[] encodeEXITransformer(final Element xml) throws Exception {
-        final Transmogrifier transmogrifier = new Transmogrifier();
-
-        transmogrifier.setAlignmentType(ALIGNMENT_TYPE);
-
-        final ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-        transmogrifier.setGrammarCache(getGrammarCache());
-
-        transmogrifier.setOutputStream(out);
-
-        final Transformer transformer = saxTransformerFactory.newTransformer();
-        transformer.transform(new DOMSource(xml), new SAXResult(transmogrifier.getSAXTransmogrifier()));
-
-        return out.toByteArray();
-    }
-
-    public static byte[] encodeEXI(final Element xml) throws Exception {
-        final Transmogrifier transmogrifier = new Transmogrifier();
-
-        transmogrifier.setAlignmentType(ALIGNMENT_TYPE);
-
-        final ByteArrayOutputStream out = new ByteArrayOutputStream();
-
-        transmogrifier.setGrammarCache(getGrammarCache());
-
-        transmogrifier.setOutputStream(out);
-
-        transmogrifier.encode(new InputSource(new ByteArrayInputStream(toString(xml, false).getBytes())));
-
-        out.flush();
-
-        return out.toByteArray();
-    }
-
-    private static GrammarCache getGrammarCache() {
-        short go = GrammarOptions.DEFAULT_OPTIONS;
-
-        // This option on or off, nagasena still fails
-//        go = GrammarOptions.addNS(go);
-
-        return new GrammarCache(null, go);
-    }
-
-    public static Document decodeEXI(final byte[] input) throws Exception {
-
-        final GrammarCache grammarCache;
-        final DOMResult domResult = new DOMResult();
-
-        try(ByteArrayInputStream in = new ByteArrayInputStream(input)) {
-
-            final EXIReader reader = new EXIReader();
-
-            reader.setAlignmentType(ALIGNMENT_TYPE);
-            grammarCache = getGrammarCache();
-
-            reader.setGrammarCache(grammarCache);
-
-            final SAXTransformerFactory transformerFactory
-                    = (SAXTransformerFactory) TransformerFactory.newInstance();
-            final TransformerHandler handler = transformerFactory.newTransformerHandler();
-            handler.setResult(domResult);
-
-            reader.setContentHandler(handler);
-
-            reader.parse(new InputSource(in));
-        }
-
-        return (Document) domResult.getNode();
-    }
-
-    public static Element getDom() {
-        final Element dom;
-
-        final Document d = newDocument();
-
-        dom = d.createElement("rpc");
-        dom.setAttribute("xmlns", "a.b.c");
-        dom.setAttribute("message-id", "id");
-        dom.appendChild(d.createElement("inner"));
-
-        return dom;
-    }
-
-    public static Element getDom2() {
-        final Element dom;
-
-        final Document d = newDocument();
-
-        dom = d.createElementNS("a.b.c", "rpc");
-        dom.setAttribute("message-id", "id");
-        dom.appendChild(d.createElement("inner"));
-
-        return dom;
-    }
-
-    private static final DocumentBuilderFactory BUILDERFACTORY;
-
-    static {
-        final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        factory.setNamespaceAware(true);
-        factory.setCoalescing(true);
-        factory.setIgnoringElementContentWhitespace(true);
-        factory.setIgnoringComments(true);
-        BUILDERFACTORY = factory;
-    }
-
-    private static Document newDocument() {
-        try {
-            final DocumentBuilder builder = BUILDERFACTORY.newDocumentBuilder();
-            return builder.newDocument();
-        } catch (final ParserConfigurationException e) {
-            throw new RuntimeException("Failed to create document", e);
-        }
-    }
-
-    private static String toString(final Element xml, final boolean addXmlDeclaration) {
-        try {
-            final Transformer transformer = TransformerFactory.newInstance().newTransformer();
-            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
-            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, addXmlDeclaration ? "no" : "yes");
-
-            final StreamResult result = new StreamResult(new StringWriter());
-            final DOMSource source = new DOMSource(xml);
-            transformer.transform(source, result);
-
-            return result.getWriter().toString();
-        } catch (IllegalArgumentException | TransformerFactoryConfigurationError | TransformerException e) {
-            throw new RuntimeException("Unable to serialize xml element " + xml, e);
-        }
-    }
-}
index d3cefd41b3dcaa49ca0062c51c4787c9ad84714f..94e67247c8eaa44696f83d2950bea6650732f89a 100644 (file)
@@ -1010,12 +1010,10 @@ public class SimpleForwardingImpl implements IfNewHostNotify,
                     routing.getRoute(incomingNodeConnector.getNode(), destHost.getnodeconnectorNode()) != null)) {
 
             log.trace("Host {} is at {}", dIP, destHost.getnodeConnector());
-            HostNodePair key = new HostNodePair(destHost, destHost.getnodeconnectorNode());
 
             // If SimpleForwarding is aware of this host, it will try to install
             // a path. Forward packet until it's done.
-            if (dataPacketService != null && this.rulesDB.containsKey(key)) {
-
+            if (dataPacketService != null) {
 
                 /*
                  * if we know where the host is and there's a path from where this
similarity index 85%
rename from third-party/org.openexi/nagasena-rta/nagasena-rta-0000.0002.0035.0.jar
rename to third-party/org.openexi/nagasena-rta/nagasena-rta-0000.0002.0038.0.jar
index 060b17152913558da98ab92344e60cb769860d7d..1b6a02710a7b4779a6853a44fbf3c3af72d00667 100644 (file)
Binary files a/third-party/org.openexi/nagasena-rta/nagasena-rta-0000.0002.0035.0.jar and b/third-party/org.openexi/nagasena-rta/nagasena-rta-0000.0002.0038.0.jar differ
index 6beba8c28bc188157c5da5e54a204dc80d9eee6f..98da51aca834e5ef20bc1df25f5b2b1719ac2acd 100644 (file)
@@ -13,7 +13,7 @@
     <parent>
         <groupId>org.opendaylight.controller.thirdparty</groupId>
         <artifactId>org.openexi</artifactId>
-        <version>0000.0002.0035.0-SNAPSHOT</version>
+        <version>0000.0002.0038.0-SNAPSHOT</version>
     </parent>
 
     <groupId>org.opendaylight.controller.thirdparty</groupId>
@@ -21,7 +21,7 @@
     <packaging>bundle</packaging>
 
     <properties>
-        <archive>nagasena-rta-0000.0002.0035.0.jar</archive>
+        <archive>nagasena-rta-0000.0002.0038.0.jar</archive>
     </properties>
 
     <build>
similarity index 80%
rename from third-party/org.openexi/nagasena/nagasena-0000.0002.0035.0.jar
rename to third-party/org.openexi/nagasena/nagasena-0000.0002.0038.0.jar
index c566f27d8335e22ea9649b0fcfabb5363482c3a7..ffc28ead4b0f59ae0e7174b8274e386cb7923c1d 100644 (file)
Binary files a/third-party/org.openexi/nagasena/nagasena-0000.0002.0035.0.jar and b/third-party/org.openexi/nagasena/nagasena-0000.0002.0038.0.jar differ
index 297f15f201224f7bae1e75fe5659028f78c0361c..a890431ca652c3220c260b4365ec55c6b5d562b2 100644 (file)
@@ -13,7 +13,7 @@
     <parent>
         <groupId>org.opendaylight.controller.thirdparty</groupId>
         <artifactId>org.openexi</artifactId>
-        <version>0000.0002.0035.0-SNAPSHOT</version>
+        <version>0000.0002.0038.0-SNAPSHOT</version>
     </parent>
 
     <groupId>org.opendaylight.controller.thirdparty</groupId>
@@ -21,7 +21,7 @@
     <packaging>bundle</packaging>
 
     <properties>
-        <archive>nagasena-0000.0002.0035.0.jar</archive>
+        <archive>nagasena-0000.0002.0038.0.jar</archive>
     </properties>
 
     <build>
index d623ef8cdc614e90edb0254872eb2039e37f6641..6369b294ba47688b45b9b5655e068fbe7a644760 100644 (file)
@@ -19,7 +19,7 @@
 
     <groupId>org.opendaylight.controller.thirdparty</groupId>
     <artifactId>org.openexi</artifactId>
-    <version>0000.0002.0035.0-SNAPSHOT</version>
+    <version>0000.0002.0038.0-SNAPSHOT</version>
     <packaging>pom</packaging>
     <prerequisites>
         <maven>3.0.4</maven>