</data-broker>
<notification-service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- binding:binding-notification-service
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+ binding:binding-new-notification-publish-service
</type>
- <name>binding-notification-broker</name>
+ <name>binding-notification-publish-adapter</name>
</notification-service>
</module>
</rpc-registry>
<notification-service>
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">
- binding:binding-notification-service
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">
+ binding:binding-new-notification-service
</type>
- <name>binding-notification-broker</name>
+ <name>binding-notification-adapter</name>
</notification-service>
</module>
</modules>
package org.opendaylight.controller.sample.kitchen.impl;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableList.Builder;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.JdkFutureAdapters;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
-
import org.opendaylight.controller.config.yang.config.kitchen_service.impl.KitchenServiceRuntimeMXBean;
+import org.opendaylight.controller.md.sal.common.util.jmx.AbstractMXBean;
import org.opendaylight.controller.sample.kitchen.api.EggsType;
import org.opendaylight.controller.sample.kitchen.api.KitchenService;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToastInput;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterService;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.WheatBread;
import org.opendaylight.yangtools.yang.common.RpcError;
-import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableList.Builder;
-import com.google.common.util.concurrent.AsyncFunction;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.JdkFutureAdapters;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-
-public class KitchenServiceImpl implements KitchenService, KitchenServiceRuntimeMXBean, ToasterListener {
+public class KitchenServiceImpl extends AbstractMXBean
+ implements KitchenService, KitchenServiceRuntimeMXBean, ToasterListener {
private static final Logger log = LoggerFactory.getLogger( KitchenServiceImpl.class );
private volatile boolean toasterOutOfBread;
public KitchenServiceImpl(ToasterService toaster) {
+ super("KitchenService", "toaster-consumer", null);
this.toaster = toaster;
}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+ odl:use-default-for-reference-types="true">
+
+ <!-- Retrieves the RPC service for the ToasterService interface -->
+ <odl:rpc-service id="toasterService" interface="org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterService"/>
+
+ <!-- Create the KitchenServiceImpl instance and inject the RPC service identified by "toasterService" -->
+ <bean id="kitchenService" class="org.opendaylight.controller.sample.kitchen.impl.KitchenServiceImpl"
+ init-method="register" destroy-method="unregister">
+ <argument ref="toasterService"/>
+ </bean>
+
+ <!-- Register the KitchenServiceImpl to receive yang notifications -->
+ <odl:notification-listener ref="kitchenService"/>
+
+ <!-- Advertise the KitchenServiceImpl with the OSGi registry with the type property set to "default" . The
+ type property is optional but can be used to distinguish this implementation from any other potential
+ KitchenService implementations (if there were any). Clients consuming the KitchenService can pick the
+ desired implementation via the particular type.
+ -->
+ <service ref="kitchenService" interface="org.opendaylight.controller.sample.kitchen.api.KitchenService"
+ odl:type="default"/>
+</blueprint>
\ No newline at end of file
import rpc-context { prefix rpcx; revision-date 2013-06-17; }
import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
+ import opendaylight-sal-binding-broker-impl { prefix binding-impl; revision-date 2013-10-28; }
description
"This module contains the base YANG definitions for
uses config:service-ref {
refine type {
mandatory true;
- config:required-identity mdsal:binding-notification-service;
+ config:required-identity binding-impl:binding-new-notification-service;
}
}
}
package org.opendaylight.controller.config.yang.config.toaster_provider.impl;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
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.Toaster;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterService;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
DataBroker dataBrokerService = getDataBrokerDependency();
opendaylightToaster.setDataProvider(dataBrokerService);
- final ListenerRegistration<OpendaylightToaster> dataTreeChangeListenerRegistration = dataBrokerService
- .registerDataTreeChangeListener(new DataTreeIdentifier<Toaster>(LogicalDatastoreType.CONFIGURATION,
- OpendaylightToaster.TOASTER_IID), opendaylightToaster);
-
final BindingAwareBroker.RpcRegistration<ToasterService> rpcRegistration = getRpcRegistryDependency()
.addRpcImplementation(ToasterService.class, opendaylightToaster);
@Override
public void close() throws Exception {
- dataTreeChangeListenerRegistration.close();
rpcRegistration.close();
runtimeReg.close();
closeQuietly(opendaylightToaster);
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.OptimisticLockFailedException;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.controller.md.sal.common.util.jmx.AbstractMXBean;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.DisplayString;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToastInput;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.RestockToasterInput;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterRestocked;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterRestockedBuilder;
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.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class OpendaylightToaster implements ToasterService, ToasterProviderRuntimeMXBean,
+public class OpendaylightToaster extends AbstractMXBean implements ToasterService, ToasterProviderRuntimeMXBean,
DataTreeChangeListener<Toaster>, AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(OpendaylightToaster.class);
private static final DisplayString TOASTER_MANUFACTURER = new DisplayString("Opendaylight");
private static final DisplayString TOASTER_MODEL_NUMBER = new DisplayString("Model 1 - Binding Aware");
- private NotificationProviderService notificationProvider;
+ private NotificationPublishService notificationProvider;
private DataBroker dataProvider;
+ private ListenerRegistration<OpendaylightToaster> dataTreeChangeListenerRegistration;
private final ExecutorService executor;
private final AtomicLong darknessFactor = new AtomicLong( 1000 );
public OpendaylightToaster() {
+ super("OpendaylightToaster", "toaster-provider", null);
executor = Executors.newFixedThreadPool(1);
}
- public void setNotificationProvider(final NotificationProviderService salService) {
- this.notificationProvider = salService;
+ public void setNotificationProvider(final NotificationPublishService notificationPublishService) {
+ this.notificationProvider = notificationPublishService;
}
public void setDataProvider(final DataBroker salDataProvider) {
this.dataProvider = salDataProvider;
+
+ dataProvider.registerDataTreeChangeListener(new DataTreeIdentifier<Toaster>(
+ LogicalDatastoreType.CONFIGURATION, OpendaylightToaster.TOASTER_IID), this);
+
setToasterStatusUp( null );
}
executor.shutdown();
if (dataProvider != null) {
+ dataTreeChangeListenerRegistration.close();
+
WriteTransaction tx = dataProvider.newWriteOnlyTransaction();
tx.delete(LogicalDatastoreType.OPERATIONAL,TOASTER_IID);
Futures.addCallback( tx.submit(), new FutureCallback<Void>() {
if( amountOfBreadInStock.get() > 0 ) {
ToasterRestocked reStockedNotification = new ToasterRestockedBuilder()
.setAmountOfBread( input.getAmountOfBreadToStock() ).build();
- notificationProvider.publish( reStockedNotification );
+ notificationProvider.offerNotification( reStockedNotification );
}
return Futures.immediateFuture( RpcResultBuilder.<Void> success().build() );
if( outOfBread() ) {
LOG.info( "Toaster is out of bread!" );
- notificationProvider.publish( new ToasterOutOfBreadBuilder().build() );
+ notificationProvider.offerNotification( new ToasterOutOfBreadBuilder().build() );
}
// Set the Toaster status back to up - this essentially releases the toasting lock.
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
+ xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.1.0"
+ odl:restart-dependents-on-updates="true" odl:use-default-for-reference-types="true">
+
+ <!-- "restart-dependents-on-updates" is an ODL extension attribute that processes any "property-placeholder"
+ elements and reacts to updates to the corresponding cfg file by restarting this blueprint container any
+ dependent containers that consume OSGi services provided by this container in an atomic and orderly
+ manner.
+
+ "use-default-for-reference-types" is an ODL extension attribute that adds a filter to all services
+ imported via "reference" elements where the "type" property is either not set or set to "default" if
+ the odl:type attribute isn't explicitly specified. This ensures the default implementation is imported
+ if there are other implementations advertised with other types.
+ -->
+
+ <!-- Accesses properties via the etc/org.opendaylight.toaster.cfg file. The properties are made available
+ as variables that can be referenced. The variables are substituted with the actual values read from
+ the cfg file, if present, or the default-properties.
+ -->
+ <cm:property-placeholder persistent-id="org.opendaylight.toaster" update-strategy="none">
+ <cm:default-properties>
+ <cm:property name="databroker-type" value="default"/>
+ </cm:default-properties>
+ </cm:property-placeholder>
+
+ <!-- Import MD-SAL services. For the DataBroker, we explicitly specify the odl:type which is configurable
+ via the cfg file. In this manner the toaster can be configured to use the default clustered DataBroker
+ or the specialized "pingpong" DataBroker (or any other DataBroker implementation).
+ -->
+ <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker" odl:type="${databroker-type}" />
+ <reference id="notificationService" interface="org.opendaylight.controller.md.sal.binding.api.NotificationPublishService"/>
+
+ <!-- Create the OpendaylightToaster instance and inject its dependencies -->
+ <bean id="toaster" class="org.opendaylight.controller.sample.toaster.provider.OpendaylightToaster"
+ init-method="register" destroy-method="unregister">
+ <property name="dataProvider" ref="dataBroker"/>
+ <property name="notificationProvider" ref="notificationService"/>
+ </bean>
+
+ <!-- Register the OpendaylightToaster instance as an RPC implementation provider. The "rpc-implementation"
+ element automatically figures out the RpcService interface although it can be explicitly specified.
+ -->
+ <odl:rpc-implementation ref="toaster"/>
+</blueprint>
\ No newline at end of file
import config { prefix config; revision-date 2013-04-05; }
import rpc-context { prefix rpcx; revision-date 2013-06-17; }
import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
+ import opendaylight-sal-binding-broker-impl { prefix binding-impl; revision-date 2013-10-28; }
description
"This module contains the base YANG definitions for
uses config:service-ref {
refine type {
mandatory true;
- config:required-identity mdsal:binding-notification-service;
+ config:required-identity binding-impl:binding-new-notification-publish-service;
}
}
}
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
-
+import com.google.common.base.Optional;
import java.util.concurrent.Future;
-
import org.junit.Ignore;
import org.junit.Test;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.DisplayString;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToastInput;
import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToastInputBuilder;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
-import com.google.common.base.Optional;
-
public class OpenDaylightToasterTest extends AbstractDataBrokerTest{
private static InstanceIdentifier<Toaster> TOASTER_IID =
* Doesn't look like we have support for the NotificationProviderService yet, so mock it
* for now.
*/
- NotificationProviderService mockNotification = mock( NotificationProviderService.class );
+ NotificationPublishService mockNotification = mock( NotificationPublishService.class );
toaster.setNotificationProvider( mockNotification );
}