From: Ed Warnicke Date: Thu, 5 Jun 2014 13:36:44 +0000 (+0000) Subject: Merge "Fixed Karaf Distribution javax.annotations conflicts with Jersey" X-Git-Tag: release/helium~709 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=5c23f8b37b10befc3d33d20723e6bf219c37a93d;hp=5b637de36f0668844722a31ecdf3e39d77cbd3e3 Merge "Fixed Karaf Distribution javax.annotations conflicts with Jersey" --- diff --git a/opendaylight/commons/opendaylight/pom.xml b/opendaylight/commons/opendaylight/pom.xml index 0360c9a5a4..943bbb878c 100644 --- a/opendaylight/commons/opendaylight/pom.xml +++ b/opendaylight/commons/opendaylight/pom.xml @@ -110,7 +110,7 @@ 1.1-SNAPSHOT 1.9.5 0.2.5-SNAPSHOT - 4.0.17.Final + 4.0.19.Final 0.0.3-SNAPSHOT 0.4.2-SNAPSHOT 0.4.2-SNAPSHOT diff --git a/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleTest.java b/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleTest.java index d9c9dada62..75323d256e 100644 --- a/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleTest.java +++ b/opendaylight/config/logback-config/src/test/java/org/opendaylight/controller/config/yang/logback/config/LogbackModuleTest.java @@ -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()); diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java index c95661d9c9..af7f01a632 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/fixed/FixedThreadPoolConfigBeanTest.java @@ -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 diff --git a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/ScheduledThreadPoolConfigBeanTest.java b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/ScheduledThreadPoolConfigBeanTest.java index ef06e43d2f..0fc2fd6eb3 100644 --- a/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/ScheduledThreadPoolConfigBeanTest.java +++ b/opendaylight/config/threadpool-config-impl/src/test/java/org/opendaylight/controller/config/threadpool/scheduled/ScheduledThreadPoolConfigBeanTest.java @@ -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 index 0000000000..8a190c115f --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/AbstractDOMStoreTransaction.java @@ -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 diff --git a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java index 87c68596ef..2495146aa6 100644 --- a/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/InMemoryDOMDataStore.java @@ -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, 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, 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, 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, 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, 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>> 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>> 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 index 0000000000..315293fbe7 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SnapshotBackedReadTransaction.java @@ -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>> 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 index 0000000000..4abc80229f --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SnapshotBackedReadWriteTransaction.java @@ -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>> 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 index 0000000000..717fb11987 --- /dev/null +++ b/opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/store/impl/SnapshotBackedWriteTransaction.java @@ -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 diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java index dbcbab982a..7d9cc7ecbd 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/NodeStatisticsHandler.java @@ -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()); } diff --git a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsRequestScheduler.java b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsRequestScheduler.java index 9ebfd6fd62..bea43ef68a 100644 --- a/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsRequestScheduler.java +++ b/opendaylight/md-sal/statistics-manager/src/main/java/org/opendaylight/controller/md/statistics/manager/StatisticsRequestScheduler.java @@ -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> 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); } diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategyTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategyTest.java index 78a2043e20..22a3f10547 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategyTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/ReplaceEditConfigStrategyTest.java @@ -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)); }