<data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
<module>
- <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl">prefix:dom-inmemory-data-broker</type>
- <name>inmemory-data-broker</name>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:config:concurrent-data-broker">prefix:dom-concurrent-data-broker</type>
+ <name>concurrent-data-broker</name>
<schema-service>
<type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:schema-service</type>
<type xmlns:operational-dom-store-spi="urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store">operational-dom-store-spi:operational-dom-datastore</type>
<name>distributed-operational-store-service</name>
</operational-data-store>
-
- <allow-concurrent-commits>true</allow-concurrent-commits>
</module>
<module>
</module>
</modules>
+
<services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
<service>
</instance>
</service>
+ <!-- Overrides the definition from 01-md-sal.xml -->
+ <service>
+ <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
+ <instance>
+ <name>inmemory-data-broker</name>
+ <provider>/modules/module[type='dom-concurrent-data-broker'][name='concurrent-data-broker']</provider>
+ </instance>
+ </service>
+
</services>
</data>
</configuration>
<required-capabilities>
- <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl?module=opendaylight-sal-dom-broker-impl&revision=2013-10-28</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:config:concurrent-data-broker?module=odl-concurrent-data-broker-cfg&revision=2014-11-24</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:config:distributed-datastore-provider?module=distributed-datastore-privider&revision=2014-06-12</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store?module=opendaylight-config-dom-datastore&revision=2014-06-17</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store?module=opendaylight-operational-dom-datastore&revision=2014-06-17</capability>
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom?module=opendaylight-md-sal-dom&revision=2013-10-28</capability>
</required-capabilities>
</snapshot>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-common-util</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-broker-impl</artifactId>
+ </dependency>
+
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>sal-core-spi</artifactId>
* 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.broker.impl;
+package org.opendaylight.controller.cluster.datastore;
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.broker.impl.AbstractDOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.broker.impl.TransactionCommitFailedExceptionMapper;
import org.opendaylight.controller.sal.core.spi.data.DOMStore;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreThreePhaseCommitCohort;
import org.opendaylight.yangtools.util.DurationStatisticsTracker;
--- /dev/null
+/*
+ * 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.config.yang.config.concurrent_data_broker;
+
+import com.google.common.collect.Lists;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import org.opendaylight.controller.cluster.datastore.ConcurrentDOMDataBroker;
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.util.jmx.AbstractMXBean;
+import org.opendaylight.controller.md.sal.common.util.jmx.ThreadExecutorStatsMXBeanImpl;
+import org.opendaylight.controller.md.sal.dom.broker.impl.jmx.CommitStatsMXBeanImpl;
+import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStoreFactory;
+import org.opendaylight.controller.sal.core.spi.data.DOMStore;
+import org.opendaylight.yangtools.util.DurationStatisticsTracker;
+import org.opendaylight.yangtools.util.concurrent.SpecialExecutors;
+
+public class DomConcurrentDataBrokerModule extends AbstractDomConcurrentDataBrokerModule {
+ private static final String JMX_BEAN_TYPE = "DOMDataBroker";
+
+ public DomConcurrentDataBrokerModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public DomConcurrentDataBrokerModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final DependencyResolver dependencyResolver, final DomConcurrentDataBrokerModule oldModule, final AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public AutoCloseable createInstance() {
+ //Initializing Operational DOM DataStore defaulting to InMemoryDOMDataStore if one is not configured
+ DOMStore operStore = getOperationalDataStoreDependency();
+ if(operStore == null){
+ //we will default to InMemoryDOMDataStore creation
+ operStore = InMemoryDOMDataStoreFactory.create("DOM-OPER", getSchemaServiceDependency());
+ }
+
+ DOMStore configStore = getConfigDataStoreDependency();
+ if(configStore == null){
+ //we will default to InMemoryDOMDataStore creation
+ configStore = InMemoryDOMDataStoreFactory.create("DOM-CFG", getSchemaServiceDependency());
+ }
+
+ final Map<LogicalDatastoreType, DOMStore> datastores = new EnumMap<>(LogicalDatastoreType.class);
+ datastores.put(LogicalDatastoreType.OPERATIONAL, operStore);
+ datastores.put(LogicalDatastoreType.CONFIGURATION, configStore);
+
+ /*
+ * We use an executor for commit ListenableFuture callbacks that favors reusing available
+ * threads over creating new threads at the expense of execution time. The assumption is
+ * that most ListenableFuture callbacks won't execute a lot of business logic where we want
+ * it to run quicker - many callbacks will likely just handle error conditions and do
+ * nothing on success. The executor queue capacity is bounded and, if the capacity is
+ * reached, subsequent submitted tasks will block the caller.
+ */
+ ExecutorService listenableFutureExecutor = SpecialExecutors.newBlockingBoundedCachedThreadPool(
+ getMaxDataBrokerFutureCallbackPoolSize(), getMaxDataBrokerFutureCallbackQueueSize(),
+ "CommitFutures");
+
+ final List<AbstractMXBean> mBeans = Lists.newArrayList();
+
+ final DurationStatisticsTracker commitStatsTracker;
+ final ConcurrentDOMDataBroker cdb = new ConcurrentDOMDataBroker(datastores, listenableFutureExecutor);
+ commitStatsTracker = cdb.getCommitStatsTracker();
+
+ if(commitStatsTracker != null) {
+ final CommitStatsMXBeanImpl commitStatsMXBean = new CommitStatsMXBeanImpl(
+ commitStatsTracker, JMX_BEAN_TYPE);
+ commitStatsMXBean.registerMBean();
+ mBeans.add(commitStatsMXBean);
+ }
+
+ final AbstractMXBean commitFutureStatsMXBean =
+ ThreadExecutorStatsMXBeanImpl.create(listenableFutureExecutor,
+ "CommitFutureExecutorStats", JMX_BEAN_TYPE, null);
+ if(commitFutureStatsMXBean != null) {
+ mBeans.add(commitFutureStatsMXBean);
+ }
+
+ cdb.setCloseable(new AutoCloseable() {
+ @Override
+ public void close() {
+ for(AbstractMXBean mBean: mBeans) {
+ mBean.unregisterMBean();
+ }
+ }
+ });
+
+ return cdb;
+ }
+}
--- /dev/null
+/*
+ * 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.config.yang.config.concurrent_data_broker;
+
+public class DomConcurrentDataBrokerModuleFactory extends AbstractDomConcurrentDataBrokerModuleFactory {
+
+}
--- /dev/null
+module odl-concurrent-data-broker-cfg {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:config:concurrent-data-broker";
+ prefix "cdb";
+
+ import config { prefix config; revision-date 2013-04-05; }
+ import opendaylight-config-dom-datastore {prefix config-dom-store-spi;}
+ import opendaylight-operational-dom-datastore {prefix operational-dom-store-spi;}
+ import opendaylight-md-sal-dom {prefix sal; }
+ import opendaylight-sal-dom-broker-impl { prefix broker; }
+
+ description
+ "Service definition for concurrent dom broker.";
+
+ revision "2014-11-24" {
+ description
+ "Initial revision";
+ }
+
+ identity dom-concurrent-data-broker {
+ base config:module-type;
+ config:provided-service sal:dom-async-data-broker;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case dom-concurrent-data-broker {
+ when "/config:modules/config:module/config:type = 'dom-concurrent-data-broker'";
+
+ uses broker:dom-broker-config;
+ }
+ }
+}
* 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.broker.impl;
+package org.opendaylight.controller.cluster.datastore;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
<!-- TODO Remove sal.broker.impl from export when SchemaAwareRpcRegistry is not used in connector anymore -->
org.opendaylight.controller.sal.dom.broker.impl,
org.opendaylight.controller.sal.dom.broker.impl.*,
+
+ <!-- Temporary until we move abstract classes out into SPI -->
+ org.opendaylight.controller.md.sal.dom.broker.impl,
+ org.opendaylight.controller.md.sal.dom.broker.impl.jmx,
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.dom.impl.rev131028.*,
</Export-Package>
<Private-Package>org.opendaylight.controller.sal.dom.broker,
org.opendaylight.controller.sal.dom.broker.osgi,
org.opendaylight.controller.md.sal.dom.broker.impl,
org.opendaylight.controller.md.sal.dom.broker.impl.*,
org.opendaylight.yangtools.yang.util,
- org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.dom.impl.rev131028.*,
org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.dom.pingpong.rev141107.*
</Private-Package>
<Import-Package>*</Import-Package>
*/
package org.opendaylight.controller.config.yang.md.sal.dom.impl;
+import com.google.common.collect.Lists;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitDeadlockException;
import org.opendaylight.controller.md.sal.common.util.jmx.AbstractMXBean;
import org.opendaylight.controller.md.sal.common.util.jmx.ThreadExecutorStatsMXBeanImpl;
-import org.opendaylight.controller.md.sal.dom.broker.impl.ConcurrentDOMDataBroker;
-import org.opendaylight.controller.md.sal.dom.broker.impl.AbstractDOMDataBroker;
import org.opendaylight.controller.md.sal.dom.broker.impl.SerializedDOMDataBroker;
import org.opendaylight.controller.md.sal.dom.broker.impl.jmx.CommitStatsMXBeanImpl;
import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStoreFactory;
import org.opendaylight.yangtools.util.DurationStatisticsTracker;
import org.opendaylight.yangtools.util.concurrent.DeadlockDetectingListeningExecutorService;
import org.opendaylight.yangtools.util.concurrent.SpecialExecutors;
-import com.google.common.collect.Lists;
/**
*
"CommitFutures");
final List<AbstractMXBean> mBeans = Lists.newArrayList();
-
final DurationStatisticsTracker commitStatsTracker;
- final AbstractDOMDataBroker broker;
-
- if (getAllowConcurrentCommits()) {
- final ConcurrentDOMDataBroker cdb = new ConcurrentDOMDataBroker(datastores, listenableFutureExecutor);
- commitStatsTracker = cdb.getCommitStatsTracker();
- broker = cdb;
- } else {
- /*
- * We use a single-threaded executor for commits with a bounded queue capacity. If the
- * queue capacity is reached, subsequent commit tasks will be rejected and the commits will
- * fail. This is done to relieve back pressure. This should be an extreme scenario - either
- * there's deadlock(s) somewhere and the controller is unstable or some rogue component is
- * continuously hammering commits too fast or the controller is just over-capacity for the
- * system it's running on.
- */
- ExecutorService commitExecutor = SpecialExecutors.newBoundedSingleThreadExecutor(
- getMaxDataBrokerCommitQueueSize(), "WriteTxCommit");
-
- SerializedDOMDataBroker sdb = new SerializedDOMDataBroker(datastores,
- new DeadlockDetectingListeningExecutorService(commitExecutor,
- TransactionCommitDeadlockException.DEADLOCK_EXCEPTION_SUPPLIER,
- listenableFutureExecutor));
- commitStatsTracker = sdb.getCommitStatsTracker();
- broker = sdb;
-
- final AbstractMXBean commitExecutorStatsMXBean =
- ThreadExecutorStatsMXBeanImpl.create(commitExecutor, "CommitExecutorStats",
- JMX_BEAN_TYPE, null);
- if(commitExecutorStatsMXBean != null) {
- mBeans.add(commitExecutorStatsMXBean);
- }
+
+ /*
+ * We use a single-threaded executor for commits with a bounded queue capacity. If the
+ * queue capacity is reached, subsequent commit tasks will be rejected and the commits will
+ * fail. This is done to relieve back pressure. This should be an extreme scenario - either
+ * there's deadlock(s) somewhere and the controller is unstable or some rogue component is
+ * continuously hammering commits too fast or the controller is just over-capacity for the
+ * system it's running on.
+ */
+ ExecutorService commitExecutor = SpecialExecutors.newBoundedSingleThreadExecutor(
+ getMaxDataBrokerCommitQueueSize(), "WriteTxCommit");
+
+ SerializedDOMDataBroker sdb = new SerializedDOMDataBroker(datastores,
+ new DeadlockDetectingListeningExecutorService(commitExecutor,
+ TransactionCommitDeadlockException.DEADLOCK_EXCEPTION_SUPPLIER,
+ listenableFutureExecutor));
+ commitStatsTracker = sdb.getCommitStatsTracker();
+
+ final AbstractMXBean commitExecutorStatsMXBean =
+ ThreadExecutorStatsMXBeanImpl.create(commitExecutor, "CommitExecutorStats",
+ JMX_BEAN_TYPE, null);
+ if(commitExecutorStatsMXBean != null) {
+ mBeans.add(commitExecutorStatsMXBean);
}
if(commitStatsTracker != null) {
mBeans.add(commitFutureStatsMXBean);
}
- broker.setCloseable(new AutoCloseable() {
+ sdb.setCloseable(new AutoCloseable() {
@Override
public void close() {
for(AbstractMXBean mBean: mBeans) {
}
});
- return broker;
+ return sdb;
}
}
*
* @see ExceptionMapper
*/
-final class TransactionCommitFailedExceptionMapper
+public final class TransactionCommitFailedExceptionMapper
extends ExceptionMapper<TransactionCommitFailedException> {
- static final TransactionCommitFailedExceptionMapper PRE_COMMIT_MAPPER = create("preCommit");
+ public static final TransactionCommitFailedExceptionMapper PRE_COMMIT_MAPPER = create("preCommit");
- static final TransactionCommitFailedExceptionMapper CAN_COMMIT_ERROR_MAPPER = create("canCommit");
+ public static final TransactionCommitFailedExceptionMapper CAN_COMMIT_ERROR_MAPPER = create("canCommit");
- static final TransactionCommitFailedExceptionMapper COMMIT_ERROR_MAPPER = create("commit");
+ public static final TransactionCommitFailedExceptionMapper COMMIT_ERROR_MAPPER = create("commit");
private TransactionCommitFailedExceptionMapper(final String opName) {
super( opName, TransactionCommitFailedException.class );
}
@Override
- protected TransactionCommitFailedException newWithCause( String message, Throwable cause ) {
+ protected TransactionCommitFailedException newWithCause( final String message, final Throwable cause ) {
return new TransactionCommitFailedException( message, cause );
}
}
\ No newline at end of file
module opendaylight-sal-dom-broker-impl {
- yang-version 1;
+ yang-version 1;
namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl";
prefix "binding-impl";
- import config { prefix config; revision-date 2013-04-05; }
- import opendaylight-md-sal-dom {prefix sal;}
- import opendaylight-md-sal-common {prefix common;}
- import opendaylight-config-dom-datastore {prefix config-dom-store-spi;}
- import opendaylight-operational-dom-datastore {prefix operational-dom-store-spi;}
+ import config { prefix config; revision-date 2013-04-05; }
+ import opendaylight-md-sal-dom {prefix sal;}
+ import opendaylight-md-sal-common {prefix common;}
+ import opendaylight-config-dom-datastore {prefix config-dom-store-spi;}
+ import opendaylight-operational-dom-datastore {prefix operational-dom-store-spi;}
description
"Service definition for Binding Aware MD-SAL.
Note: The dom-inmemory-data-broker utilizes configurable config-dom-datastore
and operation-dom-datastore. If configuration is not done for this stores
then it defaults to InMemoryDOMDataStore";
-
+
revision "2013-10-28" {
description
"Initial revision";
base config:module-type;
config:provided-service sal:dom-broker-osgi-registry;
config:java-name-prefix DomBrokerImpl;
- }
-
-
+ }
+
+
identity dom-inmemory-data-broker {
base config:module-type;
config:provided-service sal:dom-async-data-broker;
}
-
+
identity schema-service-singleton {
base config:module-type;
config:provided-service sal:schema-service;
}
}
}
-
- augment "/config:modules/config:module/config:configuration" {
- case dom-inmemory-data-broker {
- when "/config:modules/config:module/config:type = 'dom-inmemory-data-broker'";
-
- container schema-service {
- uses config:service-ref {
- refine type {
- mandatory false;
- config:required-identity sal:schema-service;
- }
+ grouping dom-broker-config {
+ container schema-service {
+ uses config:service-ref {
+ refine type {
+ mandatory false;
+ config:required-identity sal:schema-service;
}
-
}
+ }
- container config-data-store{
- uses config:service-ref {
- refine type {
- mandatory false;
- config:required-identity config-dom-store-spi:config-dom-datastore;
- }
+ container config-data-store {
+ uses config:service-ref {
+ refine type {
+ mandatory false;
+ config:required-identity config-dom-store-spi:config-dom-datastore;
}
- }
+ }
+ }
- container operational-data-store{
- uses config:service-ref {
- refine type {
- mandatory false;
- config:required-identity operational-dom-store-spi:operational-dom-datastore;
- }
+ container operational-data-store {
+ uses config:service-ref {
+ refine type {
+ mandatory false;
+ config:required-identity operational-dom-store-spi:operational-dom-datastore;
}
- }
+ }
+ }
- leaf max-data-broker-future-callback-queue-size {
- default 1000;
- type uint16;
- description "The maximum queue size for the data broker's commit future callback executor.";
- }
+ leaf max-data-broker-future-callback-queue-size {
+ default 1000;
+ type uint16;
+ description "The maximum queue size for the data broker's commit future callback executor.";
+ }
- leaf max-data-broker-future-callback-pool-size {
- default 20;
- type uint16;
- description "The maximum thread pool size for the data broker's commit future callback executor.";
- }
+ leaf max-data-broker-future-callback-pool-size {
+ default 20;
+ type uint16;
+ description "The maximum thread pool size for the data broker's commit future callback executor.";
+ }
- leaf max-data-broker-commit-queue-size {
- default 5000;
- type uint16;
- description "The maximum queue size for the data broker's commit executor.";
- }
+ leaf max-data-broker-commit-queue-size {
+ default 5000;
+ type uint16;
+ description "The maximum queue size for the data broker's commit executor.";
+ }
+ }
- leaf allow-concurrent-commits {
- default false;
- type boolean;
- description "Specifies whether or not to allow 3-phrase commits to run concurrently.
- Use with caution. If set to true, the data store implementations must be prepared
- to handle concurrent commits. The default is false";
- }
+ augment "/config:modules/config:module/config:configuration" {
+ case dom-inmemory-data-broker {
+ when "/config:modules/config:module/config:type = 'dom-inmemory-data-broker'";
+
+ uses dom-broker-config;
}
}
-
+
augment "/config:modules/config:module/config:state" {
case schema-service-singleton {
when "/config:modules/config:module/config:type = 'schema-service-singleton'";
}
}
-
+
augment "/config:modules/config:module/config:state" {
case dom-broker-impl {
when "/config:modules/config:module/config:type = 'dom-broker-impl'";
container data {
uses common:data-state;
- }
+ }
}
}
}