Modify config Module impls to co-exist with blueprint 14/36714/26
authorTom Pantelis <tpanteli@brocade.com>
Mon, 28 Mar 2016 17:44:11 +0000 (13:44 -0400)
committerAnil Vishnoi <vishnoianil@gmail.com>
Fri, 22 Apr 2016 17:51:30 +0000 (17:51 +0000)
Modified various config system Module implementation classes which
have corresponding instances created and advertised via blueprint to
obtain the instance in createInstance from the OSGi registry. The
instance may not be available yet so it will wait. I added a
WaitingServiceTracker class to encapsulate this logic using a ServiceTracker.

For those modules that don't advertise services, createInstance simply
returns a noop AutoCloseable since the components are created via
blueprint.

I also added the new disable-osgi-service-registration flag to the
corresponding service yang identities to prevent the CSS from
duplicating the service registrations.

This patch also adds the blueprint bundle to the mdsal features and
"turns on" blueprint.

Change-Id: I60099c82a2a248fc233ad930c4808d6ab19ea881
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
55 files changed:
features/mdsal/pom.xml
features/mdsal/src/main/features/features.xml
opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/GlobalEventExecutorUtil.java [deleted file]
opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/NeverReconnectStrategyModuleTest.java [deleted file]
opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/ReconnectImmediatelyStrategyModuleTest.java [deleted file]
opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/TimedReconnectStrategyModuleTest.java [deleted file]
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/osgi/ServiceNotFoundException.java [new file with mode: 0644]
opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/osgi/WaitingServiceTracker.java [new file with mode: 0644]
opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/AutoCloseableEventExecutor.java
opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModule.java
opendaylight/config/netty-event-executor-config/src/main/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleFactory.java
opendaylight/config/netty-event-executor-config/src/test/java/org/opendaylight/controller/config/yang/netty/eventexecutor/GlobalEventExecutorModuleTest.java
opendaylight/config/netty-threadgroup-config/pom.xml
opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModule.java
opendaylight/config/netty-threadgroup-config/src/main/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModuleFactory.java
opendaylight/config/netty-threadgroup-config/src/test/java/org/opendaylight/controller/config/yang/netty/threadgroup/NettyThreadgroupModuleTest.java
opendaylight/config/netty-timer-config/src/main/java/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModule.java
opendaylight/config/netty-timer-config/src/main/java/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModuleFactory.java
opendaylight/config/netty-timer-config/src/test/java/org/opendaylight/controller/config/yang/netty/timer/HashedWheelTimerModuleTest.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/util/BindingTestContext.java
opendaylight/md-sal/sal-binding-config/src/main/java/org/opendaylight/controller/config/yang/md/sal/binding/impl/RuntimeMappingModule.java
opendaylight/md-sal/sal-binding-config/src/main/yang/opendaylight-binding-broker-impl.yang
opendaylight/md-sal/sal-binding-config/src/main/yang/opendaylight-md-sal-binding.yang
opendaylight/md-sal/sal-clustering-commons/src/main/yang/actor-system-provider-service.yang
opendaylight/md-sal/sal-common-api/src/main/yang/opendaylight-entity-ownership-service.yang
opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/NoopAutoCloseable.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/pom.xml
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStore.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreInterface.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/admin/ClusterAdminRpcService.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/actor_system_provider/impl/ActorSystemProviderModule.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/cluster_admin_provider/ClusterAdminProviderModule.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/concurrent_data_broker/DomConcurrentDataBrokerModule.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/concurrent_data_broker/DomConcurrentDataBrokerModuleFactory.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedConfigDataStoreProviderModule.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/DistributedOperationalDataStoreProviderModule.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/ForwardingDistributedDataStore.java [new file with mode: 0644]
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_entity_ownership_service/DistributedEntityOwnershipServiceProviderModule.java
opendaylight/md-sal/sal-distributed-datastore/src/main/resources/org/opendaylight/blueprint/clustered-datastore.xml
opendaylight/md-sal/sal-distributed-datastore/src/main/yang/distributed-datastore-provider.yang
opendaylight/md-sal/sal-dom-broker-config/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomBrokerImplModule.java
opendaylight/md-sal/sal-dom-broker-config/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomBrokerImplModuleFactory.java
opendaylight/md-sal/sal-dom-broker-config/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/SchemaServiceImplSingletonModule.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMNotificationRouter.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/sal/dom/broker/BrokerImpl.java
opendaylight/md-sal/sal-dom-config/src/main/yang/opendaylight-config-dom-datastore.yang
opendaylight/md-sal/sal-dom-config/src/main/yang/opendaylight-md-sal-dom.yang
opendaylight/md-sal/sal-dom-config/src/main/yang/opendaylight-operational-dom-datastore.yang
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/config/yang/config/remote_rpc_connector/RemoteRPCBrokerModule.java
opendaylight/md-sal/sal-remoterpc-connector/src/main/java/org/opendaylight/controller/config/yang/config/remote_rpc_connector/RemoteRPCBrokerModuleFactory.java
opendaylight/md-sal/samples/clustering-test-app/provider/src/main/java/org/opendaylight/controller/config/yang/config/clustering_it_provider/ClusteringItProviderModule.java
opendaylight/md-sal/samples/toaster-consumer/src/main/java/org/opendaylight/controller/config/yang/config/kitchen_service/impl/KitchenServiceModule.java
opendaylight/md-sal/samples/toaster-consumer/src/main/java/org/opendaylight/controller/config/yang/config/kitchen_service/impl/KitchenServiceModuleFactory.java
opendaylight/md-sal/samples/toaster-it/src/test/java/org/opendaylight/controller/sample/toaster/it/ToasterTest.java
opendaylight/md-sal/samples/toaster-provider/src/main/java/org/opendaylight/controller/config/yang/config/toaster_provider/impl/ToasterProviderModule.java

index abb74a54db464472175b8cf08a74bba1241e1dd0..f12e9e13588251e89c22fd82c02964e6e9d2fe7e 100644 (file)
@@ -15,6 +15,7 @@
   <packaging>jar</packaging>
 
   <properties>
+    <blueprint.version>0.5.0-SNAPSHOT</blueprint.version>
     <yangtools.version>1.0.0-SNAPSHOT</yangtools.version>
     <mdsal.version>2.1.0-SNAPSHOT</mdsal.version>
     <mdsal.model.version>0.9.0-SNAPSHOT</mdsal.model.version>
       <artifactId>stax-utils</artifactId>
     </dependency>
 
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>blueprint</artifactId>
+      <version>${blueprint.version}</version>
+    </dependency>
+
     <!-- Required features repositories -->
     <dependency>
       <groupId>org.opendaylight.odlparent</groupId>
       <type>xml</type>
     </dependency>
 
-
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>md-sal-config</artifactId>
index b7283d0e54f212c401168c8e5876225add7d3aff..897ec4ff18783f40e9f66ab626aae6523ca8e87b 100644 (file)
@@ -51,6 +51,7 @@
         <bundle>mvn:org.opendaylight.controller/sal-binding-config/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-inmemory-datastore/{{VERSION}}</bundle>
         <bundle>mvn:org.opendaylight.controller/sal-dom-broker-config/{{VERSION}}</bundle>
+        <bundle start-level="40">mvn:org.opendaylight.controller/blueprint/{{VERSION}}</bundle>
         <configfile finalname="${config.configfile.directory}/${config.mdsal.configfile}">mvn:org.opendaylight.controller/md-sal-config/{{VERSION}}/xml/config</configfile>
     </feature>
     <feature name='odl-toaster' version='${project.version}' description="OpenDaylight :: Toaster">
diff --git a/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/GlobalEventExecutorUtil.java b/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/GlobalEventExecutorUtil.java
deleted file mode 100644 (file)
index 695e36c..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2013 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.protocol.framework;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-
-import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
-import org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
-
-final class GlobalEventExecutorUtil {
-
-    private GlobalEventExecutorUtil() {
-        throw new UnsupportedOperationException();
-    }
-
-    public static ObjectName create(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException {
-        try {
-            return transaction.lookupConfigBean(GlobalEventExecutorModuleFactory.NAME,
-                    GlobalEventExecutorModuleFactory.SINGLETON_NAME);
-        } catch (InstanceNotFoundException e) {
-            try {
-                return transaction.createModule(GlobalEventExecutorModuleFactory.NAME,
-                        GlobalEventExecutorModuleFactory.SINGLETON_NAME);
-            } catch (InstanceAlreadyExistsException e1) {
-                throw new IllegalStateException(e1);
-            }
-        }
-    }
-
-}
diff --git a/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/NeverReconnectStrategyModuleTest.java b/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/NeverReconnectStrategyModuleTest.java
deleted file mode 100644 (file)
index 77589ed..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2013 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.protocol.framework;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.api.jmx.CommitStatus;
-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 org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-public class NeverReconnectStrategyModuleTest extends AbstractConfigTest {
-
-    private static final String INSTANCE_NAME = "never-reconect-strategy-factory-impl";
-    private static final String FACTORY_NAME = NeverReconnectStrategyFactoryModuleFactory.NAME;
-
-    @Before
-    public void setUp() throws Exception {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
-                new NeverReconnectStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory()));
-    }
-
-    @Test
-    public void testValidationExceptionTimeoutNotSet() throws Exception {
-        try {
-            createInstance(null);
-            fail();
-        } catch (ValidationException e) {
-            assertTrue(e.getMessage().contains("Timeout value is not set."));
-        }
-    }
-
-    @Test
-    public void testValidationExceptionTimeoutMinValue() throws Exception {
-        try {
-            createInstance(-1);
-            fail();
-        } catch (ValidationException e) {
-            assertTrue(e.getMessage().contains("is less than 0"));
-        }
-    }
-
-    @Test
-    public void testCreateBean() throws Exception {
-        final CommitStatus status = createInstance();
-        assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 2, 0, 0);
-    }
-
-    @Test
-    public void testReusingOldInstance() throws Exception {
-        createInstance();
-        final ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        assertBeanCount(1, FACTORY_NAME);
-        final CommitStatus status = transaction.commit();
-        assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 0, 0, 2);
-    }
-
-    @Test
-    public void testReconfigure() throws Exception {
-        createInstance();
-        final ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        assertBeanCount(1, FACTORY_NAME);
-        final NeverReconnectStrategyFactoryModuleMXBean mxBean = transaction.newMXBeanProxy(
-                transaction.lookupConfigBean(FACTORY_NAME, INSTANCE_NAME), NeverReconnectStrategyFactoryModuleMXBean.class);
-        mxBean.setTimeout(200);
-        final CommitStatus status = transaction.commit();
-        assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 0, 1, 1);
-    }
-
-    private CommitStatus createInstance() throws Exception {
-        return createInstance(500);
-    }
-
-    private CommitStatus createInstance(final Integer timeout) throws InstanceAlreadyExistsException,
-            ConflictingVersionException, ValidationException {
-        final ConfigTransactionJMXClient transaction = this.configRegistryClient.createTransaction();
-        createInstance(transaction, timeout);
-        return transaction.commit();
-    }
-
-    private static ObjectName createInstance(final ConfigTransactionJMXClient transaction, final Integer timeout)
-            throws InstanceAlreadyExistsException {
-        final ObjectName nameCreated = transaction.createModule(FACTORY_NAME, INSTANCE_NAME);
-        final NeverReconnectStrategyFactoryModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated,
-                NeverReconnectStrategyFactoryModuleMXBean.class);
-        mxBean.setTimeout(timeout);
-        mxBean.setExecutor(GlobalEventExecutorUtil.create(transaction));
-        return nameCreated;
-    }
-
-}
diff --git a/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/ReconnectImmediatelyStrategyModuleTest.java b/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/ReconnectImmediatelyStrategyModuleTest.java
deleted file mode 100644 (file)
index 7e3ed5b..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2013 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.protocol.framework;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.api.jmx.CommitStatus;
-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 org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
-
-public class ReconnectImmediatelyStrategyModuleTest extends AbstractConfigTest {
-
-    private static final String INSTANCE_NAME = "reconnect-immediately-strategy-factory-impl";
-    private static final String FACTORY_NAME = ReconnectImmediatelyStrategyFactoryModuleFactory.NAME;
-
-    @Before
-    public void setUp() throws Exception {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
-                new ReconnectImmediatelyStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory()));
-    }
-
-    @Test
-    public void testValidationExceptionTimeoutNotSet() throws Exception {
-        try {
-            createInstance(null);
-            fail();
-        } catch (ValidationException e) {
-            assertTrue(e.getMessage().contains("Timeout value is not set."));
-        }
-    }
-
-    @Test
-    public void testValidationExceptionTimeoutMinValue() throws Exception {
-        try {
-            createInstance(-1);
-            fail();
-        } catch (ValidationException e) {
-            assertTrue(e.getMessage().contains("is less than 0"));
-        }
-    }
-
-    @Test
-    public void testCreateBean() throws Exception {
-        final CommitStatus status = createInstance();
-        assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 2, 0, 0);
-    }
-
-    @Test
-    public void testReusingOldInstance() throws Exception {
-        createInstance();
-        final ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        assertBeanCount(1, FACTORY_NAME);
-        final CommitStatus status = transaction.commit();
-        assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 0, 0, 2);
-    }
-
-    @Test
-    public void testReconfigure() throws Exception {
-        createInstance();
-        final ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        assertBeanCount(1, FACTORY_NAME);
-        final ReconnectImmediatelyStrategyFactoryModuleMXBean mxBean = transaction.newMXBeanProxy(
-                transaction.lookupConfigBean(FACTORY_NAME, INSTANCE_NAME),
-                ReconnectImmediatelyStrategyFactoryModuleMXBean.class);
-        mxBean.setReconnectTimeout(200);
-        final CommitStatus status = transaction.commit();
-        assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 0, 1, 1);
-    }
-
-    private CommitStatus createInstance() throws Exception {
-        return createInstance(500);
-    }
-
-    private CommitStatus createInstance(final Integer timeout) throws Exception {
-        final ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        createInstance(transaction, timeout);
-        return transaction.commit();
-    }
-
-    private static ObjectName createInstance(final ConfigTransactionJMXClient transaction, final Integer timeout)
-            throws InstanceAlreadyExistsException {
-        final ObjectName nameCreated = transaction.createModule(FACTORY_NAME, INSTANCE_NAME);
-        final ReconnectImmediatelyStrategyFactoryModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated,
-                ReconnectImmediatelyStrategyFactoryModuleMXBean.class);
-        mxBean.setReconnectTimeout(timeout);
-        mxBean.setReconnectExecutor(GlobalEventExecutorUtil.create(transaction));
-        return nameCreated;
-    }
-
-}
diff --git a/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/TimedReconnectStrategyModuleTest.java b/opendaylight/commons/protocol-framework/src/test/java/org/opendaylight/controller/config/yang/protocol/framework/TimedReconnectStrategyModuleTest.java
deleted file mode 100644 (file)
index ec8a9d6..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2013 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.protocol.framework;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.math.BigDecimal;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.ObjectName;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.controller.config.api.ConflictingVersionException;
-import org.opendaylight.controller.config.api.ValidationException;
-import org.opendaylight.controller.config.api.jmx.CommitStatus;
-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 org.opendaylight.controller.config.yang.netty.eventexecutor.GlobalEventExecutorModuleFactory;
-
-public class TimedReconnectStrategyModuleTest extends AbstractConfigTest {
-
-    private static final String INSTANCE_NAME = "timed-reconect-stategy-facotry-impl";
-    private static final String FACTORY_NAME = TimedReconnectStrategyFactoryModuleFactory.NAME;
-
-    @Before
-    public void setUp() throws Exception {
-        super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,
-                new TimedReconnectStrategyFactoryModuleFactory(), new GlobalEventExecutorModuleFactory()));
-    }
-
-    @Test
-    public void testValidationExceptionSleepFactorNotSet() throws Exception {
-        try {
-            createInstance(500, 100L, null, 500L, 10L, 10000L);
-            fail();
-        } catch (ValidationException e) {
-            assertTrue(e.getMessage().contains("SleepFactor value is not set."));
-        }
-    }
-
-    @Test
-    public void testValidationExceptionSleepFactorMinValue() throws Exception {
-        try {
-            createInstance(500, 100L, new BigDecimal(0.5), 500L, 10L, 10000L);
-            fail();
-        } catch (ValidationException e) {
-            assertTrue(e.getMessage().contains("is less than 1"));
-        }
-    }
-
-    @Test
-    public void testValidationExceptionConnectTimeNotSet() throws Exception {
-        try {
-            createInstance(null, 100L, new BigDecimal(1.0), 500L, 10L, 10000L);
-            fail();
-        } catch (ValidationException e) {
-            assertTrue(e.getMessage().contains("ConnectTime value is not set."));
-        }
-    }
-
-    @Test
-    public void testValidationExceptionConnectTimeMinValue() throws Exception {
-        try {
-            createInstance(-1, 100L, new BigDecimal(1.0), 500L, 10L, 10000L);
-            fail();
-        } catch (ValidationException e) {
-            assertTrue(e.getMessage().contains("is less than 0"));
-        }
-    }
-
-    @Test
-    public void testValidationExceptionMinSleepNotSet() throws Exception {
-        try {
-            createInstance(100, null, new BigDecimal(1.0), 100L, 10L, 10000L);
-            fail();
-        } catch (ValidationException e) {
-            assertTrue(e.getMessage().contains("MinSleep value is not set."));
-        }
-    }
-
-    @Test
-    public void testValidationExceptionMaxSleep() throws Exception {
-        try {
-            createInstance(100, 300L, new BigDecimal(1.0), 100L, 10L, 10000L);
-            fail();
-        } catch (ValidationException e) {
-            assertTrue(e.getMessage().contains("is greter than MaxSleep"));
-        }
-    }
-
-    @Test
-    public void testCreateBean() throws Exception {
-        final CommitStatus status = createInstance();
-        assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 2, 0, 0);
-    }
-
-    @Test
-    public void testReusingOldInstance() throws Exception {
-        createInstance();
-        final ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        assertBeanCount(1, FACTORY_NAME);
-        final CommitStatus status = transaction.commit();
-        assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 0, 0, 2);
-    }
-
-    @Test
-    public void testReconfigure() throws Exception {
-        createInstance();
-        final ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        assertBeanCount(1, FACTORY_NAME);
-        final TimedReconnectStrategyFactoryModuleMXBean mxBean = transaction.newMXBeanProxy(
-                transaction.lookupConfigBean(FACTORY_NAME, INSTANCE_NAME), TimedReconnectStrategyFactoryModuleMXBean.class);
-        assertEquals(mxBean.getMinSleep(), new Long(100));
-        mxBean.setMinSleep(200L);
-        assertEquals(mxBean.getMinSleep(), new Long(200));
-        final CommitStatus status = transaction.commit();
-        assertBeanCount(1, FACTORY_NAME);
-        assertStatus(status, 0, 1, 1);
-
-    }
-
-    private CommitStatus createInstance() throws Exception {
-        return createInstance(500, 100L, new BigDecimal(1.0), 500L, 10L, 10000L);
-    }
-
-    private CommitStatus createInstance(final Integer connectTime, final Long minSleep, final BigDecimal sleepFactor,
-            final Long maxSleep, final Long maxAttempts, final Long deadline) throws ConflictingVersionException,
-            ValidationException, InstanceAlreadyExistsException {
-        ConfigTransactionJMXClient transaction = configRegistryClient.createTransaction();
-        createInstance(transaction, INSTANCE_NAME, connectTime, minSleep, sleepFactor, maxSleep, maxAttempts, deadline);
-        return transaction.commit();
-    }
-
-    public static ObjectName createInstance(final ConfigTransactionJMXClient transaction, final String InstanceName)
-            throws Exception {
-        return createInstance(transaction, InstanceName, 500, 100L, new BigDecimal(1.0), 500L, 10L, 10000L);
-    }
-
-    private static ObjectName createInstance(final ConfigTransactionJMXClient transaction, final String instanceName,
-            final Integer connectTime, final Long minSleep, final BigDecimal sleepFactor, final Long maxSleep,
-            final Long maxAttempts, final Long deadline) throws InstanceAlreadyExistsException {
-        final ObjectName nameCreated = transaction.createModule(FACTORY_NAME, instanceName);
-        final TimedReconnectStrategyFactoryModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated,
-                TimedReconnectStrategyFactoryModuleMXBean.class);
-        mxBean.setConnectTime(connectTime);
-        mxBean.setDeadline(deadline);
-        mxBean.setMaxAttempts(maxAttempts);
-        mxBean.setMaxSleep(maxSleep);
-        mxBean.setMinSleep(minSleep);
-        mxBean.setSleepFactor(sleepFactor);
-        mxBean.setTimedReconnectExecutor(GlobalEventExecutorUtil.create(transaction));
-        return nameCreated;
-    }
-
-}
diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/osgi/ServiceNotFoundException.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/osgi/ServiceNotFoundException.java
new file mode 100644 (file)
index 0000000..0d9e7f0
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2016 Brocade Communications 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.api.osgi;
+
+/**
+ * RuntimeException thrown when an OSGi service lookup fails.
+ *
+ * @author Thomas Pantelis
+ */
+public class ServiceNotFoundException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+
+    public ServiceNotFoundException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public ServiceNotFoundException(String message) {
+        super(message);
+    }
+}
diff --git a/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/osgi/WaitingServiceTracker.java b/opendaylight/config/config-api/src/main/java/org/opendaylight/controller/config/api/osgi/WaitingServiceTracker.java
new file mode 100644 (file)
index 0000000..1549e6b
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 Brocade Communications 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.api.osgi;
+
+import java.util.concurrent.TimeUnit;
+import javax.annotation.Nonnull;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.util.tracker.ServiceTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tracker that waits for an OSGi service.
+ *
+ * @author Thomas Pantelis
+ */
+public final class WaitingServiceTracker<T> implements AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(WaitingServiceTracker.class);
+    public static final long FIVE_MINUTES = TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES);
+
+    private final ServiceTracker<T, ?> tracker;
+    private final Class<T> serviceInterface;
+
+    private WaitingServiceTracker(Class<T> serviceInterface, ServiceTracker<T, ?> tracker) {
+        this.tracker = tracker;
+        this.serviceInterface = serviceInterface;
+    }
+
+    /**
+     * Waits for an OSGi services.
+     *
+     * @param timeoutInMillis the timeout in millis
+     * @return the service instance
+     * @throws ServiceNotFoundException if it times out or is interrupted
+     */
+    @SuppressWarnings("unchecked")
+    public T waitForService(long timeoutInMillis) throws ServiceNotFoundException {
+        try {
+            T service = (T) tracker.waitForService(timeoutInMillis);
+            if(service == null) {
+                throw new ServiceNotFoundException(String.format("OSGi Service %s was not found after %d ms",
+                        serviceInterface, timeoutInMillis));
+            }
+
+            return service;
+        } catch(InterruptedException e) {
+            throw new ServiceNotFoundException(String.format("Wait for OSGi service %s was interrrupted",
+                    serviceInterface));
+        }
+    }
+
+    /**
+     * Creates an instance.
+     *
+     * @param serviceInterface the service interface
+     * @param context the BundleContext
+     * @return new WaitingServiceTracker instance
+     */
+    public static <T> WaitingServiceTracker<T> create(@Nonnull Class<T> serviceInterface, @Nonnull BundleContext context) {
+        ServiceTracker<T, ?> tracker = new ServiceTracker<>(context, serviceInterface, null);
+        tracker.open();
+        return new WaitingServiceTracker<T>(serviceInterface, tracker);
+    }
+
+    /**
+     * Creates an instance.
+     *
+     * @param serviceInterface the service interface
+     * @param context the BundleContext
+     * @param filter the OSGi service filter
+     * @return new WaitingServiceTracker instance
+     */
+    public static <T> WaitingServiceTracker<T> create(@Nonnull Class<T> serviceInterface, @Nonnull BundleContext context,
+            @Nonnull String filter) {
+        String newFilter = String.format("(&(%s=%s)%s)", Constants.OBJECTCLASS, serviceInterface.getName(), filter);
+        try {
+            ServiceTracker<T, ?> tracker = new ServiceTracker<>(context, context.createFilter(newFilter), null);
+            tracker.open();
+            return new WaitingServiceTracker<T>(serviceInterface, tracker);
+        } catch(InvalidSyntaxException e) {
+            throw new IllegalArgumentException(String.format("Invalid OSGi filter %s", newFilter), e);
+        }
+    }
+
+    @Override
+    public void close() {
+        try {
+            tracker.close();
+        } catch(RuntimeException e) {
+            // The ServiceTracker could throw IllegalStateException if the BundleContext is already closed.
+            // This is benign so ignore it.
+            LOG.debug("Error closing ServiceTracker", e);
+        }
+    }
+}
index cb721db67d597cac0efc0ef93341c8b264f1a98f..99d94d08e386b2c6df5652d017d781afb5aa08df 100644 (file)
@@ -27,33 +27,43 @@ public interface AutoCloseableEventExecutor extends EventExecutor, AutoCloseable
         }
 
         @Override
-        public void close() {
+        public void close() throws Exception {
             eventExecutor.shutdownGracefully(0, DEFAULT_SHUTDOWN_SECONDS, TimeUnit.SECONDS);
         }
 
 
-        private static AutoCloseableEventExecutor createCloseableProxy(final EventExecutor eventExecutor) {
-            final CloseableEventExecutorMixin closeableGlobalEventExecutorMixin =
-                    new CloseableEventExecutorMixin(eventExecutor);
+        private static AutoCloseableEventExecutor createCloseableProxy(
+                final CloseableEventExecutorMixin closeableEventExecutorMixin) {
             return Reflection.newProxy(AutoCloseableEventExecutor.class, new AbstractInvocationHandler() {
                 @Override
                 protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
                     if (method.getName().equals("close")) {
-                        closeableGlobalEventExecutorMixin.close();
+                        closeableEventExecutorMixin.close();
                         return null;
                     } else {
-                        return method.invoke(eventExecutor, args);
+                        return method.invoke(closeableEventExecutorMixin.eventExecutor, args);
                     }
                 }
             });
         }
 
         public static AutoCloseableEventExecutor globalEventExecutor() {
-            return createCloseableProxy(GlobalEventExecutor.INSTANCE);
+            return createCloseableProxy(new CloseableEventExecutorMixin(GlobalEventExecutor.INSTANCE));
         }
 
         public static AutoCloseableEventExecutor immediateEventExecutor() {
-            return createCloseableProxy(ImmediateEventExecutor.INSTANCE);
+            return createCloseableProxy(new CloseableEventExecutorMixin(ImmediateEventExecutor.INSTANCE));
+        }
+
+        public static AutoCloseableEventExecutor forwardingEventExecutor(final EventExecutor eventExecutor,
+                final AutoCloseable closeable) {
+            return createCloseableProxy(new CloseableEventExecutorMixin(eventExecutor) {
+                @Override
+                public void close() throws Exception {
+                    // Intentional no-op.
+                    closeable.close();
+                }
+            });
         }
     }
 }
\ No newline at end of file
index caca6b1b64e70a747b55f0ab1cc45267980fc206..da0639187d0cd7b7569f93b1b5f6416384de9108 100644 (file)
  */
 package org.opendaylight.controller.config.yang.netty.eventexecutor;
 
+import io.netty.util.concurrent.EventExecutor;
+import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
 import org.opendaylight.controller.config.yang.netty.eventexecutor.AutoCloseableEventExecutor.CloseableEventExecutorMixin;
+import org.osgi.framework.BundleContext;
 
 public final class GlobalEventExecutorModule extends
         org.opendaylight.controller.config.yang.netty.eventexecutor.AbstractGlobalEventExecutorModule {
+    private BundleContext bundleContext;
 
     public GlobalEventExecutorModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
             org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -39,10 +43,15 @@ public final class GlobalEventExecutorModule extends
     }
 
     @Override
-    public java.lang.AutoCloseable createInstance() {
-        return CloseableEventExecutorMixin.globalEventExecutor();
+    public AutoCloseable createInstance() {
+        // The service is provided via blueprint so wait for and return it here for backwards compatibility.
+        final WaitingServiceTracker<EventExecutor> tracker = WaitingServiceTracker.create(
+                EventExecutor.class, bundleContext, "(type=global-event-executor)");
+        EventExecutor eventExecutor = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
+        return CloseableEventExecutorMixin.forwardingEventExecutor(eventExecutor, tracker);
     }
 
-
-
+    public void setBundleContext(final BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
 }
index 1ca57c637f562e834eb6f686a25613f5cff91542..467f0689e9b5c0d852d0cb273dac036afcab3900 100644 (file)
@@ -18,7 +18,6 @@
 package org.opendaylight.controller.config.yang.netty.eventexecutor;
 
 import static com.google.common.base.Preconditions.checkArgument;
-
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.osgi.framework.BundleContext;
 
@@ -29,12 +28,17 @@ public class GlobalEventExecutorModuleFactory extends org.opendaylight.controlle
     @Override
     public GlobalEventExecutorModule instantiateModule(String instanceName, DependencyResolver dependencyResolver, GlobalEventExecutorModule oldModule, AutoCloseable oldInstance, BundleContext bundleContext) {
         checkArgument(SINGLETON_NAME.equals(instanceName),"Illegal instance name '" + instanceName + "', only allowed name is " + SINGLETON_NAME);
-        return super.instantiateModule(instanceName, dependencyResolver, oldModule, oldInstance, bundleContext);
+        GlobalEventExecutorModule module = super.instantiateModule(instanceName, dependencyResolver, oldModule,
+                oldInstance, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
     }
 
     @Override
     public GlobalEventExecutorModule instantiateModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
         checkArgument(SINGLETON_NAME.equals(instanceName),"Illegal instance name '" + instanceName + "', only allowed name is " + SINGLETON_NAME);
-        return super.instantiateModule(instanceName, dependencyResolver, bundleContext);
+        GlobalEventExecutorModule module = super.instantiateModule(instanceName, dependencyResolver, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
     }
 }
index 8fe3d7c24c2c6f8fb2001c12ba4b8d7bc03041b2..7d763699ffd4e7d3ba9bad4ec0f6eb6bbb2960e6 100644 (file)
@@ -10,7 +10,12 @@ package org.opendaylight.controller.config.yang.netty.eventexecutor;
 
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
-
+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 io.netty.util.concurrent.EventExecutor;
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.ObjectName;
 import org.junit.Before;
@@ -21,16 +26,29 @@ import org.opendaylight.controller.config.api.jmx.CommitStatus;
 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 org.osgi.framework.Filter;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
 
 public class GlobalEventExecutorModuleTest extends AbstractConfigTest {
 
     private GlobalEventExecutorModuleFactory factory;
     private final String instanceName = GlobalEventExecutorModuleFactory.SINGLETON_NAME;
 
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         factory = new GlobalEventExecutorModuleFactory();
         super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
+
+        Filter mockFilter = mock(Filter.class);
+        doReturn("mock").when(mockFilter).toString();
+        doReturn(mockFilter).when(mockedContext).createFilter(anyString());
+        doNothing().when(mockedContext).addServiceListener(any(ServiceListener.class), anyString());
+        ServiceReference mockServiceRef = mock(ServiceReference.class);
+        doReturn(new ServiceReference[]{mockServiceRef}).when(mockedContext).
+                getServiceReferences(anyString(), anyString());
+        doReturn(mock(EventExecutor.class)).when(mockedContext).getService(mockServiceRef);
     }
 
     @Test
index 223eca1d38ff0e60b77c9273fcc3960cb4da5490..5a0e48372731f22a90d187ffeff0287fb30091de 100644 (file)
@@ -68,7 +68,6 @@
           <instructions>
             <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
             <Export-Package>org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.netty.threadgroup.rev131107.*,</Export-Package>
-            <Import-Package>*,io.netty.channel</Import-Package>
           </instructions>
         </configuration>
       </plugin>
index 54266f4e840e456c28f1625bec9b5fd27f786e8e..09ea6720019cdf9c539c1e81921745d757d4f07d 100644 (file)
 */
 package org.opendaylight.controller.config.yang.netty.threadgroup;
 
+import com.google.common.reflect.AbstractInvocationHandler;
+import com.google.common.reflect.Reflection;
+import io.netty.channel.EventLoopGroup;
+import java.lang.reflect.Method;
 import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
+import org.osgi.framework.BundleContext;
 
 /**
 *
 */
 public final class NettyThreadgroupModule extends org.opendaylight.controller.config.yang.netty.threadgroup.AbstractNettyThreadgroupModule
 {
+    private BundleContext bundleContext;
+
     public NettyThreadgroupModule(org.opendaylight.controller.config.api.ModuleIdentifier name, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(name, dependencyResolver);
     }
@@ -41,7 +49,30 @@ public final class NettyThreadgroupModule extends org.opendaylight.controller.co
     }
 
     @Override
-    public java.lang.AutoCloseable createInstance() {
-        return NioEventLoopGroupCloseable.newInstance(getThreadCount());
+    public AutoCloseable createInstance() {
+        // The service is provided via blueprint so wait for and return it here for backwards compatibility.
+        String typeFilter = String.format("(type=%s)", getIdentifier().getInstanceName());
+        final WaitingServiceTracker<EventLoopGroup> tracker = WaitingServiceTracker.create(
+                EventLoopGroup.class, bundleContext, typeFilter);
+        final EventLoopGroup group = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
+
+        return Reflection.newProxy(AutoCloseableEventLoopGroupInterface.class, new AbstractInvocationHandler() {
+            @Override
+            protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
+                if (method.getName().equals("close")) {
+                    tracker.close();
+                    return null;
+                } else {
+                    return method.invoke(group, args);
+                }
+            }
+        });
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+
+    private static interface AutoCloseableEventLoopGroupInterface extends EventLoopGroup, AutoCloseable {
     }
 }
index c97bd566b07f98ac8ad9914e1db24308a081dd5a..b509932568426701d1e7e224cc42ba13a8e7f01a 100644 (file)
 */
 package org.opendaylight.controller.config.yang.netty.threadgroup;
 
-/**
-*
-*/
-public class NettyThreadgroupModuleFactory extends org.opendaylight.controller.config.yang.netty.threadgroup.AbstractNettyThreadgroupModuleFactory
-{
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.osgi.framework.BundleContext;
 
+public class NettyThreadgroupModuleFactory extends AbstractNettyThreadgroupModuleFactory {
+    @Override
+    public NettyThreadgroupModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+            NettyThreadgroupModule oldModule, AutoCloseable oldInstance, BundleContext bundleContext) {
+        NettyThreadgroupModule module = super.instantiateModule(instanceName, dependencyResolver, oldModule, oldInstance, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
 
+    @Override
+    public NettyThreadgroupModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+            BundleContext bundleContext) {
+        NettyThreadgroupModule module = super.instantiateModule(instanceName, dependencyResolver, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
 }
index ceefcda6def92db8f9eb027d08344283f6d83f55..81f85845fb282996e637316fa37a60daf4c0fd48 100644 (file)
@@ -7,6 +7,12 @@
  */
 package org.opendaylight.controller.config.yang.netty.threadgroup;
 
+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 io.netty.channel.EventLoopGroup;
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.InstanceNotFoundException;
 import javax.management.ObjectName;
@@ -18,16 +24,29 @@ import org.opendaylight.controller.config.api.jmx.CommitStatus;
 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 org.osgi.framework.Filter;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
 
 public class NettyThreadgroupModuleTest extends AbstractConfigTest {
 
     private NettyThreadgroupModuleFactory factory;
     private final String instanceName = "netty1";
 
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         factory = new NettyThreadgroupModuleFactory();
         super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext,factory));
+
+        Filter mockFilter = mock(Filter.class);
+        doReturn("mock").when(mockFilter).toString();
+        doReturn(mockFilter).when(mockedContext).createFilter(anyString());
+        doNothing().when(mockedContext).addServiceListener(any(ServiceListener.class), anyString());
+        ServiceReference mockServiceRef = mock(ServiceReference.class);
+        doReturn(new ServiceReference[]{mockServiceRef}).when(mockedContext).
+                getServiceReferences(anyString(), anyString());
+        doReturn(mock(EventLoopGroup.class)).when(mockedContext).getService(mockServiceRef);
     }
 
     @Test
index 7114ed6025833be1343505caa6706a16c2a88efb..76d75e83728ca6aa86ec0fc903c14c163bc33e7c 100644 (file)
  */
 package org.opendaylight.controller.config.yang.netty.timer;
 
+import com.google.common.reflect.AbstractInvocationHandler;
+import com.google.common.reflect.Reflection;
+import io.netty.util.Timer;
+import java.lang.reflect.Method;
 import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
+import org.osgi.framework.BundleContext;
 
 /**
 *
 */
 public final class HashedWheelTimerModule extends
         org.opendaylight.controller.config.yang.netty.timer.AbstractHashedWheelTimerModule {
+    private BundleContext bundleContext;
 
     public HashedWheelTimerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier,
             org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -50,7 +57,29 @@ public final class HashedWheelTimerModule extends
     }
 
     @Override
-    public java.lang.AutoCloseable createInstance() {
-        return HashedWheelTimerCloseable.newInstance(getThreadFactoryDependency(), getTickDuration(), getTicksPerWheel());
+    public AutoCloseable createInstance() {
+        // The service is provided via blueprint so wait for and return it here for backwards compatibility.
+        final WaitingServiceTracker<Timer> tracker = WaitingServiceTracker.create(
+                Timer.class, bundleContext, "(type=global-timer)");
+        final Timer timer = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
+
+        return Reflection.newProxy(AutoCloseableTimerInterface.class, new AbstractInvocationHandler() {
+            @Override
+            protected Object handleInvocation(Object proxy, Method method, Object[] args) throws Throwable {
+                if (method.getName().equals("close")) {
+                    tracker.close();
+                    return null;
+                } else {
+                    return method.invoke(timer, args);
+                }
+            }
+        });
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+
+    private static interface AutoCloseableTimerInterface extends Timer, AutoCloseable {
     }
 }
index c869413a5e1726349d894cb9ab140dbb8439cd31..d8ec0fcf90606515a96d69cd4055c94ba2153eb9 100644 (file)
  */
 package org.opendaylight.controller.config.yang.netty.timer;
 
-/**
-*
-*/
-public class HashedWheelTimerModuleFactory extends
-        org.opendaylight.controller.config.yang.netty.timer.AbstractHashedWheelTimerModuleFactory {
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.osgi.framework.BundleContext;
+
+public class HashedWheelTimerModuleFactory extends AbstractHashedWheelTimerModuleFactory {
+    @Override
+    public HashedWheelTimerModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+            HashedWheelTimerModule oldModule, AutoCloseable oldInstance, BundleContext bundleContext) {
+        HashedWheelTimerModule module = super.instantiateModule(instanceName, dependencyResolver, oldModule,
+                oldInstance, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
 
+    @Override
+    public HashedWheelTimerModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+            BundleContext bundleContext) {
+        HashedWheelTimerModule module = super.instantiateModule(instanceName, dependencyResolver, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
 }
index 6ffeb0490d0539874d7cc59e0b07507f1f073a20..99368239737b3995e931b895a73eaa109f8b3f7d 100644 (file)
@@ -9,7 +9,12 @@ package org.opendaylight.controller.config.yang.netty.timer;
 
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
-
+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 io.netty.util.Timer;
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.InstanceNotFoundException;
 import javax.management.ObjectName;
@@ -23,6 +28,9 @@ import org.opendaylight.controller.config.manager.impl.factoriesresolver.Hardcod
 import org.opendaylight.controller.config.util.ConfigTransactionJMXClient;
 import org.opendaylight.controller.config.yang.threadpool.impl.NamingThreadFactoryModuleFactory;
 import org.opendaylight.controller.config.yang.threadpool.impl.NamingThreadFactoryModuleMXBean;
+import org.osgi.framework.Filter;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
 
 public class HashedWheelTimerModuleTest extends AbstractConfigTest {
 
@@ -30,11 +38,21 @@ public class HashedWheelTimerModuleTest extends AbstractConfigTest {
     private NamingThreadFactoryModuleFactory threadFactory;
     private final String instanceName = "hashed-wheel-timer1";
 
+    @SuppressWarnings({ "rawtypes", "unchecked" })
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         factory = new HashedWheelTimerModuleFactory();
         threadFactory = new NamingThreadFactoryModuleFactory();
         super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(mockedContext, factory, threadFactory));
+
+        Filter mockFilter = mock(Filter.class);
+        doReturn("mock").when(mockFilter).toString();
+        doReturn(mockFilter).when(mockedContext).createFilter(anyString());
+        doNothing().when(mockedContext).addServiceListener(any(ServiceListener.class), anyString());
+        ServiceReference mockServiceRef = mock(ServiceReference.class);
+        doReturn(new ServiceReference[]{mockServiceRef}).when(mockedContext).
+                getServiceReferences(anyString(), anyString());
+        doReturn(mock(Timer.class)).when(mockedContext).getService(mockServiceRef);
     }
 
     public void testValidationExceptionTickDuration() throws InstanceAlreadyExistsException {
index 5ca041a3e60a4b40fb043fa9045e4dd4995c9171..526f4005f50f5b54574da8b8048dafd5c773561d 100644 (file)
@@ -8,16 +8,13 @@
 package org.opendaylight.controller.sal.binding.test.util;
 
 import static com.google.common.base.Preconditions.checkState;
-
 import com.google.common.annotations.Beta;
 import com.google.common.collect.ClassToInstanceMap;
-import com.google.common.collect.ImmutableClassToInstanceMap;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.MutableClassToInstanceMap;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
-import javassist.ClassPool;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.MountPointService;
 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
@@ -50,7 +47,6 @@ import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
 import org.opendaylight.controller.sal.binding.impl.RootBindingAwareBroker;
-import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
 import org.opendaylight.controller.sal.core.api.BrokerService;
 import org.opendaylight.controller.sal.core.spi.data.DOMStore;
 import org.opendaylight.controller.sal.dom.broker.BrokerImpl;
@@ -63,6 +59,7 @@ import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
 import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import javassist.ClassPool;
 
 @Beta
 public class BindingTestContext implements AutoCloseable {
@@ -175,33 +172,6 @@ public class BindingTestContext implements AutoCloseable {
 
     }
 
-    private ProviderSession createMockContext() {
-
-        final ClassToInstanceMap<BrokerService> domBrokerServices = ImmutableClassToInstanceMap
-                .<BrokerService> builder()
-                //
-                .put(DOMRpcRouter.class, biBrokerImpl.getRouter()) //
-                .put(DOMMountPointService.class, biMountImpl)
-                .build();
-
-        return new ProviderSession() {
-
-            @Override
-            public <T extends BrokerService> T getService(final Class<T> service) {
-                return domBrokerServices.getInstance(service);
-            }
-
-            @Override
-            public boolean isClosed() {
-                return false;
-            }
-
-            @Override
-            public void close() {
-            }
-        };
-    }
-
     public void startBindingToDomMappingService() {
         checkState(classPool != null, "ClassPool needs to be present");
 
index e2d942e9cd7cc8cf60d989d347f03fd4150d8264..f6b86ebcd14abb84bddadf56aada5774d22a200a 100644 (file)
@@ -8,20 +8,18 @@
 package org.opendaylight.controller.config.yang.md.sal.binding.impl;
 
 import com.google.common.base.Preconditions;
-import java.util.Hashtable;
+import com.google.common.base.Stopwatch;
+import com.google.common.util.concurrent.Uninterruptibles;
+import java.util.concurrent.TimeUnit;
 import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec;
-import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder;
-import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator;
-import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
-import org.opendaylight.yangtools.sal.binding.generator.api.ClassLoadingStrategy;
-import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodecFactory;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
 
 /**
  *
 **/
 public final class RuntimeMappingModule extends AbstractRuntimeMappingModule {
+    private static final long WAIT_IN_MINUTES = 5;
 
     private BundleContext bundleContext;
 
@@ -50,16 +48,31 @@ public final class RuntimeMappingModule extends AbstractRuntimeMappingModule {
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        final ClassLoadingStrategy classLoading = getGlobalClassLoadingStrategy();
-        final BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator.create(SingletonHolder.JAVASSIST));
-        final BindingToNormalizedNodeCodec instance = new BindingToNormalizedNodeCodec(classLoading, codecRegistry,getWaitForSchema());
-        bundleContext.registerService(SchemaContextListener.class, instance, new Hashtable<String,String>());
-        return instance;
-    }
+        // This is kind of ugly - you might cringe (you've been warned). The BindingToNormalizedNodeCodec
+        // instance is advertised via blueprint so ideally we'd obtain it from the OSGi service registry.
+        // The config yang service identity declares the concrete BindingToNormalizedNodeCodec class
+        // and not an interface as the java-class so we must return a BindingToNormalizedNodeCodec instance.
+        // However we can't cast the instance obtained from the service registry to
+        // BindingToNormalizedNodeCodec b/c Aries may register a proxy if there are interceptors defined.
+        // By default karaf ships with the org.apache.aries.quiesce.api bundle which automatically adds
+        // an interceptor that adds stat tracking for service method calls. While this can be disabled, we
+        // shouldn't rely on it.
+        //
+        // Therefore we store a static instance in the BindingToNormalizedNodeCodecFactory which is created
+        // by blueprint via newInstance. We obtain the static instance here and busy wait if not yet available.
+
+        Stopwatch sw = Stopwatch.createStarted();
+        while(sw.elapsed(TimeUnit.MINUTES) <= WAIT_IN_MINUTES) {
+            BindingToNormalizedNodeCodec instance = BindingToNormalizedNodeCodecFactory.getInstance();
+            if(instance != null) {
+                return instance;
+            }
+
+            Uninterruptibles.sleepUninterruptibly(50, TimeUnit.MILLISECONDS);
+        }
 
-    private ClassLoadingStrategy getGlobalClassLoadingStrategy() {
-        final ServiceReference<ClassLoadingStrategy> ref = bundleContext.getServiceReference(ClassLoadingStrategy.class);
-        return bundleContext.getService(ref);
+        throw new IllegalStateException("Could not obtain the BindingToNormalizedNodeCodec instance after " +
+                WAIT_IN_MINUTES + " minutes.");
     }
 
     public void setBundleContext(final BundleContext bundleContext) {
index 3244b5a4ee6f25e6653fb0258889b6ff1ecc4e79..a56e2f9e32d18ca67f85a0e40275eb541bc6c7ef 100644 (file)
@@ -19,18 +19,21 @@ module opendaylight-sal-binding-broker-impl {
     identity binding-dom-mapping-service {
         base config:service-type;
         config:java-class "org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec";
+        config:disable-osgi-service-registration;
     }
 
     /* FIXME: move to opendaylight-md-sal-binding (cannot be there due to Class name confict with old implementation)*/
     identity binding-new-notification-service {
         base config:service-type;
         config:java-class "org.opendaylight.controller.md.sal.binding.api.NotificationService";
+        config:disable-osgi-service-registration;
     }
 
     /* TODO: move to opendaylight-md-sal-binding (cannot be there due to Class name confict with old implementation)*/
     identity binding-new-notification-publish-service {
         base config:service-type;
         config:java-class "org.opendaylight.controller.md.sal.binding.api.NotificationPublishService";
+        config:disable-osgi-service-registration;
     }
 
     identity binding-broker-impl {
@@ -134,7 +137,7 @@ module opendaylight-sal-binding-broker-impl {
                 container notification-service {
                     uses config:service-ref {
                         refine type {
-                            mandatory true;
+                            mandatory false;
                             config:required-identity sal:binding-notification-service;
                         }
                     }
index 18a94dfacded8d6523f4195c6b44f71842c5be34..f1f19b4c1e5c0eb2d31b18c6b0806b837b6358dc 100644 (file)
@@ -26,6 +26,7 @@ module opendaylight-md-sal-binding {
     identity binding-async-data-broker {
         base "config:service-type";
         config:java-class "org.opendaylight.controller.md.sal.binding.api.DataBroker";
+        config:disable-osgi-service-registration;
     }
 
     identity binding-data-consumer-broker {
@@ -36,26 +37,31 @@ module opendaylight-md-sal-binding {
     identity binding-rpc-registry {
         base "config:service-type";
         config:java-class "org.opendaylight.controller.sal.binding.api.RpcProviderRegistry";
+        config:disable-osgi-service-registration;
     }
 
     identity binding-notification-service {
         base "config:service-type";
         config:java-class "org.opendaylight.controller.sal.binding.api.NotificationProviderService";
+        config:disable-osgi-service-registration;
     }
 
     identity binding-codec-tree-factory {
         base "config:service-type";
         config:java-class "org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTreeFactory";
+        config:disable-osgi-service-registration;
     }
 
     identity binding-normalized-node-serializer {
         base "config:service-type";
         config:java-class "org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer";
+        config:disable-osgi-service-registration;
     }
 
     identity binding-notification-subscription-service {
         base "config:service-type";
         config:java-class "org.opendaylight.controller.sal.binding.api.NotificationService";
+        config:disable-osgi-service-registration;
     }
 
 }
index f284851cd9e9731c17b16966872d8fe859bfd0df..4f97c3ae5262c3619cdc10fd8cd8e89548a6f2c7 100644 (file)
@@ -14,5 +14,6 @@ module actor-system-provider-service {
     identity actor-system-provider-service {
         base "config:service-type";
         config:java-class  "org.opendaylight.controller.cluster.ActorSystemProvider";
+        config:disable-osgi-service-registration;
     }
 }
\ No newline at end of file
index f16f7c443031178317e90b4dd181f2adb1248e65..28aee9fd4ce2da967806a8e0b931e8574bf7d665 100644 (file)
@@ -14,5 +14,6 @@ module opendaylight-entity-ownership-service {
     identity entity-ownership-service {
         base "config:service-type";
         config:java-class  "org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService";
+        config:disable-osgi-service-registration;
     }
 }
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/NoopAutoCloseable.java b/opendaylight/md-sal/sal-common-util/src/main/java/org/opendaylight/controller/sal/common/util/NoopAutoCloseable.java
new file mode 100644 (file)
index 0000000..7f95f96
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016 Brocade Communications 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.sal.common.util;
+
+/**
+ * An AutoCloseable that does nothing.
+ *
+ * @author Thomas Pantelis
+ */
+public final class NoopAutoCloseable implements AutoCloseable {
+    public static final NoopAutoCloseable INSTANCE = new NoopAutoCloseable();
+
+    private NoopAutoCloseable() {
+    }
+
+    @Override
+    public void close() {
+    }
+}
index 935af23caedb64c0a21e77578125db69b127d2de..d545cf49ecf1e72e51db6b188b8ca8dd5ff9670e 100644 (file)
             <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
             <Bundle-Activator>org.opendaylight.controller.cluster.datastore.osgi.Activator</Bundle-Activator>
             <Export-Package></Export-Package>
-            <Import-Package>!*snappy;!org.jboss.*;!com.jcraft.*;!*jetty*;!sun.security.*;*</Import-Package>
+            <Import-Package>
+                !*snappy;
+                !org.jboss.*;
+                !com.jcraft.*;
+                !*jetty*;
+                !sun.security.*;
+                *;
+                org.opendaylight.controller.md.sal.dom.broker.impl.jmx
+            </Import-Package>
             <!--
             <Embed-Dependency>
                 sal-clustering-commons;
index 198c3b2edaa137e6a2b6c5d32d14a1b00798106b..579c89747ab9847192c836a0c2cd383d5f98e391 100644 (file)
@@ -27,7 +27,6 @@ import org.opendaylight.controller.cluster.datastore.utils.PrimaryShardInfoFutur
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeListener;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeListener;
-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.DOMStoreTransactionChain;
@@ -44,7 +43,7 @@ import org.slf4j.LoggerFactory;
 /**
  *
  */
-public class DistributedDataStore implements DOMStore, SchemaContextListener,
+public class DistributedDataStore implements DistributedDataStoreInterface, SchemaContextListener,
         DatastoreContextConfigAdminOverlay.Listener, DOMStoreTreeChangePublisher, AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(DistributedDataStore.class);
@@ -215,6 +214,7 @@ public class DistributedDataStore implements DOMStore, SchemaContextListener,
         actorContext.shutdown();
     }
 
+    @Override
     public ActorContext getActorContext() {
         return actorContext;
     }
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreInterface.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStoreInterface.java
new file mode 100644 (file)
index 0000000..b678d17
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2016 Brocade Communications 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.cluster.datastore;
+
+import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
+import org.opendaylight.controller.sal.core.spi.data.DOMStore;
+
+/**
+ * The public interface exposed vi a DistributedDataStore via the OSGi registry.
+ *
+ * @author Thomas Pantelis
+ */
+public interface DistributedDataStoreInterface extends DOMStore {
+
+    ActorContext getActorContext();
+}
\ No newline at end of file
index a67d3de96402827d81557c5cc4f9a4056255e4c7..39aafcaed5faa7571f65d3ce356d3bcbf7492c03 100644 (file)
@@ -28,7 +28,7 @@ import java.util.Set;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import org.apache.commons.lang3.SerializationUtils;
-import org.opendaylight.controller.cluster.datastore.DistributedDataStore;
+import org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface;
 import org.opendaylight.controller.cluster.datastore.messages.AddShardReplica;
 import org.opendaylight.controller.cluster.datastore.messages.DatastoreSnapshot;
 import org.opendaylight.controller.cluster.datastore.messages.DatastoreSnapshotList;
@@ -67,11 +67,12 @@ public class ClusterAdminRpcService implements ClusterAdminService, AutoCloseabl
 
     private static final Logger LOG = LoggerFactory.getLogger(ClusterAdminRpcService.class);
 
-    private final DistributedDataStore configDataStore;
-    private final DistributedDataStore operDataStore;
+    private final DistributedDataStoreInterface configDataStore;
+    private final DistributedDataStoreInterface operDataStore;
     private RpcRegistration<ClusterAdminService> rpcRegistration;
 
-    public ClusterAdminRpcService(DistributedDataStore configDataStore, DistributedDataStore operDataStore) {
+    public ClusterAdminRpcService(DistributedDataStoreInterface configDataStore,
+            DistributedDataStoreInterface operDataStore) {
         this.configDataStore = configDataStore;
         this.operDataStore = operDataStore;
     }
index 89f296d47dea08f93396ef6431eee2459acd7df9..8c2e8d05463684107460ae347ea9d235e1d71c80 100644 (file)
@@ -8,6 +8,12 @@
 
 package org.opendaylight.controller.config.yang.config.actor_system_provider.impl;
 
+import akka.actor.ActorSystem;
+import com.google.common.collect.ForwardingObject;
+import org.opendaylight.controller.cluster.ActorSystemProvider;
+import org.opendaylight.controller.cluster.ActorSystemProviderListener;
+import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.osgi.framework.BundleContext;
 
 public class ActorSystemProviderModule extends AbstractActorSystemProviderModule {
@@ -27,11 +33,53 @@ public class ActorSystemProviderModule extends AbstractActorSystemProviderModule
     }
 
     @Override
-    public java.lang.AutoCloseable createInstance() {
-        return new ActorSystemProviderImpl(bundleContext);
+    public boolean canReuseInstance(AbstractActorSystemProviderModule oldModule) {
+        return true;
+    }
+
+    @Override
+    public AutoCloseable createInstance() {
+        // The service is provided via blueprint so wait for and return it here for backwards compatibility.
+        WaitingServiceTracker<ActorSystemProvider> tracker = WaitingServiceTracker.create(
+                ActorSystemProvider.class, bundleContext);
+        ActorSystemProvider delegate = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
+        return new ForardingActorSystemProvider(delegate, tracker);
     }
 
     public void setBundleContext(BundleContext bundleContext) {
         this.bundleContext = bundleContext;
     }
+
+    private static class ForardingActorSystemProvider extends ForwardingObject
+            implements ActorSystemProvider, AutoCloseable {
+        private final ActorSystemProvider delegate;
+        private final AutoCloseable closeable;
+
+        ForardingActorSystemProvider(ActorSystemProvider delegate, AutoCloseable closeable) {
+            this.delegate = delegate;
+            this.closeable = closeable;
+        }
+
+        @Override
+        public ActorSystem getActorSystem() {
+            return delegate().getActorSystem();
+        }
+
+        @Override
+        public ListenerRegistration<ActorSystemProviderListener> registerActorSystemProviderListener(
+                ActorSystemProviderListener listener) {
+            return delegate().registerActorSystemProviderListener(listener);
+        }
+
+        @Override
+        protected ActorSystemProvider delegate() {
+            return delegate;
+        }
+
+        @Override
+        public void close() throws Exception {
+            // We don't close the delegate as the life-cycle is controlled via blueprint.
+            closeable.close();
+        }
+    }
 }
index 0d96368f1c68a0f22a6324303b4fb8dbb682ce72..facc07f11d121044a8c8d5d1299f95d38d315bad 100644 (file)
@@ -9,7 +9,7 @@
 package org.opendaylight.controller.config.yang.config.cluster_admin_provider;
 
 import com.google.common.base.Preconditions;
-import org.opendaylight.controller.cluster.datastore.DistributedDataStore;
+import org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface;
 import org.opendaylight.controller.cluster.datastore.admin.ClusterAdminRpcService;
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
@@ -31,13 +31,14 @@ public class ClusterAdminProviderModule extends AbstractClusterAdminProviderModu
 
     @Override
     public AutoCloseable createInstance() {
-        Preconditions.checkArgument(getConfigDataStoreDependency() instanceof DistributedDataStore,
-                "Injected config DOMStore must be an instance of DistributedDataStore");
-        Preconditions.checkArgument(getOperDataStoreDependency() instanceof DistributedDataStore,
-                "Injected operational DOMStore must be an instance of DistributedDataStore");
-        ClusterAdminRpcService service = new ClusterAdminRpcService((DistributedDataStore)getConfigDataStoreDependency(),
-                (DistributedDataStore)getOperDataStoreDependency());
+        Preconditions.checkArgument(getConfigDataStoreDependency() instanceof DistributedDataStoreInterface,
+                "Injected config DOMStore must be an instance of DistributedDataStoreInterface");
+        Preconditions.checkArgument(getOperDataStoreDependency() instanceof DistributedDataStoreInterface,
+                "Injected operational DOMStore must be an instance of DistributedDataStoreInterface");
+        ClusterAdminRpcService service = new ClusterAdminRpcService(
+                (DistributedDataStoreInterface)getConfigDataStoreDependency(),
+                (DistributedDataStoreInterface)getOperDataStoreDependency());
         service.start(getRpcRegistryDependency());
         return service;
     }
-}
+}
\ No newline at end of file
index 262197fcf520b7929629e970eee7a73c628d2935..596229360ae14a849a41b12844edfb1379840b08 100644 (file)
@@ -7,24 +7,14 @@
  */
 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.databroker.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;
+import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
+import org.opendaylight.controller.md.sal.dom.spi.ForwardingDOMDataBroker;
+import org.osgi.framework.BundleContext;
 
 public class DomConcurrentDataBrokerModule extends AbstractDomConcurrentDataBrokerModule {
-    private static final String JMX_BEAN_TYPE = "DOMDataBroker";
+    private BundleContext bundleContext;
 
     public DomConcurrentDataBrokerModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
@@ -41,64 +31,36 @@ public class DomConcurrentDataBrokerModule extends AbstractDomConcurrentDataBrok
 
     @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");
+        // The ConcurrentDOMDataBroker is provided via blueprint so wait for and return it here for
+        // backwards compatibility.
+        WaitingServiceTracker<DOMDataBroker> tracker = WaitingServiceTracker.create(
+                DOMDataBroker.class, bundleContext, "(type=default)");
+        DOMDataBroker delegate = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
+        return new ForwardingConcurrentDOMBroker(delegate, tracker);
+    }
 
-        final List<AbstractMXBean> mBeans = Lists.newArrayList();
+    public void setBundleContext(final BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
 
-        final DurationStatisticsTracker commitStatsTracker;
-        final ConcurrentDOMDataBroker cdb = new ConcurrentDOMDataBroker(datastores, listenableFutureExecutor);
-        commitStatsTracker = cdb.getCommitStatsTracker();
+    private static class ForwardingConcurrentDOMBroker extends ForwardingDOMDataBroker implements AutoCloseable {
+        private final DOMDataBroker delegate;
+        private final AutoCloseable closeable;
 
-        if(commitStatsTracker != null) {
-            final CommitStatsMXBeanImpl commitStatsMXBean = new CommitStatsMXBeanImpl(
-                    commitStatsTracker, JMX_BEAN_TYPE);
-            commitStatsMXBean.registerMBean();
-            mBeans.add(commitStatsMXBean);
+        ForwardingConcurrentDOMBroker(DOMDataBroker delegate, AutoCloseable closeable) {
+            this.delegate = delegate;
+            this.closeable = closeable;
         }
 
-        final AbstractMXBean commitFutureStatsMXBean =
-                ThreadExecutorStatsMXBeanImpl.create(listenableFutureExecutor,
-                        "CommitFutureExecutorStats", JMX_BEAN_TYPE, null);
-        if(commitFutureStatsMXBean != null) {
-            mBeans.add(commitFutureStatsMXBean);
+        @Override
+        protected DOMDataBroker delegate() {
+            return delegate;
         }
 
-        cdb.setCloseable(new AutoCloseable() {
-            @Override
-            public void close() {
-                for(AbstractMXBean mBean: mBeans) {
-                    mBean.unregisterMBean();
-                }
-            }
-        });
-
-        return cdb;
+        @Override
+        public void close() throws Exception {
+            // We don't close the delegate as the life-cycle is controlled via blueprint.
+            closeable.close();
+        }
     }
 }
index d42c44449378500fe2fd8bb13284681f976469e0..c6f5a9e70c8076b7a10e5bd251a8fe3a24116923 100644 (file)
@@ -7,6 +7,26 @@
  */
 package org.opendaylight.controller.config.yang.config.concurrent_data_broker;
 
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
+
 public class DomConcurrentDataBrokerModuleFactory extends AbstractDomConcurrentDataBrokerModuleFactory {
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
+        DomConcurrentDataBrokerModule module = (DomConcurrentDataBrokerModule)super.createModule(instanceName,
+                dependencyResolver, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
 
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver, DynamicMBeanWithInstance old,
+            BundleContext bundleContext) throws Exception {
+        DomConcurrentDataBrokerModule module = (DomConcurrentDataBrokerModule)super.createModule(instanceName,
+                dependencyResolver, old, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
 }
index daa4c14cb2afdf995ce4753707074bd93bd364ad..30763234500ee023528d6088722874cbaff846d1 100644 (file)
@@ -9,8 +9,8 @@
 package org.opendaylight.controller.config.yang.config.distributed_datastore_provider;
 
 import org.opendaylight.controller.cluster.datastore.DatastoreContext;
-import org.opendaylight.controller.cluster.datastore.DatastoreSnapshotRestore;
-import org.opendaylight.controller.cluster.datastore.DistributedDataStoreFactory;
+import org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface;
+import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.osgi.framework.BundleContext;
 
@@ -43,12 +43,13 @@ public class DistributedConfigDataStoreProviderModule extends
     }
 
     @Override
-    public java.lang.AutoCloseable createInstance() {
-        DatastoreContext datastoreContext = newDatastoreContext(getConfigProperties());
-
-        return DistributedDataStoreFactory.createInstance(getConfigSchemaServiceDependency(),
-                datastoreContext, DatastoreSnapshotRestore.instance(),
-                getConfigActorSystemProviderDependency(), bundleContext);
+    public AutoCloseable createInstance() {
+        // The DistributedConfigDataStore is provided via blueprint so wait for and return it here for
+        // backwards compatibility.
+        WaitingServiceTracker<DistributedDataStoreInterface> tracker = WaitingServiceTracker.create(
+                DistributedDataStoreInterface.class, bundleContext, "(type=distributed-config)");
+        DistributedDataStoreInterface delegate = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
+        return new ForwardingDistributedDataStore(delegate, tracker);
     }
 
     public static DatastoreContext newDatastoreContext() {
index 9bb6b82eee7b16cede1b60242b561e770d27000c..e7589e0d3621547bce0ee8fda1dd4e1280b18dcf 100644 (file)
@@ -9,8 +9,8 @@
 package org.opendaylight.controller.config.yang.config.distributed_datastore_provider;
 
 import org.opendaylight.controller.cluster.datastore.DatastoreContext;
-import org.opendaylight.controller.cluster.datastore.DatastoreSnapshotRestore;
-import org.opendaylight.controller.cluster.datastore.DistributedDataStoreFactory;
+import org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface;
+import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.osgi.framework.BundleContext;
 
@@ -44,11 +44,12 @@ public class DistributedOperationalDataStoreProviderModule extends
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        DatastoreContext datastoreContext = newDatastoreContext(getOperationalProperties());
-
-        return DistributedDataStoreFactory.createInstance(getOperationalSchemaServiceDependency(),
-                datastoreContext, DatastoreSnapshotRestore.instance(),
-                getOperationalActorSystemProviderDependency(), bundleContext);
+        // The DistributedOperDataStore is provided via blueprint so wait for and return it here for
+        // backwards compatibility
+        WaitingServiceTracker<DistributedDataStoreInterface> tracker = WaitingServiceTracker.create(
+                DistributedDataStoreInterface.class, bundleContext, "(type=distributed-operational)");
+        DistributedDataStoreInterface delegate = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
+        return new ForwardingDistributedDataStore(delegate, tracker);
     }
 
     public static DatastoreContext newDatastoreContext() {
diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/ForwardingDistributedDataStore.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/config/yang/config/distributed_datastore_provider/ForwardingDistributedDataStore.java
new file mode 100644 (file)
index 0000000..b04bf1b
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016 Brocade Communications 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.distributed_datastore_provider;
+
+import com.google.common.collect.ForwardingObject;
+import org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface;
+import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
+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.sal.core.spi.data.DOMStoreReadTransaction;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
+import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * DOMStore implementation that forwards to a delegate.
+ *
+ * @author Thomas Pantelis
+ */
+class ForwardingDistributedDataStore extends ForwardingObject implements DistributedDataStoreInterface, AutoCloseable {
+    private final DistributedDataStoreInterface delegate;
+    private final AutoCloseable closeable;
+
+    ForwardingDistributedDataStore(DistributedDataStoreInterface delegate, AutoCloseable closeable) {
+        this.delegate = delegate;
+        this.closeable = closeable;
+    }
+
+    @Override
+    public DOMStoreReadTransaction newReadOnlyTransaction() {
+        return delegate().newReadOnlyTransaction();
+    }
+
+    @Override
+    public DOMStoreWriteTransaction newWriteOnlyTransaction() {
+        return delegate().newWriteOnlyTransaction();
+    }
+
+    @Override
+    public DOMStoreReadWriteTransaction newReadWriteTransaction() {
+        return delegate().newReadWriteTransaction();
+    }
+
+    @Override
+    public <L extends AsyncDataChangeListener<YangInstanceIdentifier, NormalizedNode<?, ?>>> ListenerRegistration<L> registerChangeListener(
+            YangInstanceIdentifier path, L listener, DataChangeScope scope) {
+        return delegate().registerChangeListener(path, listener, scope);
+    }
+
+    @Override
+    public DOMStoreTransactionChain createTransactionChain() {
+        return delegate().createTransactionChain();
+    }
+
+    @Override
+    public ActorContext getActorContext() {
+        return delegate().getActorContext();
+    }
+
+    @Override
+    public void close() throws Exception {
+        closeable.close();
+    }
+
+    @Override
+    protected DistributedDataStoreInterface delegate() {
+        return delegate;
+    }
+}
index c0a45852cc6db2e9a60bab225b757cb06c3068d5..a7ea21f1ab31ab486d57650751ca565131add7d6 100644 (file)
@@ -8,19 +8,21 @@
 
 package org.opendaylight.controller.config.yang.config.distributed_entity_ownership_service;
 
-import com.google.common.base.Preconditions;
-import org.opendaylight.controller.cluster.datastore.DistributedDataStore;
-import org.opendaylight.controller.cluster.datastore.entityownership.DistributedEntityOwnershipService;
-import org.opendaylight.controller.cluster.datastore.entityownership.selectionstrategy.EntityOwnerSelectionStrategyConfig;
-import org.opendaylight.controller.cluster.datastore.entityownership.selectionstrategy.EntityOwnerSelectionStrategyConfigReader;
-import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
+import com.google.common.base.Optional;
+import com.google.common.collect.ForwardingObject;
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
-import org.opendaylight.controller.sal.core.spi.data.DOMStore;
+import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
+import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
+import org.opendaylight.controller.md.sal.common.api.clustering.Entity;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidateRegistration;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListenerRegistration;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
+import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipState;
 import org.osgi.framework.BundleContext;
 
 public class DistributedEntityOwnershipServiceProviderModule extends AbstractDistributedEntityOwnershipServiceProviderModule {
-    private EntityOwnerSelectionStrategyConfig strategyConfig;
     private BundleContext bundleContext;
 
     public DistributedEntityOwnershipServiceProviderModule(final ModuleIdentifier identifier,
@@ -36,7 +38,6 @@ public class DistributedEntityOwnershipServiceProviderModule extends AbstractDis
 
     @Override
     public void customValidation() {
-        strategyConfig = EntityOwnerSelectionStrategyConfigReader.loadStrategyWithConfig(bundleContext);
     }
 
     @Override
@@ -46,17 +47,59 @@ public class DistributedEntityOwnershipServiceProviderModule extends AbstractDis
 
     @Override
     public AutoCloseable createInstance() {
-        // FIXME: EntityOwnership needs only the ActorContext, not the entire datastore
-        DOMStore dataStore = getDataStoreDependency();
-        Preconditions.checkArgument(dataStore instanceof DistributedDataStore,
-                "Injected DOMStore must be an instance of DistributedDataStore");
-
-        final ActorContext context = ((DistributedDataStore)dataStore).getActorContext();
-        return DistributedEntityOwnershipService.start(context, strategyConfig);
+        // The DistributedEntityOwnershipService is provided via blueprint so wait for and return it here for
+        // backwards compatibility.
+        WaitingServiceTracker<EntityOwnershipService> tracker = WaitingServiceTracker.create(
+                EntityOwnershipService.class, bundleContext);
+        EntityOwnershipService delegate = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
+        return new ForwardingEntityOwnershipService(delegate, tracker);
     }
 
     public void setBundleContext(final BundleContext bundleContext) {
-        // What do we need from the bundle context?
         this.bundleContext = bundleContext;
     }
+
+    private static class ForwardingEntityOwnershipService extends ForwardingObject
+            implements EntityOwnershipService, AutoCloseable {
+        private final EntityOwnershipService delegate;
+        private final AutoCloseable closeable;
+
+        public ForwardingEntityOwnershipService(EntityOwnershipService delegate, AutoCloseable closeable) {
+            this.delegate = delegate;
+            this.closeable = closeable;
+        }
+
+        @Override
+        public EntityOwnershipCandidateRegistration registerCandidate(Entity entity)
+                throws CandidateAlreadyRegisteredException {
+            return delegate().registerCandidate(entity);
+        }
+
+        @Override
+        public EntityOwnershipListenerRegistration registerListener(String entityType,
+                EntityOwnershipListener listener) {
+            return delegate().registerListener(entityType, listener);
+        }
+
+        @Override
+        public Optional<EntityOwnershipState> getOwnershipState(Entity forEntity) {
+            return delegate().getOwnershipState(forEntity);
+        }
+
+        @Override
+        public boolean isCandidateRegistered(Entity entity) {
+            return delegate().isCandidateRegistered(entity);
+        }
+
+        @Override
+        protected EntityOwnershipService delegate() {
+            return delegate;
+        }
+
+        @Override
+        public void close() throws Exception {
+            // We don't close the delegate as the life-cycle is controlled via blueprint.
+            closeable.close();
+        }
+    }
 }
index ac0f02ffcc235454da5c5e06ea9789977ae9e2be..cd2ee2def20ee15c35af2a6fc8aaa17d554fd0bc 100644 (file)
     <argument ref="blueprintBundleContext"/>
   </bean>
 
+  <service ref="configDatastore" odl:type="distributed-config">
+    <interfaces>
+      <value>org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface</value>
+    </interfaces>
+  </service>
+
   <!-- Distributed Operational Datastore -->
 
   <bean id="operDatastoreContext" class="org.opendaylight.controller.config.yang.config.distributed_datastore_provider.DistributedOperationalDataStoreProviderModule"
     <argument ref="blueprintBundleContext"/>
   </bean>
 
+  <service ref="operDatastore" odl:type="distributed-operational">
+    <interfaces>
+      <value>org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface</value>
+    </interfaces>
+  </service>
+
   <!-- Concurrent DOMDataBroker -->
 
   <bean id="listenableFutureExecutor" class="org.opendaylight.yangtools.util.concurrent.SpecialExecutors"
@@ -64,7 +76,7 @@
   <bean id="commitStatsTracker" class="org.opendaylight.yangtools.util.DurationStatisticsTracker"
           factory-method="createConcurrent"/>
 
-  <bean id="clusteredDOMDataBroker" class="org.opendaylight.controller.cluster.datastore.ConcurrentDOMDataBroker"
+  <bean id="clusteredDOMDataBroker" class="org.opendaylight.controller.cluster.databroker.ConcurrentDOMDataBroker"
           destroy-method="close">
     <argument>
       <map>
 
   <service ref="distributedEntityOwnershipService" interface="org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService"
         odl:type="default"/>
-
 </blueprint>
\ No newline at end of file
index d40a3aafade4c024af7dbb91a26cbc9002b3ab98..8174c7786336417b9ae9a0c765721fb2fc655464 100644 (file)
@@ -242,7 +242,7 @@ module distributed-datastore-provider {
                 container config-schema-service {
                     uses config:service-ref {
                         refine type {
-                            mandatory true;
+                            mandatory false;
                             config:required-identity sal:schema-service;
                         }
                     }
@@ -251,7 +251,7 @@ module distributed-datastore-provider {
                 container config-actor-system-provider {
                     uses config:service-ref {
                         refine type {
-                            mandatory true;
+                            mandatory false;
                             config:required-identity actor-system:actor-system-provider-service;
                         }
                     }
@@ -270,7 +270,7 @@ module distributed-datastore-provider {
                 container operational-schema-service {
                     uses config:service-ref {
                         refine type {
-                            mandatory true;
+                            mandatory false;
                             config:required-identity sal:schema-service;
                         }
                     }
@@ -279,7 +279,7 @@ module distributed-datastore-provider {
                 container operational-actor-system-provider {
                     uses config:service-ref {
                         refine type {
-                            mandatory true;
+                            mandatory false;
                             config:required-identity actor-system:actor-system-provider-service;
                         }
                     }
index 61385ded68f70a9c331c0ddc5243ca0d9f0a84c1..895d3d2e29ea0eb6a45b64b1e32735938944765a 100644 (file)
@@ -10,23 +10,27 @@ package org.opendaylight.controller.config.yang.md.sal.dom.impl;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ClassToInstanceMap;
 import com.google.common.collect.MutableClassToInstanceMap;
-import java.util.concurrent.TimeUnit;
+import java.util.ArrayList;
+import java.util.List;
+import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcProviderService;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
-import org.opendaylight.controller.md.sal.dom.broker.impl.DOMNotificationRouter;
-import org.opendaylight.controller.md.sal.dom.broker.impl.DOMRpcRouter;
-import org.opendaylight.controller.md.sal.dom.broker.impl.mount.DOMMountPointServiceImpl;
 import org.opendaylight.controller.sal.core.api.BrokerService;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.dom.broker.BrokerImpl;
 import org.opendaylight.controller.sal.dom.broker.GlobalBundleScanningSchemaServiceImpl;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-public final class DomBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractDomBrokerImplModule
-{
+public final class DomBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractDomBrokerImplModule{
+    private static final Logger LOG = LoggerFactory.getLogger(DomBrokerImplModule.class);
+
+    private BundleContext bundleContext;
 
     public DomBrokerImplModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
@@ -45,28 +49,63 @@ public final class DomBrokerImplModule extends org.opendaylight.controller.confi
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        final DOMDataBroker asyncBroker= getAsyncDataBrokerDependency();
+        // The services are provided via blueprint so retrieve then from the OSGi service registry for
+        // backwards compatibility.
+
+        final List<AutoCloseable> closeables = new ArrayList<>();
+        DOMNotificationService domNotificationService = newTracker(
+                DOMNotificationService.class, closeables).waitForService(WaitingServiceTracker.FIVE_MINUTES);
+
+        DOMNotificationPublishService domNotificationPublishService = newTracker(
+                DOMNotificationPublishService.class, closeables).waitForService(WaitingServiceTracker.FIVE_MINUTES);
+
+        DOMRpcService domRpcService = newTracker(
+                DOMRpcService.class, closeables).waitForService(WaitingServiceTracker.FIVE_MINUTES);
+
+        DOMRpcProviderService domRpcProvider = newTracker(
+                DOMRpcProviderService.class, closeables).waitForService(WaitingServiceTracker.FIVE_MINUTES);
+
+        DOMMountPointService mountService = newTracker(DOMMountPointService.class, closeables).
+                waitForService(WaitingServiceTracker.FIVE_MINUTES);
+
+        final DOMDataBroker dataBroker = getAsyncDataBrokerDependency();
 
         final ClassToInstanceMap<BrokerService> services = MutableClassToInstanceMap.create();
 
-        final DOMNotificationRouter domNotificationRouter = DOMNotificationRouter.create(getNotificationQueueDepth().getValue().intValue(),
-            getNotificationQueueSpin().longValue(), getNotificationQueuePark().longValue(), TimeUnit.MILLISECONDS);
-        services.putInstance(DOMNotificationService.class, domNotificationRouter);
-        services.putInstance(DOMNotificationPublishService.class, domNotificationRouter);
+        services.putInstance(DOMNotificationService.class, domNotificationService);
+        services.putInstance(DOMNotificationPublishService.class, domNotificationPublishService);
 
         final SchemaService schemaService = getSchemaServiceImpl();
         services.putInstance(SchemaService.class, schemaService);
 
-        services.putInstance(DOMDataBroker.class, asyncBroker);
+        services.putInstance(DOMDataBroker.class, dataBroker);
 
-        final DOMRpcRouter rpcRouter = DOMRpcRouter.newInstance(schemaService);
-        services.putInstance(DOMRpcService.class, rpcRouter);
-        services.putInstance(DOMRpcProviderService.class, rpcRouter);
+        services.putInstance(DOMRpcService.class, domRpcService);
+        services.putInstance(DOMRpcProviderService.class, domRpcProvider);
 
-        final DOMMountPointService mountService = new DOMMountPointServiceImpl();
         services.putInstance(DOMMountPointService.class, mountService);
 
-        return new BrokerImpl(rpcRouter, services);
+        BrokerImpl broker = new BrokerImpl(domRpcService, domRpcProvider, services);
+        broker.setDeactivator(new AutoCloseable() {
+            @Override
+            public void close() {
+                for(AutoCloseable ac: closeables) {
+                    try {
+                        ac.close();
+                    } catch(Exception e) {
+                        LOG.warn("Exception while closing {}", ac, e);
+                    }
+                }
+            }
+        });
+
+        return broker;
+    }
+
+    private <T> WaitingServiceTracker<T> newTracker(Class<T> serviceInterface, List<AutoCloseable> closeables) {
+        WaitingServiceTracker<T> tracker = WaitingServiceTracker.create(serviceInterface, bundleContext);
+        closeables.add(tracker);
+        return tracker;
     }
 
     private SchemaService getSchemaServiceImpl() {
@@ -78,4 +117,8 @@ public final class DomBrokerImplModule extends org.opendaylight.controller.confi
         }
         return schemaService;
     }
+
+    public void setBundleContext(final BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
 }
index f1fcb495aace6a38ade530efa34b32eba817772f..52230180eb9a5b4d7d07a1b21d35b49977f28201 100644 (file)
@@ -7,11 +7,29 @@
  */
 package org.opendaylight.controller.config.yang.md.sal.dom.impl;
 
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
+import org.opendaylight.controller.config.spi.Module;
+import org.osgi.framework.BundleContext;
 
-/**
-*
-*/
 public class DomBrokerImplModuleFactory extends
         org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractDomBrokerImplModuleFactory {
 
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver,
+            BundleContext bundleContext) {
+        DomBrokerImplModule module = (DomBrokerImplModule)super.createModule(instanceName, dependencyResolver,
+                bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
+
+    @Override
+    public Module createModule(String instanceName, DependencyResolver dependencyResolver, DynamicMBeanWithInstance old,
+            BundleContext bundleContext) throws Exception {
+        DomBrokerImplModule module = (DomBrokerImplModule)super.createModule(instanceName, dependencyResolver,
+                old, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
 }
index 62b026430ac07756bb21d2a90095a4c73ce6229a..dae7f05cc66f513f0a0ca87abd2b6860c09a4c95 100644 (file)
@@ -7,13 +7,18 @@
  */
 package org.opendaylight.controller.config.yang.md.sal.dom.impl;
 
+import com.google.common.util.concurrent.CheckedFuture;
 import org.opendaylight.controller.sal.core.api.model.SchemaService;
+import org.opendaylight.controller.sal.core.api.model.YangTextSourceProvider;
 import org.opendaylight.controller.sal.dom.broker.GlobalBundleScanningSchemaServiceImpl;
 import org.opendaylight.yangtools.concepts.Delegator;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
+import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceException;
+import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
+import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -56,22 +61,20 @@ org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractSchemaServiceImp
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        return GlobalBundleScanningSchemaServiceImpl.getInstance();
+        return new GlobalSchemaServiceProxy(GlobalBundleScanningSchemaServiceImpl.getInstance());
     }
 
-    public class GlobalSchemaServiceProxy implements AutoCloseable, SchemaService, Delegator<SchemaService> {
+    private static class GlobalSchemaServiceProxy implements AutoCloseable, SchemaService, YangTextSourceProvider,
+            Delegator<SchemaService> {
+        private final GlobalBundleScanningSchemaServiceImpl delegate;
 
-        private SchemaService delegate;
-
-        public GlobalSchemaServiceProxy() {
-            this.delegate = GlobalBundleScanningSchemaServiceImpl.getInstance();
+        public GlobalSchemaServiceProxy(GlobalBundleScanningSchemaServiceImpl service) {
+            this.delegate = service;
         }
 
         @Override
-        public void close() throws Exception {
-            if (delegate != null) {
-                delegate = null;
-            }
+        public void close() {
+            // Intentional noop as the life-cycle is controlled via blueprint.
         }
 
         @Override
@@ -104,5 +107,10 @@ org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractSchemaServiceImp
             return delegate;
         }
 
+        @Override
+        public CheckedFuture<? extends YangTextSchemaSource, SchemaSourceException> getSource(
+                SourceIdentifier sourceIdentifier) {
+            return delegate.getSource(sourceIdentifier);
+        }
     }
 }
index 138de6b77068fc06ee9cd4e1dbe160a94f3a92fc..64c6b9e1fd1791a4e29e5868e64cf89975b9a2dd 100644 (file)
@@ -98,6 +98,8 @@ public final class DOMNotificationRouter implements AutoCloseable, DOMNotificati
     }
 
     public static DOMNotificationRouter create(final int queueDepth, final long spinTime, final long parkTime, final TimeUnit unit) {
+        Preconditions.checkArgument(Long.lowestOneBit(queueDepth) == Long.highestOneBit(queueDepth),
+                "Queue depth %s is not power-of-two", queueDepth);
         final ExecutorService executor = Executors.newCachedThreadPool();
         final WaitStrategy strategy = PhasedBackoffWaitStrategy.withLock(spinTime, parkTime, unit);
 
index 03fbb18cae31eefbb56d6c8db19e10cc44464bed..6cd0ebc5f838dbded2f16dac6fd5dc9eeee748a7 100644 (file)
@@ -46,17 +46,23 @@ public class BrokerImpl implements Broker, DOMRpcProviderService, DOMRpcService,
     private final Set<ProviderContextImpl> providerSessions = Collections
             .synchronizedSet(new HashSet<ProviderContextImpl>());
 
-    private AutoCloseable deactivator = null;
+    private AutoCloseable deactivator;
 
-    private DOMRpcRouter router = null;
+    private final DOMRpcService rpcService;
+    private final DOMRpcProviderService rpcProvider;
 
     private final ClassToInstanceMap<BrokerService> services;
 
-    public  BrokerImpl(final DOMRpcRouter router,final ClassToInstanceMap<BrokerService> services) {
-        this.router = Preconditions.checkNotNull(router, "RPC Router must not be null");
-        this.services = ImmutableClassToInstanceMap.copyOf(services);
+    public BrokerImpl(final DOMRpcRouter router,final ClassToInstanceMap<BrokerService> services) {
+        this(router, router, services);
     }
 
+    public BrokerImpl(final DOMRpcService rpcService, final DOMRpcProviderService rpcProvider,
+            final ClassToInstanceMap<BrokerService> services) {
+        this.rpcService = Preconditions.checkNotNull(rpcService, "DOMRpcService must not be null");
+        this.rpcProvider = Preconditions.checkNotNull(rpcProvider, "DOMRpcProviderService must not be null");
+        this.services = ImmutableClassToInstanceMap.copyOf(services);
+    }
 
     @Override
     public ConsumerSession registerConsumer(final Consumer consumer,
@@ -130,21 +136,6 @@ public class BrokerImpl implements Broker, DOMRpcProviderService, DOMRpcService,
         this.deactivator = deactivator;
     }
 
-    /**
-     * @return the router
-     */
-    public DOMRpcRouter getRouter() {
-        return router;
-    }
-
-    /**
-     * @param router
-     *            the router to set
-     */
-    public void setRouter(final DOMRpcRouter router) {
-        this.router = router;
-    }
-
     protected <T extends BrokerService> Optional<T> getGlobalService(final Class<T> service) {
         return Optional.fromNullable(services.getInstance(service));
     }
@@ -174,24 +165,24 @@ public class BrokerImpl implements Broker, DOMRpcProviderService, DOMRpcService,
     @Nonnull
     @Override
     public <T extends DOMRpcImplementation> DOMRpcImplementationRegistration<T> registerRpcImplementation(@Nonnull final T implementation, @Nonnull final DOMRpcIdentifier... rpcs) {
-        return router.registerRpcImplementation(implementation, rpcs);
+        return rpcProvider.registerRpcImplementation(implementation, rpcs);
     }
 
     @Nonnull
     @Override
     public <T extends DOMRpcImplementation> DOMRpcImplementationRegistration<T> registerRpcImplementation(@Nonnull final T implementation, @Nonnull final Set<DOMRpcIdentifier> rpcs) {
-        return router.registerRpcImplementation(implementation, rpcs);
+        return rpcProvider.registerRpcImplementation(implementation, rpcs);
     }
 
     @Nonnull
     @Override
     public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(@Nonnull final SchemaPath type, @Nullable final NormalizedNode<?, ?> input) {
-        return router.invokeRpc(type, input);
+        return rpcService.invokeRpc(type, input);
     }
 
     @Nonnull
     @Override
     public <T extends DOMRpcAvailabilityListener> ListenerRegistration<T> registerRpcListener(@Nonnull final T listener) {
-        return router.registerRpcListener(listener);
+        return rpcService.registerRpcListener(listener);
     }
 }
index 9a3ab181e07d8d012f15749f8ae6d6c8e25c464a..4d9c7df5ab1ab6bd83e3618689c1e75c088e40be 100644 (file)
@@ -14,9 +14,9 @@ module opendaylight-config-dom-datastore {
          }
 
      identity config-dom-datastore {
-             base "config:service-type";
-             config:java-class  "org.opendaylight.controller.sal.core.spi.data.DOMStore";
-
+         base "config:service-type";
+         config:java-class  "org.opendaylight.controller.sal.core.spi.data.DOMStore";
+         config:disable-osgi-service-registration;
      }
 
 }
\ No newline at end of file
index db62d04eaab05873c2e211b01b1bc1fa8129bee3..cf21279ff18ce285c4303f9d78cd6a8503f7342f 100644 (file)
@@ -21,15 +21,18 @@ module opendaylight-md-sal-dom {
     identity dom-async-data-broker {
         base "config:service-type";
         config:java-class "org.opendaylight.controller.md.sal.dom.api.DOMDataBroker";
+        config:disable-osgi-service-registration;
     }
 
     identity schema-service {
         base "config:service-type";
         config:java-class "org.opendaylight.controller.sal.core.api.model.SchemaService";
+        config:disable-osgi-service-registration;
     }
 
     identity yang-text-source-provider {
         base "config:service-type";
         config:java-class "org.opendaylight.controller.sal.core.api.model.YangTextSourceProvider";
+        config:disable-osgi-service-registration;
     }
 }
\ No newline at end of file
index fd408840bba80aca3502b2163594b1cb11540279..008010b7d4feb69ea39e18b1cb342203a2331613 100644 (file)
@@ -14,9 +14,9 @@ module opendaylight-operational-dom-datastore {
          }
 
      identity operational-dom-datastore {
-             base "config:service-type";
-             config:java-class  "org.opendaylight.controller.sal.core.spi.data.DOMStore";
-
+         base "config:service-type";
+         config:java-class  "org.opendaylight.controller.sal.core.spi.data.DOMStore";
+         config:disable-osgi-service-registration;
      }
 
 }
\ No newline at end of file
index 4ada10a88735d1ebc632d1cbd37208eedd474b81..e4631f965dbd0566a1baaa992a9ae65d779a2f72 100644 (file)
@@ -8,16 +8,9 @@
 
 package org.opendaylight.controller.config.yang.config.remote_rpc_connector;
 
-import akka.actor.ActorSystem;
-import org.opendaylight.controller.md.sal.dom.api.DOMRpcProviderService;
-import org.opendaylight.controller.remote.rpc.RemoteRpcProvider;
-import org.opendaylight.controller.remote.rpc.RemoteRpcProviderConfig;
-import org.opendaylight.controller.remote.rpc.RemoteRpcProviderFactory;
-import org.opendaylight.controller.sal.core.api.Broker;
-import org.osgi.framework.BundleContext;
+import org.opendaylight.controller.sal.common.util.NoopAutoCloseable;
 
 public class RemoteRPCBrokerModule extends org.opendaylight.controller.config.yang.config.remote_rpc_connector.AbstractRemoteRPCBrokerModule {
-    private BundleContext bundleContext;
     public RemoteRPCBrokerModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
     }
@@ -37,22 +30,9 @@ public class RemoteRPCBrokerModule extends org.opendaylight.controller.config.ya
     }
 
     @Override
-    public java.lang.AutoCloseable createInstance() {
-        Broker broker = getDomBrokerDependency();
-
-        ActorSystem actorSystem = getActorSystemProviderDependency().getActorSystem();
-        RemoteRpcProviderConfig config = new RemoteRpcProviderConfig.Builder(actorSystem.name())
-                .metricCaptureEnabled(getEnableMetricCapture())
-                .mailboxCapacity(getBoundedMailboxCapacity())
-                .build();
-
-        RemoteRpcProvider rpcProvider = RemoteRpcProviderFactory.createInstance((DOMRpcProviderService)broker,
-                actorSystem, config);
-        broker.registerProvider(rpcProvider);
-        return rpcProvider;
-    }
-
-    public void setBundleContext(BundleContext bundleContext) {
-        this.bundleContext = bundleContext;
+    public AutoCloseable createInstance() {
+        // The RemoteRpcProvider is created via blueprint and doesn't advertise any services so return a
+        // no-op here for backwards compatibility.
+        return NoopAutoCloseable.INSTANCE;
     }
 }
index 4d75ebb443596390da891c3216c90228b31e591e..dec35597fee5d31948a82218a4865e92b688fb36 100644 (file)
 */
 package org.opendaylight.controller.config.yang.config.remote_rpc_connector;
 
-
-import org.opendaylight.controller.config.api.DependencyResolver;
-import org.opendaylight.controller.config.api.DynamicMBeanWithInstance;
-import org.opendaylight.controller.config.spi.Module;
-import org.osgi.framework.BundleContext;
-
-public class RemoteRPCBrokerModuleFactory extends org.opendaylight.controller.config.yang.config.remote_rpc_connector.AbstractRemoteRPCBrokerModuleFactory {
-  @Override
-  public Module createModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
-    RemoteRPCBrokerModule module = (RemoteRPCBrokerModule)super.createModule(instanceName,dependencyResolver,bundleContext);
-    module.setBundleContext(bundleContext);
-    return module;
-  }
-
-  @Override
-  public Module createModule(String instanceName, DependencyResolver dependencyResolver,
-                             DynamicMBeanWithInstance old, BundleContext bundleContext) throws Exception {
-    RemoteRPCBrokerModule module = (RemoteRPCBrokerModule)super.createModule(instanceName, dependencyResolver,
-        old, bundleContext);
-    module.setBundleContext(bundleContext);
-    return module;
-  }
+public class RemoteRPCBrokerModuleFactory extends AbstractRemoteRPCBrokerModuleFactory {
 }
index 45b4afaa6e4954c7ed13fac6f24791e77b7dd90c..926054d3256944ead1b499587d919eea990f668e 100644 (file)
@@ -9,18 +9,7 @@
 package org.opendaylight.controller.config.yang.config.clustering_it_provider;
 
 
-import org.opendaylight.controller.clustering.it.listener.PeopleCarListener;
-import org.opendaylight.controller.clustering.it.provider.CarProvider;
-import org.opendaylight.controller.clustering.it.provider.PeopleProvider;
-import org.opendaylight.controller.clustering.it.provider.PurchaseCarProvider;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.sal.clustering.it.car.purchase.rev140818.CarPurchaseService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.sal.clustering.it.car.rev140818.CarService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.sal.clustering.it.people.rev140818.PeopleService;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.controller.sal.common.util.NoopAutoCloseable;
 
 public class ClusteringItProviderModule extends org.opendaylight.controller.config.yang.config.clustering_it_provider.AbstractClusteringItProviderModule {
     public ClusteringItProviderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
@@ -37,53 +26,8 @@ public class ClusteringItProviderModule extends org.opendaylight.controller.conf
     }
 
     @Override
-    public java.lang.AutoCloseable createInstance() {
-      DataBroker dataBrokerService = getDataBrokerDependency();
-      NotificationProviderService notificationProvider = getNotificationServiceDependency();
-
-      // Add routed RPC registration for car purchase
-      final PurchaseCarProvider purchaseCar = new PurchaseCarProvider();
-      purchaseCar.setNotificationProvider(notificationProvider);
-
-      final BindingAwareBroker.RoutedRpcRegistration<CarPurchaseService> purchaseCarRpc = getRpcRegistryDependency()
-          .addRoutedRpcImplementation(CarPurchaseService.class, purchaseCar);
-
-      // Add people provider registration
-      final PeopleProvider people = new PeopleProvider();
-      people.setDataProvider(dataBrokerService);
-
-      people.setRpcRegistration(purchaseCarRpc);
-
-      CarProvider carProvider = new CarProvider(dataBrokerService, getOwnershipServiceDependency());
-      getRpcRegistryDependency().addRpcImplementation(CarService.class, carProvider);
-
-      final BindingAwareBroker.RpcRegistration<PeopleService> peopleRpcReg = getRpcRegistryDependency()
-          .addRpcImplementation(PeopleService.class, people);
-
-
-
-      final PeopleCarListener peopleCarListener = new PeopleCarListener();
-      peopleCarListener.setDataProvider(dataBrokerService);
-
-      final ListenerRegistration<NotificationListener> listenerReg =
-          getNotificationServiceDependency().registerNotificationListener( peopleCarListener );
-
-      // Wrap toaster as AutoCloseable and close registrations to md-sal at
-      // close()
-      final class AutoCloseableToaster implements AutoCloseable {
-
-        @Override
-        public void close() throws Exception {
-          peopleRpcReg.close();
-          purchaseCarRpc.close();
-          people.close();
-          purchaseCar.close();
-          listenerReg.close();
-        }
-      }
-
-      AutoCloseable ret = new AutoCloseableToaster();
-      return ret;
+    public AutoCloseable createInstance() {
+        // The components are created and wired via blueprint so return an empty AutoCloseable.
+        return NoopAutoCloseable.INSTANCE;
     }
-
 }
index 75432769f22753445e7d16ccb59a11a0a87122c8..65fba77fb647553b26d4c10a0c80e4fe753d88a3 100644 (file)
 package org.opendaylight.controller.config.yang.config.kitchen_service.impl;
 
 import java.util.concurrent.Future;
-
+import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
 import org.opendaylight.controller.sample.kitchen.api.EggsType;
 import org.opendaylight.controller.sample.kitchen.api.KitchenService;
-import org.opendaylight.controller.sample.kitchen.impl.KitchenServiceImpl;
 import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToastType;
-import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterService;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.NotificationListener;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.osgi.framework.BundleContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,6 +33,8 @@ import org.slf4j.LoggerFactory;
 public final class KitchenServiceModule extends AbstractKitchenServiceModule {
     private static final Logger log = LoggerFactory.getLogger(KitchenServiceModule.class);
 
+    private BundleContext bundleContext;
+
     public KitchenServiceModule(final org.opendaylight.controller.config.api.ModuleIdentifier identifier, final org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
         super(identifier, dependencyResolver);
     }
@@ -53,36 +52,34 @@ public final class KitchenServiceModule extends AbstractKitchenServiceModule {
     }
 
     @Override
-    public java.lang.AutoCloseable createInstance() {
-        ToasterService toasterService = getRpcRegistryDependency().getRpcService(ToasterService.class);
-
-        final KitchenServiceImpl kitchenService = new KitchenServiceImpl(toasterService);
-
-        final ListenerRegistration<NotificationListener> toasterListenerReg =
-                getNotificationServiceDependency().registerNotificationListener( kitchenService );
-
-        final KitchenServiceRuntimeRegistration runtimeReg =
-                getRootRuntimeBeanRegistratorWrapper().register( kitchenService );
+    public AutoCloseable createInstance() {
+        // The KitchenServiceImpl instance is created and advertised with the OSGi registry via blueprint
+        // so obtain it here so we can return it to the config system. It's possible the blueprint container
+        // hasn't been created yet so we busy wait 5 min for the service.
+        final WaitingServiceTracker<KitchenService> tracker = WaitingServiceTracker.create(
+                KitchenService.class, bundleContext);
+        final KitchenService kitchenService = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
 
         final class AutoCloseableKitchenService implements KitchenService, AutoCloseable {
-
             @Override
-            public void close() throws Exception {
-                toasterListenerReg.close();
-                runtimeReg.close();
-                log.info("Toaster consumer (instance {}) torn down.", this);
+            public void close() {
+                // We need to close the ServiceTracker however we don't want to close the actual
+                // KitchenService instance because its life-cycle is controlled via blueprint.
+                tracker.close();
+                log.info("KitchenService (instance {}) closed.", kitchenService);
             }
 
             @Override
-            public Future<RpcResult<Void>> makeBreakfast( final EggsType eggs,
-                                                          final Class<? extends ToastType> toast,
-                                                          final int toastDoneness ) {
-                return kitchenService.makeBreakfast( eggs, toast, toastDoneness );
+            public Future<RpcResult<Void>> makeBreakfast(final EggsType eggs, final Class<? extends ToastType> toast,
+                    final int toastDoneness) {
+                return kitchenService.makeBreakfast(eggs, toast, toastDoneness);
             }
         }
 
-        AutoCloseable ret = new AutoCloseableKitchenService();
-        log.info("KitchenService (instance {}) initialized.", ret );
-        return ret;
+        return new AutoCloseableKitchenService();
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
     }
 }
index 4b02ceca29b99320118eb939fe7f2d4db77b8de2..e57bc187f2167f9f8769ff20575b7ad42b104953 100644 (file)
  */
 package org.opendaylight.controller.config.yang.config.kitchen_service.impl;
 
-/**
- *
- */
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.osgi.framework.BundleContext;
+
 public class KitchenServiceModuleFactory extends AbstractKitchenServiceModuleFactory {
+    @Override
+    public KitchenServiceModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+            KitchenServiceModule oldModule, AutoCloseable oldInstance, BundleContext bundleContext) {
+        KitchenServiceModule module = super.instantiateModule(instanceName, dependencyResolver, oldModule,
+                oldInstance, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
 
+    @Override
+    public KitchenServiceModule instantiateModule(String instanceName, DependencyResolver dependencyResolver,
+            BundleContext bundleContext) {
+        KitchenServiceModule module = super.instantiateModule(instanceName, dependencyResolver, bundleContext);
+        module.setBundleContext(bundleContext);
+        return module;
+    }
 }
index b255ad318f574e5bd18373b9384c75c7aee6c061..c115fc9114c06cadd224fed0df577faba9da1e65 100644 (file)
@@ -55,7 +55,7 @@ public class ToasterTest extends AbstractMdsalTestBase {
     @Test
     public void testToaster() throws Exception {
         MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();
-        ObjectName providerOn = new ObjectName("org.opendaylight.controller:instanceName=toaster-provider-impl,type=RuntimeBean,moduleFactoryName=toaster-provider-impl");
+        ObjectName providerOn = new ObjectName("org.opendaylight.controller:name=OpendaylightToaster,type=toaster-provider");
 
         long toastsMade = (long) platformMBeanServer.getAttribute(providerOn, "ToastsMade");
         assertEquals(0, toastsMade);
index 47c5692564c056c509d63a045d5c7dc1781cbbd0..73438eb878a8239892c1bbc5c7913a56b3d08fd8 100644 (file)
 */
 package org.opendaylight.controller.config.yang.config.toaster_provider.impl;
 
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.controller.sample.toaster.provider.OpendaylightToaster;
-import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterService;
+import org.opendaylight.controller.sal.common.util.NoopAutoCloseable;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -52,44 +49,8 @@ public final class ToasterProviderModule extends
 
     @Override
     public java.lang.AutoCloseable createInstance() {
-        final OpendaylightToaster opendaylightToaster = new OpendaylightToaster();
-
-        // Register to md-sal
-        opendaylightToaster.setNotificationProvider(getNotificationServiceDependency());
-
-        DataBroker dataBrokerService = getDataBrokerDependency();
-        opendaylightToaster.setDataProvider(dataBrokerService);
-
-        final BindingAwareBroker.RpcRegistration<ToasterService> rpcRegistration = getRpcRegistryDependency()
-                .addRpcImplementation(ToasterService.class, opendaylightToaster);
-
-        // Register runtimeBean for toaster statistics via JMX
-        final ToasterProviderRuntimeRegistration runtimeReg = getRootRuntimeBeanRegistratorWrapper().register(
-                opendaylightToaster);
-
-        // Wrap toaster as AutoCloseable and close registrations to md-sal at
-        // close()
-        final class AutoCloseableToaster implements AutoCloseable {
-
-            @Override
-            public void close() throws Exception {
-                rpcRegistration.close();
-                runtimeReg.close();
-                closeQuietly(opendaylightToaster);
-                log.info("Toaster provider (instance {}) torn down.", this);
-            }
-
-            private void closeQuietly(final AutoCloseable resource) {
-                try {
-                    resource.close();
-                } catch (final Exception e) {
-                    log.debug("Ignoring exception while closing {}", resource, e);
-                }
-            }
-        }
-
-        AutoCloseable ret = new AutoCloseableToaster();
-        log.info("Toaster provider (instance {}) initialized.", ret);
-        return ret;
+        // The components are created and wired via blueprint and, since this module doesn't advertise any
+        // services, return an empty AutoCloseable. The config module is kept for backwards compatibility.
+        return NoopAutoCloseable.INSTANCE;
     }
 }