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=4f245685aa6318f9a477b2ea576222b655142117;hb=refs%2Fchanges%2F27%2F100827%2F7;hp=911a8c87d7166edc38c7faa2597678c8f55c611a;hpb=478ce1fa1dc30974b7cf23fd5258f1af5366d547;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 911a8c87d7..4f245685aa 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,75 +1,141 @@ +/* + * 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.ListeningExecutorService; +import com.google.common.util.concurrent.MoreExecutors; +import java.util.List; import java.util.concurrent.ExecutionException; - -import org.opendaylight.controller.config.yang.config.kitchen_service.impl.KitchenServiceRuntimeMXBean; +import java.util.concurrent.Executors; +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.controller.sample.kitchen.api.KitchenServiceRuntimeMXBean; +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.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.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.RpcResultBuilder; +import org.opendaylight.yangtools.yang.common.Uint32; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -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 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 volatile boolean toasterOutOfBread; - public KitchenServiceImpl(ToasterService toaster) { + public KitchenServiceImpl(final ToasterService toaster) { + super("KitchenService", "toaster-consumer", null); this.toaster = toaster; } @Override - public boolean makeBreakfast( EggsType eggs, Class toast, int toastDoneness ) { + 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 = makeToast(toastType, toastDoneness); + + ListenableFuture> makeEggsFuture = makeEggs(eggsType); + + // Combine the 2 ListenableFutures into 1 containing a list RpcResults. + + ListenableFuture>> combinedFutures = Futures + .allAsList(ImmutableList.of(makeToastFuture, makeEggsFuture)); + + // Then transform the RpcResults into 1. + + return Futures.transformAsync(combinedFutures, results -> { + 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 RpcResultBuilder.status(atLeastOneSucceeded).withRpcErrors(errorList.build()).buildFuture(); + }, MoreExecutors.directExecutor()); + } - if( toasterOutOfBread ) - { - log.info( "We're out of toast but we can make eggs" ); - return true; + private ListenableFuture> makeEggs(final EggsType eggsType) { + return executor.submit(() -> RpcResultBuilder.success().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. - // We don't actually make the eggs for this example - sorry. - MakeToastInputBuilder toastInput = new MakeToastInputBuilder(); - toastInput.setToasterDoneness( (long) toastDoneness); - toastInput.setToasterToastType( toast ); - try { - RpcResult result = toaster.makeToast( toastInput.build() ).get(); + MakeToastInput toastInput = new MakeToastInputBuilder().setToasterDoneness(Uint32.valueOf(toastDoneness)) + .setToasterToastType(toastType).build(); - if( result.isSuccessful() ) { - log.info( "makeToast succeeded" ); + return toaster.makeToast(toastInput); + } + + @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.VALUE, 2).get(); + if (result.isSuccessful()) { + LOG.info("makeBreakfast succeeded"); } else { - log.warn( "makeToast failed: " + result.getErrors() ); + LOG.warn("makeBreakfast failed: {}", result.getErrors()); } return result.isSuccessful(); - } catch( InterruptedException | ExecutionException e ) { - log.warn( "Error occurred during toast creation" ); + } catch (InterruptedException | ExecutionException e) { + LOG.warn("An error occurred while maing breakfast", e); } - return false; - } - @Override - public Boolean makeScrambledWithWheat() { - return makeBreakfast( EggsType.SCRAMBLED, WheatBread.class, 2 ); + return Boolean.FALSE; } /** * Implemented from the ToasterListener interface. */ @Override - public void onToasterOutOfBread( ToasterOutOfBread notification ) { - log.info( "ToasterOutOfBread notification" ); + public void onToasterOutOfBread(final ToasterOutOfBread notification) { + LOG.info("ToasterOutOfBread notification"); toasterOutOfBread = true; } @@ -77,8 +143,8 @@ public class KitchenServiceImpl implements KitchenService, KitchenServiceRuntime * Implemented from the ToasterListener interface. */ @Override - public void onToasterRestocked( ToasterRestocked notification ) { - log.info( "ToasterRestocked notification - amountOfBread: " + notification.getAmountOfBread() ); + public void onToasterRestocked(final ToasterRestocked notification) { + LOG.info("ToasterRestocked notification - amountOfBread: {}", notification.getAmountOfBread()); toasterOutOfBread = false; } }