*/
package org.opendaylight.controller.sample.toaster.provider;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+import java.util.Collection;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
-
import org.opendaylight.controller.config.yang.config.toaster_provider.impl.ToasterProviderRuntimeMXBean;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
+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.AsyncDataChangeEvent;
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.yang.binding.DataObject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.toaster.app.config.rev160503.ToasterAppConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.toaster.app.config.rev160503.ToasterAppConfigBuilder;
+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.RpcResultBuilder;
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.base.Function;
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.AsyncFunction;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-
-public class OpendaylightToaster implements ToasterService, ToasterProviderRuntimeMXBean,
- DataChangeListener, AutoCloseable {
+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;
// Thread safe holder for our darkness multiplier.
private final AtomicLong darknessFactor = new AtomicLong( 1000 );
+ private final ToasterAppConfig toasterAppConfig;
+
public OpendaylightToaster() {
+ this(new ToasterAppConfigBuilder().setManufacturer(TOASTER_MANUFACTURER).setModelNumber(TOASTER_MODEL_NUMBER).
+ setMaxMakeToastTries(2).build());
+ }
+
+ public OpendaylightToaster(ToasterAppConfig toasterAppConfig) {
+ super("OpendaylightToaster", "toaster-provider", null);
executor = Executors.newFixedThreadPool(1);
+ this.toasterAppConfig = toasterAppConfig;
}
- 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>() {
// note - we are simulating a device whose manufacture and model are
// fixed (embedded) into the hardware.
// This is why the manufacture and model number are hardcoded.
- return new ToasterBuilder().setToasterManufacturer( TOASTER_MANUFACTURER )
- .setToasterModelNumber( TOASTER_MODEL_NUMBER )
+ return new ToasterBuilder().setToasterManufacturer( toasterAppConfig.getManufacturer() )
+ .setToasterModelNumber( toasterAppConfig.getModelNumber() )
.setToasterStatus( status )
.build();
}
/**
- * Implemented from the DataChangeListener interface.
+ * Implemented from the DataTreeChangeListener interface.
*/
@Override
- public void onDataChanged( final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change ) {
- DataObject dataObject = change.getUpdatedSubtree();
- if( dataObject instanceof Toaster )
- {
- Toaster toaster = (Toaster) dataObject;
- Long darkness = toaster.getDarknessFactor();
- if( darkness != null )
- {
- darknessFactor.set( darkness );
+ public void onDataTreeChanged(Collection<DataTreeModification<Toaster>> changes) {
+ for(DataTreeModification<Toaster> change: changes) {
+ DataObjectModification<Toaster> rootNode = change.getRootNode();
+ if(rootNode.getModificationType() == DataObjectModification.ModificationType.WRITE) {
+ Toaster oldToaster = rootNode.getDataBefore();
+ Toaster newToaster = rootNode.getDataAfter();
+ LOG.info("onDataTreeChanged - Toaster config with path {} was added or replaced: old Toaster: {}, new Toaster: {}",
+ change.getRootPath().getRootIdentifier(), oldToaster, newToaster);
+
+ Long darkness = newToaster.getDarknessFactor();
+ if(darkness != null) {
+ darknessFactor.set(darkness);
+ }
+ } else if(rootNode.getModificationType() == DataObjectModification.ModificationType.DELETE) {
+ LOG.info("onDataTreeChanged - Toaster config with path {} was deleted: old Toaster: {}",
+ change.getRootPath().getRootIdentifier(), rootNode.getDataBefore());
}
}
}
final SettableFuture<RpcResult<Void>> futureResult = SettableFuture.create();
- checkStatusAndMakeToast( input, futureResult, 2 );
+ checkStatusAndMakeToast( input, futureResult, toasterAppConfig.getMaxMakeToastTries() );
return futureResult;
}
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.