Merge "Provided OSGi Friendly version of Jersey2 as karaf feature"
authorEd Warnicke <eaw@cisco.com>
Thu, 5 Jun 2014 13:35:20 +0000 (13:35 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 5 Jun 2014 13:35:20 +0000 (13:35 +0000)
12 files changed:
opendaylight/commons/opendaylight/pom.xml
opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleTest.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java
opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/ScheduledThreadPoolConfigBeanTest.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/AbstractDOMStoreTransaction.java [new file with mode: 0644]
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/SnapshotBackedReadTransaction.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SnapshotBackedReadWriteTransaction.java [new file with mode: 0644]
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SnapshotBackedWriteTransaction.java [new file with mode: 0644]
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java
opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsRequestScheduler.java
opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategyTest.java

index 0360c9a5a45d232da445285e828e00da07849d4c..943bbb878cf1bebdfb554142b3d70c49b96b84bd 100644 (file)
     <mdsal.version>1.1-SNAPSHOT</mdsal.version>
     <mockito.version>1.9.5</mockito.version>
     <netconf.version>0.2.5-SNAPSHOT</netconf.version>
-    <netty.version>4.0.17.Final</netty.version>
+    <netty.version>4.0.19.Final</netty.version>
     <networkconfig.bridgedomain.northbound.version>0.0.3-SNAPSHOT</networkconfig.bridgedomain.northbound.version>
     <networkconfig.neutron.implementation.version>0.4.2-SNAPSHOT</networkconfig.neutron.implementation.version>
     <networkconfig.neutron.northbound.version>0.4.2-SNAPSHOT</networkconfig.neutron.northbound.version>
index d9c9dada6202be0a4eac69d138329cb5f69c745f..75323d256e73de143a35c75bbfe9df1faf806d24 100644 (file)
@@ -7,6 +7,14 @@
  */
 package org.opendaylight.controller.config.yang.logback.config;
 
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.junit.matchers.JUnitMatchers.containsString;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import javax.management.ObjectName;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -16,15 +24,6 @@ import org.opendaylight.controller.config.manager.impl.AbstractConfigTest;
 import org.opendaylight.controller.config.manager.impl.factoriesresolver.HardcodedModuleFactoriesResolver;
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 
-import javax.management.ObjectName;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-import static org.junit.matchers.JUnitMatchers.containsString;
-
 public class LogbackModuleTest extends AbstractConfigTest {
 
     private static final String INSTANCE_NAME = "singleton";
@@ -89,7 +88,7 @@ public class LogbackModuleTest extends AbstractConfigTest {
         assertBeanCount(1, factory.getImplementationName());
 
         ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        transaction.destroyConfigBean(factory.getImplementationName(), INSTANCE_NAME);
+        transaction.destroyModule(factory.getImplementationName(), INSTANCE_NAME);
         CommitStatus status = transaction.commit();
 
         assertBeanCount(0, factory.getImplementationName());
index c95661d9c95b7470ca45156b56c6bc2df3fe7fe6..af7f01a6327529521dfd70e5230c4155605919c5 100644 (file)
@@ -7,6 +7,15 @@
  */
 package org.opendaylight.controller.config.threadpool.fixed;
 
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.matchers.JUnitMatchers.containsString;
+
+import java.lang.management.ManagementFactory;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.config.api.ConflictingVersionException;
@@ -20,14 +29,6 @@ import org.opendaylight.controller.config.yang.threadpool.impl.NamingThreadFacto
 import org.opendaylight.controller.config.yang.threadpool.impl.fixed.FixedThreadPoolModuleFactory;
 import org.opendaylight.controller.config.yang.threadpool.impl.fixed.FixedThreadPoolModuleMXBean;
 
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.fail;
-import static org.junit.matchers.JUnitMatchers.containsString;
-
 public class FixedThreadPoolConfigBeanTest extends AbstractConfigTest {
 
     private FixedThreadPoolModuleFactory factory;
@@ -92,17 +93,24 @@ public class FixedThreadPoolConfigBeanTest extends AbstractConfigTest {
     @Test
     public void testDestroy() throws InstanceAlreadyExistsException, ValidationException, ConflictingVersionException,
             InstanceNotFoundException {
-        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        createFixed(transaction, nameInstance, 1);
 
+        int numberOfThreads = 100;
+        int threadCount1 = ManagementFactory.getThreadMXBean().getThreadCount();
+        assertTrue("Expected less than " + numberOfThreads + " threads, got " + threadCount1, threadCount1 < numberOfThreads);
+        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
+        createFixed(transaction, nameInstance, numberOfThreads);
         transaction.commit();
+        int threadCount2 = ManagementFactory.getThreadMXBean().getThreadCount();
+        assertTrue("Expected more than " + numberOfThreads + " threads, got " + threadCount2, threadCount2 > numberOfThreads);
 
         transaction = configRegistryClient.createTransaction();
-        transaction.destroyConfigBean(factory.getImplementationName(), nameInstance);
+        transaction.destroyModule(factory.getImplementationName(), nameInstance);
         CommitStatus status = transaction.commit();
 
         assertBeanCount(0, factory.getImplementationName());
         assertStatus(status, 0, 0, 1);
+        int threadCount3 = ManagementFactory.getThreadMXBean().getThreadCount();
+        assertTrue("Expected less than " + numberOfThreads + " threads, got " + threadCount3, threadCount3 < numberOfThreads);
     }
 
     @Test
index ef06e43d2f291b87f994d04612c0f9f5488ea86b..0fc2fd6eb3d0c5aa9c0bd4d0c4d45611417f4887 100644 (file)
@@ -7,6 +7,15 @@
  */
 package org.opendaylight.controller.config.threadpool.scheduled;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.matchers.JUnitMatchers.containsString;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.config.api.ConflictingVersionException;
@@ -20,16 +29,6 @@ import org.opendaylight.controller.config.yang.threadpool.impl.NamingThreadFacto
 import org.opendaylight.controller.config.yang.threadpool.impl.scheduled.ScheduledThreadPoolModuleFactory;
 import org.opendaylight.controller.config.yang.threadpool.impl.scheduled.ScheduledThreadPoolModuleMXBean;
 
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.junit.matchers.JUnitMatchers.containsString;
-
 public class ScheduledThreadPoolConfigBeanTest extends AbstractConfigTest {
 
     private ScheduledThreadPoolModuleFactory factory;
@@ -103,7 +102,7 @@ public class ScheduledThreadPoolConfigBeanTest extends AbstractConfigTest {
         transaction.commit();
 
         transaction = configRegistryClient.createTransaction();
-        transaction.destroyConfigBean(factory.getImplementationName(), instanceName);
+        transaction.destroyModule(factory.getImplementationName(), instanceName);
         CommitStatus status = transaction.commit();
 
         assertBeanCount(0, factory.getImplementationName());
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/AbstractDOMStoreTransaction.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/AbstractDOMStoreTransaction.java
new file mode 100644 (file)
index 0000000..8a190c1
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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.dom.store.impl;
+
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransaction;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.Preconditions;
+
+/**
+ * Abstract DOM Store Transaction
+ *
+ * Convenience super implementation of DOM Store transaction which provides
+ * common implementation of {@link #toString()} and {@link #getIdentifier()}.
+ *
+ *
+ */
+abstract class AbstractDOMStoreTransaction implements DOMStoreTransaction {
+    private final Object identifier;
+
+    protected AbstractDOMStoreTransaction(final Object identifier) {
+        this.identifier = Preconditions.checkNotNull(identifier,"Identifier must not be null.");
+    }
+
+    @Override
+    public final Object getIdentifier() {
+        return identifier;
+    }
+
+    @Override
+    public final String toString() {
+        return addToStringAttributes(Objects.toStringHelper(this)).toString();
+    }
+
+    /**
+     * Add class-specific toString attributes.
+     *
+     * @param toStringHelper
+     *            ToStringHelper instance
+     * @return ToStringHelper instance which was passed in
+     */
+    protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
+        return toStringHelper.add("id", identifier);
+    }
+}
\ No newline at end of file
index 87c68596efa60a668a7afe005d482eefac1f6ad7..2495146aa64d290460ab83c1c681a781e760f720 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.controller.md.sal.dom.store.impl;
 
-import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 
 import java.util.Collections;
@@ -16,6 +15,7 @@ import java.util.concurrent.atomic.AtomicLong;
 
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
+import org.opendaylight.controller.md.sal.dom.store.impl.SnapshotBackedWriteTransaction.TransactionReadyPrototype;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataPreconditionFailedException;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTree;
 import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeCandidate;
@@ -27,7 +27,6 @@ import org.opendaylight.controller.sal.core.spi.data.DOMStore;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
-import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransaction;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
 import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
 import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
@@ -40,15 +39,22 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.base.Objects;
-import com.google.common.base.Objects.ToStringHelper;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 
-public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, SchemaContextListener {
+/**
+ * In-memory DOM Data Store
+ *
+ * Implementation of {@link DOMStore} which uses {@link DataTree}
+ * and other classes such as {@link SnapshotBackedWriteTransaction}.
+ * {@link SnapshotBackedReadTransaction} and {@link ResolveDataChangeEventsTask}
+ * to implement {@link DOMStore} contract.
+ *
+ */
+public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, SchemaContextListener, TransactionReadyPrototype {
     private static final Logger LOG = LoggerFactory.getLogger(InMemoryDOMDataStore.class);
     private final DataTree dataTree = InMemoryDataTreeFactory.getInstance().create();
     private final ListenerTree listenerTree = ListenerTree.create();
@@ -83,7 +89,7 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, Sch
 
     @Override
     public DOMStoreTransactionChain createTransactionChain() {
-        throw new UnsupportedOperationException("Not implemented yet.");
+        return new DOMStoreTransactionChainImpl();
     }
 
     @Override
@@ -130,7 +136,8 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, Sch
         };
     }
 
-    private synchronized DOMStoreThreePhaseCommitCohort submit(final SnapshotBackedWriteTransaction writeTx) {
+    @Override
+    public synchronized DOMStoreThreePhaseCommitCohort ready(final SnapshotBackedWriteTransaction writeTx) {
         LOG.debug("Tx: {} is submitted. Modifications: {}", writeTx.getIdentifier(), writeTx.getMutatedView());
         return new ThreePhaseCommitImpl(writeTx);
     }
@@ -139,162 +146,61 @@ public class InMemoryDOMDataStore implements DOMStore, Identifiable<String>, Sch
         return name + "-" + txCounter.getAndIncrement();
     }
 
-    private static abstract class AbstractDOMStoreTransaction implements DOMStoreTransaction {
-        private final Object identifier;
-
-        protected AbstractDOMStoreTransaction(final Object identifier) {
-            this.identifier = identifier;
-        }
-
-        @Override
-        public final Object getIdentifier() {
-            return identifier;
-        }
-
-        @Override
-        public final String toString() {
-            return addToStringAttributes(Objects.toStringHelper(this)).toString();
-        }
-
-        /**
-         * Add class-specific toString attributes.
-         *
-         * @param toStringHelper
-         *            ToStringHelper instance
-         * @return ToStringHelper instance which was passed in
-         */
-        protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
-            return toStringHelper.add("id", identifier);
-        }
-    }
-
-    private static final class SnapshotBackedReadTransaction extends AbstractDOMStoreTransaction implements
-    DOMStoreReadTransaction {
-        private DataTreeSnapshot stableSnapshot;
+    private class DOMStoreTransactionChainImpl implements DOMStoreTransactionChain, TransactionReadyPrototype {
 
-        public SnapshotBackedReadTransaction(final Object identifier, final DataTreeSnapshot snapshot) {
-            super(identifier);
-            this.stableSnapshot = Preconditions.checkNotNull(snapshot);
-            LOG.debug("ReadOnly Tx: {} allocated with snapshot {}", identifier, snapshot);
-        }
-
-        @Override
-        public void close() {
-            LOG.debug("Store transaction: {} : Closed", getIdentifier());
-            stableSnapshot = null;
-        }
+        private SnapshotBackedWriteTransaction previousOutstandingTx;
 
         @Override
-        public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final InstanceIdentifier path) {
-            checkNotNull(path, "Path must not be null.");
-            checkState(stableSnapshot != null, "Transaction is closed");
-            return Futures.immediateFuture(stableSnapshot.readNode(path));
-        }
-    }
-
-    private static class SnapshotBackedWriteTransaction extends AbstractDOMStoreTransaction implements
-    DOMStoreWriteTransaction {
-        private DataTreeModification mutableTree;
-        private InMemoryDOMDataStore store;
-        private boolean ready = false;
-
-        public SnapshotBackedWriteTransaction(final Object identifier, final DataTreeSnapshot snapshot,
-                final InMemoryDOMDataStore store) {
-            super(identifier);
-            mutableTree = snapshot.newModification();
-            this.store = store;
-            LOG.debug("Write Tx: {} allocated with snapshot {}", identifier, snapshot);
-        }
-
-        @Override
-        public void close() {
-            LOG.debug("Store transaction: {} : Closed", getIdentifier());
-            this.mutableTree = null;
-            this.store = null;
-        }
-
-        @Override
-        public void write(final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
-            checkNotReady();
-            try {
-                LOG.trace("Tx: {} Write: {}:{}", getIdentifier(), path, data);
-                mutableTree.write(path, data);
-                // FIXME: Add checked exception
-            } catch (Exception e) {
-                LOG.error("Tx: {}, failed to write {}:{} in {}", getIdentifier(), path, data, mutableTree, e);
+        public synchronized DOMStoreReadTransaction newReadOnlyTransaction() {
+            final DataTreeSnapshot snapshot;
+            if(previousOutstandingTx != null) {
+                checkState(previousOutstandingTx.isReady(), "Previous transaction in chain must be ready.");
+                snapshot = previousOutstandingTx.getMutatedView();
+            } else {
+                snapshot = dataTree.takeSnapshot();
             }
+            return new SnapshotBackedReadTransaction(nextIdentifier(), snapshot);
         }
 
         @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);
+        public synchronized DOMStoreReadWriteTransaction newReadWriteTransaction() {
+            final DataTreeSnapshot snapshot;
+            if(previousOutstandingTx != null) {
+                checkState(previousOutstandingTx.isReady(), "Previous transaction in chain must be ready.");
+                snapshot = previousOutstandingTx.getMutatedView();
+            } else {
+                snapshot = dataTree.takeSnapshot().newModification();
             }
+            SnapshotBackedReadWriteTransaction ret = new SnapshotBackedReadWriteTransaction(nextIdentifier(), snapshot,this);
+            return ret;
         }
 
         @Override
-        public void delete(final InstanceIdentifier path) {
-            checkNotReady();
-            try {
-                LOG.trace("Tx: {} Delete: {}", getIdentifier(), path);
-                mutableTree.delete(path);
-                // FIXME: Add checked exception
-            } catch (Exception e) {
-                LOG.error("Tx: {}, failed to delete {} in {}", getIdentifier(), path, mutableTree, e);
+        public synchronized DOMStoreWriteTransaction newWriteOnlyTransaction() {
+            final DataTreeSnapshot snapshot;
+            if(previousOutstandingTx != null) {
+                checkState(previousOutstandingTx.isReady(), "Previous transaction in chain must be ready.");
+                snapshot = previousOutstandingTx.getMutatedView();
+            } else {
+                snapshot = dataTree.takeSnapshot().newModification();
             }
-        }
-
-        protected final boolean isReady() {
-            return ready;
-        }
-
-        protected final void checkNotReady() {
-            checkState(!ready, "Transaction %s is ready. No further modifications allowed.", getIdentifier());
+            SnapshotBackedWriteTransaction ret =new SnapshotBackedWriteTransaction(nextIdentifier(), snapshot,this);
+            return ret;
         }
 
         @Override
-        public synchronized DOMStoreThreePhaseCommitCohort ready() {
-            checkState(!ready, "Transaction %s is already ready.", getIdentifier());
-            ready = true;
-
-            LOG.debug("Store transaction: {} : Ready", getIdentifier());
-            mutableTree.ready();
-            return store.submit(this);
-        }
-
-        protected DataTreeModification getMutatedView() {
-            return mutableTree;
+        public DOMStoreThreePhaseCommitCohort ready(final SnapshotBackedWriteTransaction tx) {
+            DOMStoreThreePhaseCommitCohort storeCohort = InMemoryDOMDataStore.this.ready(tx);
+            // FIXME: We probably want to add Transaction Chain cohort
+            return storeCohort;
         }
 
         @Override
-        protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
-            return toStringHelper.add("ready", isReady());
-        }
-    }
-
-    private static class SnapshotBackedReadWriteTransaction extends SnapshotBackedWriteTransaction implements
-    DOMStoreReadWriteTransaction {
+        public void close() {
+            // TODO Auto-generated method stub
 
-        protected SnapshotBackedReadWriteTransaction(final Object identifier, final DataTreeSnapshot snapshot,
-                final InMemoryDOMDataStore store) {
-            super(identifier, snapshot, store);
         }
 
-        @Override
-        public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final InstanceIdentifier path) {
-            LOG.trace("Tx: {} Read: {}", getIdentifier(), path);
-            try {
-                return Futures.immediateFuture(getMutatedView().readNode(path));
-            } catch (Exception e) {
-                LOG.error("Tx: {} Failed Read of {}", getIdentifier(), path, e);
-                throw e;
-            }
-        }
     }
 
     private class ThreePhaseCommitImpl implements DOMStoreThreePhaseCommitCohort {
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SnapshotBackedReadTransaction.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SnapshotBackedReadTransaction.java
new file mode 100644 (file)
index 0000000..315293f
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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.dom.store.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeSnapshot;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadTransaction;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+/**
+ *
+ * Implementation of read-only transaction backed by {@link DataTreeSnapshot}
+ *
+ * Implementation of read-only transaction backed by {@link DataTreeSnapshot}
+ * which delegates most of its calls to similar methods provided by underlying snapshot.
+ *
+ */
+final class SnapshotBackedReadTransaction extends AbstractDOMStoreTransaction implements
+DOMStoreReadTransaction {
+    private static final Logger LOG = LoggerFactory.getLogger(SnapshotBackedReadTransaction.class);
+    private DataTreeSnapshot stableSnapshot;
+
+    public SnapshotBackedReadTransaction(final Object identifier, final DataTreeSnapshot snapshot) {
+        super(identifier);
+        this.stableSnapshot = Preconditions.checkNotNull(snapshot);
+        LOG.debug("ReadOnly Tx: {} allocated with snapshot {}", identifier, snapshot);
+    }
+
+    @Override
+    public void close() {
+        LOG.debug("Store transaction: {} : Closed", getIdentifier());
+        stableSnapshot = null;
+    }
+
+    @Override
+    public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final InstanceIdentifier path) {
+        checkNotNull(path, "Path must not be null.");
+        checkState(stableSnapshot != null, "Transaction is closed");
+        return Futures.immediateFuture(stableSnapshot.readNode(path));
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SnapshotBackedReadWriteTransaction.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SnapshotBackedReadWriteTransaction.java
new file mode 100644 (file)
index 0000000..4abc802
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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.dom.store.impl;
+
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeSnapshot;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
+/**
+ * Implementation of Read-Write transaction which is backed by {@link DataTreeSnapshot}
+ * and executed according to {@link TransactionReadyPrototype}.
+ *
+ */
+class SnapshotBackedReadWriteTransaction extends SnapshotBackedWriteTransaction implements
+DOMStoreReadWriteTransaction {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SnapshotBackedReadWriteTransaction.class);
+
+    /**
+     * Creates new read-write transaction.
+     *
+     * @param identifier transaction Identifier
+     * @param snapshot Snapshot which will be modified.
+     * @param readyImpl Implementation of ready method.
+     */
+    protected SnapshotBackedReadWriteTransaction(final Object identifier, final DataTreeSnapshot snapshot,
+            final TransactionReadyPrototype store) {
+        super(identifier, snapshot, store);
+    }
+
+    @Override
+    public ListenableFuture<Optional<NormalizedNode<?, ?>>> read(final InstanceIdentifier path) {
+        LOG.debug("Tx: {} Read: {}", getIdentifier(), path);
+        try {
+            return Futures.immediateFuture(getMutatedView().readNode(path));
+        } catch (Exception e) {
+            LOG.error("Tx: {} Failed Read of {}", getIdentifier(), path, e);
+            throw e;
+        }
+    }
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SnapshotBackedWriteTransaction.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SnapshotBackedWriteTransaction.java
new file mode 100644 (file)
index 0000000..717fb11
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * 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.dom.store.impl;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeModification;
+import org.opendaylight.controller.md.sal.dom.store.impl.tree.DataTreeSnapshot;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
+
+/**
+ * Implementation of Write transaction which is backed by
+ * {@link DataTreeSnapshot} and executed according to
+ * {@link TransactionReadyPrototype}.
+ * 
+ */
+class SnapshotBackedWriteTransaction extends AbstractDOMStoreTransaction implements DOMStoreWriteTransaction {
+
+    private static final Logger LOG = LoggerFactory.getLogger(SnapshotBackedWriteTransaction.class);
+    private DataTreeModification mutableTree;
+    private boolean ready = false;
+    private TransactionReadyPrototype readyImpl;
+
+    /**
+     * Creates new write-only transaction.
+     * 
+     * @param identifier
+     *            transaction Identifier
+     * @param snapshot
+     *            Snapshot which will be modified.
+     * @param readyImpl
+     *            Implementation of ready method.
+     */
+    public SnapshotBackedWriteTransaction(final Object identifier, final DataTreeSnapshot snapshot,
+            final TransactionReadyPrototype readyImpl) {
+        super(identifier);
+        mutableTree = snapshot.newModification();
+        this.readyImpl = Preconditions.checkNotNull(readyImpl, "readyImpl must not be null.");
+        LOG.debug("Write Tx: {} allocated with snapshot {}", identifier, snapshot);
+    }
+
+    @Override
+    public void close() {
+        LOG.debug("Store transaction: {} : Closed", getIdentifier());
+        this.mutableTree = null;
+        this.readyImpl = null;
+    }
+
+    @Override
+    public void write(final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        checkNotReady();
+        try {
+            LOG.debug("Tx: {} Write: {}:{}", getIdentifier(), path, data);
+            mutableTree.write(path, data);
+            // FIXME: Add checked exception
+        } catch (Exception e) {
+            LOG.error("Tx: {}, failed to write {}:{} in {}", getIdentifier(), path, data, mutableTree, e);
+            // Rethrow original ones if they are subclasses of RuntimeException
+            // or Error
+            Throwables.propagateIfPossible(e);
+            // FIXME: Introduce proper checked exception
+            throw new IllegalArgumentException("Illegal input data.", e);
+        }
+    }
+
+    @Override
+    public void merge(final InstanceIdentifier path, final NormalizedNode<?, ?> data) {
+        checkNotReady();
+        try {
+            LOG.debug("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);
+            // Rethrow original ones if they are subclasses of RuntimeException
+            // or Error
+            Throwables.propagateIfPossible(e);
+            // FIXME: Introduce proper checked exception
+            throw new IllegalArgumentException("Illegal input data.", e);
+        }
+    }
+
+    @Override
+    public void delete(final InstanceIdentifier path) {
+        checkNotReady();
+        try {
+            LOG.debug("Tx: {} Delete: {}", getIdentifier(), path);
+            mutableTree.delete(path);
+            // FIXME: Add checked exception
+        } catch (Exception e) {
+            LOG.error("Tx: {}, failed to delete {} in {}", getIdentifier(), path, mutableTree, e);
+            // Rethrow original ones if they are subclasses of RuntimeException
+            // or Error
+            Throwables.propagateIfPossible(e);
+            // FIXME: Introduce proper checked exception
+            throw new IllegalArgumentException("Illegal path to delete.", e);
+        }
+    }
+
+    protected final boolean isReady() {
+        return ready;
+    }
+
+    protected final void checkNotReady() {
+        checkState(!ready, "Transaction %s is ready. No further modifications allowed.", getIdentifier());
+    }
+
+    @Override
+    public synchronized DOMStoreThreePhaseCommitCohort ready() {
+        checkState(!ready, "Transaction %s is already ready.", getIdentifier());
+        ready = true;
+        LOG.debug("Store transaction: {} : Ready", getIdentifier());
+        mutableTree.ready();
+        return readyImpl.ready(this);
+    }
+
+    protected DataTreeModification getMutatedView() {
+        return mutableTree;
+    }
+
+    @Override
+    protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
+        return toStringHelper.add("ready", isReady());
+    }
+
+    /**
+     * Prototype implementation of
+     * {@link #ready(SnapshotBackedWriteTransaction)}
+     * 
+     * This class is intended to be implemented by Transaction factories
+     * responsible for allocation of {@link SnapshotBackedWriteTransaction} and
+     * providing underlying logic for applying implementation.
+     * 
+     */
+    public static interface TransactionReadyPrototype {
+
+        /**
+         * Returns a commit coordinator associated with supplied transactions.
+         * 
+         * This call must not fail.
+         * 
+         * @param tx
+         *            Transaction on which ready was invoked.
+         * @return DOMStoreThreePhaseCommitCohort associated with transaction
+         */
+        DOMStoreThreePhaseCommitCohort ready(SnapshotBackedWriteTransaction tx);
+    }
+}
\ No newline at end of file
index dbcbab982a9aec997e37a2fb09e763bb3f3c5f96..7d9cc7ecbd789634e96ddbf32153e534d594dbc4 100644 (file)
@@ -313,6 +313,9 @@ public final class NodeStatisticsHandler implements AutoCloseable, FlowCapableCo
         meterStats.close();
         queueStats.close();
 
+        //Clean up queued statistics request from scheduler queue 
+        srScheduler.removeRequestsFromSchedulerQueue(this.getNodeRef());
+
         logger.debug("Statistics handler for {} shut down", targetNodeKey.getId());
     }
 
index 9ebfd6fd62f7b2ab8933d86a03a788b3154d2eb5..bea43ef68a05c1000d7a7d904d0c36f6fccc1b4a 100644 (file)
@@ -18,6 +18,7 @@ import java.util.concurrent.TimeUnit;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction.DataTransactionListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -62,6 +63,19 @@ public class StatisticsRequestScheduler implements DataTransactionListener {
         requestQueue.put(statsRequest, null);
     }
     
+    public void removeRequestsFromSchedulerQueue(NodeRef node){
+        AbstractStatsTracker stats = null;
+        synchronized(requestQueue){
+            Iterator<Map.Entry<AbstractStatsTracker, Integer>> nodesItr = requestQueue.entrySet().iterator();
+            while(nodesItr.hasNext()){
+                stats = nodesItr.next().getKey();
+                if(stats.getNodeRef().equals(node)){
+                    nodesItr.remove();
+                }
+            }
+        }
+
+    }
     public AbstractStatsTracker getNextRequestFromSchedulerQueue(){
         //Remove first element
         AbstractStatsTracker stats = null;
@@ -79,10 +93,7 @@ public class StatisticsRequestScheduler implements DataTransactionListener {
 
     private void requestStatistics(){
         AbstractStatsTracker stats = this.getNextRequestFromSchedulerQueue();
-        if(stats != null) {
-            stats.request();
-            stats.increaseRequestCounter();
-        }
+        sendStatsRequest(stats);
     }
     @Override
     public void onStatusUpdated(DataModificationTransaction transaction, TransactionStatus status) {
@@ -106,12 +117,19 @@ public class StatisticsRequestScheduler implements DataTransactionListener {
                 break;
             }
         }
+        sendStatsRequest(stats);
+    }
+    
+    private void sendStatsRequest(AbstractStatsTracker stats){
         if(stats != null){
-            stats.request();
-            stats.increaseRequestCounter();
+            try{
+                stats.request();
+                stats.increaseRequestCounter();
+            }catch(Exception e){
+                srsLogger.warn("Statistics request was not sent successfully. Reason : {}",e.getMessage());
+            }
         }
     }
-    
     public void start(){
         timer.schedule(task, 0, REQUEST_MONITOR_INTERVAL);
     }
index 78a2043e202413786f1000954c10289ce5395696..22a3f105477fbc300739a579b17767a640660406 100644 (file)
@@ -8,7 +8,17 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
 
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
 import com.google.common.collect.Sets;
+import java.util.Map;
+import javax.management.Attribute;
+import javax.management.ObjectName;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -16,17 +26,6 @@ import org.mockito.MockitoAnnotations;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
 import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
 
-import javax.management.Attribute;
-import javax.management.ObjectName;
-import java.util.Map;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
 public class ReplaceEditConfigStrategyTest {
 
     @Mock
@@ -35,7 +34,7 @@ public class ReplaceEditConfigStrategyTest {
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-        doNothing().when(ta).destroyConfigBean(anyString(), anyString());
+        doNothing().when(ta).destroyModule(anyString(), anyString());
         doReturn(mockON()).when(ta).lookupConfigBean(anyString(), anyString());
         doNothing().when(ta).setAttribute(any(ObjectName.class), anyString(), any(Attribute.class));
     }