X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsamples%2Ftoaster-consumer%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsample%2Fkitchen%2Fimpl%2FKitchenServiceImpl.java;h=306efc5e63dd613b335f935ca168f4bd8a1fd0fa;hb=HEAD;hp=c6aa545935af5e2ae9771343706ac24a0518a363;hpb=11e9ade9af527aba7faeb633d3c9c7552fd09d2d;p=controller.git diff --git a/opendaylight/md-sal/samples/toaster-consumer/src/main/java/org/opendaylight/controller/sample/kitchen/impl/KitchenServiceImpl.java b/opendaylight/md-sal/samples/toaster-consumer/src/main/java/org/opendaylight/controller/sample/kitchen/impl/KitchenServiceImpl.java index c6aa545935..b67de11367 100644 --- a/opendaylight/md-sal/samples/toaster-consumer/src/main/java/org/opendaylight/controller/sample/kitchen/impl/KitchenServiceImpl.java +++ b/opendaylight/md-sal/samples/toaster-consumer/src/main/java/org/opendaylight/controller/sample/kitchen/impl/KitchenServiceImpl.java @@ -1,166 +1,161 @@ +/* + * Copyright (c) 2014, 2015 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.sample.kitchen.impl; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.MoreExecutors; import java.util.List; -import java.util.concurrent.Callable; +import java.util.Set; import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -import org.opendaylight.controller.config.yang.config.kitchen_service.impl.KitchenServiceRuntimeMXBean; +import javax.annotation.PreDestroy; +import javax.inject.Inject; +import javax.inject.Singleton; +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.controller.sample.kitchen.api.KitchenServiceRuntimeMXBean; +import org.opendaylight.mdsal.binding.api.NotificationService; +import org.opendaylight.mdsal.binding.api.NotificationService.CompositeListener; +import org.opendaylight.mdsal.binding.api.RpcService; +import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToast; import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToastInputBuilder; +import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToastOutput; +import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToastOutputBuilder; 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.ToasterListener; import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.ToasterOutOfBread; 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.ToasterService; import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.WheatBread; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.common.ErrorTag; +import org.opendaylight.yangtools.yang.common.ErrorType; 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.RpcResultBuilder; +import org.opendaylight.yangtools.yang.common.Uint32; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; 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 { - - private static final Logger log = LoggerFactory.getLogger( KitchenServiceImpl.class ); +@Singleton +@Component(service = KitchenService.class, immediate = true) +public final class KitchenServiceImpl extends AbstractMXBean implements KitchenService, KitchenServiceRuntimeMXBean { + private static final Logger LOG = LoggerFactory.getLogger(KitchenServiceImpl.class); + private static final MakeToastOutput EMPTY_MAKE_OUTPUT = new MakeToastOutputBuilder().build(); - private final ToasterService toaster; - - private final ListeningExecutorService executor = - MoreExecutors.listeningDecorator( Executors.newCachedThreadPool() ); + private final ExecutorService executor = Executors.newCachedThreadPool(); + private final MakeToast makeToast; + private final Registration reg; private volatile boolean toasterOutOfBread; - public KitchenServiceImpl(ToasterService toaster) { - this.toaster = toaster; + @Inject + @Activate + public KitchenServiceImpl(@Reference final RpcService rpcService, + @Reference final NotificationService notifService) { + super("KitchenService", "toaster-consumer", null); + makeToast = rpcService.getRpc(MakeToast.class); + reg = notifService.registerCompositeListener(new CompositeListener(Set.of( + new CompositeListener.Component<>(ToasterOutOfBread.class, notification -> { + LOG.info("ToasterOutOfBread notification"); + toasterOutOfBread = true; + }), + new CompositeListener.Component<>(ToasterRestocked.class, notification -> { + LOG.info("ToasterRestocked notification - amountOfBread: {}", notification.getAmountOfBread()); + toasterOutOfBread = false; + })))); + register(); } - @Override - public Future> makeBreakfast( EggsType eggsType, Class toastType, - int toastDoneness ) { + @PreDestroy + @Deactivate + public void close() { + unregister(); + reg.close(); + } - // Call makeToast and use JdkFutureAdapters to convert the Future to a ListenableFuture, - // The OpendaylightToaster impl already returns a ListenableFuture so the conversion is + @Override + public ListenableFuture> makeBreakfast(final EggsType eggsType, final ToastType toastType, + final int toastDoneness) { + // Call makeToast, The OpendaylightToaster impl already returns a ListenableFuture so the conversion is // actually a no-op. - ListenableFuture> makeToastFuture = JdkFutureAdapters.listenInPoolThread( - makeToast( toastType, toastDoneness ), executor ); + ListenableFuture> makeToastFuture = makeToast(toastType, toastDoneness); - ListenableFuture> makeEggsFuture = makeEggs( eggsType ); + ListenableFuture> makeEggsFuture = makeEggs(eggsType); - // Combine the 2 ListenableFutures into 1 containing a list of RpcResults. + // Combine the 2 ListenableFutures into 1 containing a list RpcResults. - ListenableFuture>> combinedFutures = - Futures.allAsList( ImmutableList.of( makeToastFuture, makeEggsFuture ) ); + ListenableFuture>> combinedFutures = Futures + .allAsList(ImmutableList.of(makeToastFuture, makeEggsFuture)); // Then transform the RpcResults into 1. - return Futures.transform( combinedFutures, - new AsyncFunction>,RpcResult>() { - @Override - public ListenableFuture> apply( List> results ) - throws Exception { - boolean atLeastOneSucceeded = false; - Builder errorList = ImmutableList.builder(); - for( RpcResult result: results ) { - if( result.isSuccessful() ) { - atLeastOneSucceeded = true; - } - - if( result.getErrors() != null ) { - errorList.addAll( result.getErrors() ); - } - } - - return Futures.immediateFuture( - RpcResultBuilder. status( atLeastOneSucceeded ) - .withRpcErrors( errorList.build() ).build() ); + return Futures.transformAsync(combinedFutures, results -> { + boolean atLeastOneSucceeded = false; + Builder errorList = ImmutableList.builder(); + for (RpcResult result : results) { + if (result.isSuccessful()) { + atLeastOneSucceeded = true; } - } ); - } - - private ListenableFuture> makeEggs( EggsType eggsType ) { - - return executor.submit( new Callable>() { - - @Override - public RpcResult call() throws Exception { - // We don't actually do anything here - just return a successful result. - return RpcResultBuilder. success().build(); + if (result.getErrors() != null) { + errorList.addAll(result.getErrors()); + } } - } ); + + return RpcResultBuilder.status(atLeastOneSucceeded).withRpcErrors(errorList.build()).buildFuture(); + }, MoreExecutors.directExecutor()); } - private Future> makeToast( Class toastType, - int toastDoneness ) { + private ListenableFuture> makeEggs(final EggsType eggsType) { + return Futures.submit(() -> RpcResultBuilder.success().build(), executor); + } - if( toasterOutOfBread ) - { - log.info( "We're out of toast but we can make eggs" ); - return Futures.immediateFuture( RpcResultBuilder. success() - .withWarning( ErrorType.APPLICATION, "partial-operation", - "Toaster is out of bread but we can make you eggs" ).build() ); + private ListenableFuture> makeToast(final ToastType toastType, final int toastDoneness) { + if (toasterOutOfBread) { + LOG.info("We're out of toast but we can make eggs"); + return RpcResultBuilder.success(EMPTY_MAKE_OUTPUT) + .withWarning(ErrorType.APPLICATION, ErrorTag.PARTIAL_OPERATION, + "Toaster is out of bread but we can make you eggs") + .buildFuture(); } // Access the ToasterService to make the toast. - - MakeToastInput toastInput = new MakeToastInputBuilder() - .setToasterDoneness( (long) toastDoneness ) - .setToasterToastType( toastType ) - .build(); - - return toaster.makeToast( toastInput ); + return makeToast.invoke(new MakeToastInputBuilder() + .setToasterDoneness(Uint32.valueOf(toastDoneness)) + .setToasterToastType(toastType) + .build()); } @Override public Boolean makeScrambledWithWheat() { try { // This call has to block since we must return a result to the JMX client. - RpcResult result = makeBreakfast( EggsType.SCRAMBLED, WheatBread.class, 2 ).get(); - if( result.isSuccessful() ) { - log.info( "makeBreakfast succeeded" ); + RpcResult result = makeBreakfast(EggsType.SCRAMBLED, WheatBread.VALUE, 2).get(); + if (result.isSuccessful()) { + LOG.info("makeBreakfast succeeded"); } else { - log.warn( "makeBreakfast failed: " + result.getErrors() ); + LOG.warn("makeBreakfast failed: {}", result.getErrors()); } return result.isSuccessful(); - - } catch( InterruptedException | ExecutionException e ) { - log.warn( "An error occurred while maing breakfast: " + e ); + } catch (InterruptedException | ExecutionException e) { + LOG.warn("An error occurred while maing breakfast", e); } return Boolean.FALSE; } - - /** - * Implemented from the ToasterListener interface. - */ - @Override - public void onToasterOutOfBread( ToasterOutOfBread notification ) { - log.info( "ToasterOutOfBread notification" ); - toasterOutOfBread = true; - } - - /** - * Implemented from the ToasterListener interface. - */ - @Override - public void onToasterRestocked( ToasterRestocked notification ) { - log.info( "ToasterRestocked notification - amountOfBread: " + notification.getAmountOfBread() ); - toasterOutOfBread = false; - } }