X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsamples%2Ftoaster-provider%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsample%2Ftoaster%2Fprovider%2FOpendaylightToaster.java;h=b7518e094d0e61594a391c2fc4a78b181294e00a;hp=d2b0f90194a9a066558f6d4dca5d1d8751ec01aa;hb=17d82f582a6bc13c78be3b19954ff8c021180e93;hpb=c1362c86eb19e92e6c64d10099a45deb499c6db1 diff --git a/opendaylight/md-sal/samples/toaster-provider/src/main/java/org/opendaylight/controller/sample/toaster/provider/OpendaylightToaster.java b/opendaylight/md-sal/samples/toaster-provider/src/main/java/org/opendaylight/controller/sample/toaster/provider/OpendaylightToaster.java index d2b0f90194..b7518e094d 100644 --- a/opendaylight/md-sal/samples/toaster-provider/src/main/java/org/opendaylight/controller/sample/toaster/provider/OpendaylightToaster.java +++ b/opendaylight/md-sal/samples/toaster-provider/src/main/java/org/opendaylight/controller/sample/toaster/provider/OpendaylightToaster.java @@ -7,9 +7,6 @@ */ package org.opendaylight.controller.sample.toaster.provider; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; @@ -23,13 +20,11 @@ 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.ReadWriteTransaction; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; -import org.opendaylight.controller.md.sal.common.api.TransactionStatus; 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.sal.common.util.RpcErrors; -import org.opendaylight.controller.sal.common.util.Rpcs; 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; @@ -43,7 +38,7 @@ import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120 import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcError; -import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; import org.opendaylight.yangtools.yang.common.RpcError.ErrorType; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; @@ -105,24 +100,23 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti executor.shutdown(); if (dataProvider != null) { - WriteTransaction t = dataProvider.newWriteOnlyTransaction(); - t.delete(LogicalDatastoreType.OPERATIONAL,TOASTER_IID); - ListenableFuture> future = t.commit(); - Futures.addCallback( future, new FutureCallback>() { + WriteTransaction tx = dataProvider.newWriteOnlyTransaction(); + tx.delete(LogicalDatastoreType.OPERATIONAL,TOASTER_IID); + Futures.addCallback( tx.submit(), new FutureCallback() { @Override - public void onSuccess( RpcResult result ) { + public void onSuccess( final Void result ) { LOG.debug( "Delete Toaster commit result: " + result ); } @Override - public void onFailure( Throwable t ) { + public void onFailure( final Throwable t ) { LOG.error( "Delete of Toaster failed", t ); } } ); } } - private Toaster buildToaster( ToasterStatus status ) { + private Toaster buildToaster( final ToasterStatus status ) { // note - we are simulating a device whose manufacture and model are // fixed (embedded) into the hardware. @@ -163,8 +157,7 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti } // Always return success from the cancel toast call. - return Futures.immediateFuture( Rpcs. getRpcResult( true, - Collections.emptyList() ) ); + return Futures.immediateFuture( RpcResultBuilder. success().build() ); } /** @@ -176,46 +169,43 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti final SettableFuture> futureResult = SettableFuture.create(); - checkStatusAndMakeToast( input, futureResult ); + checkStatusAndMakeToast( input, futureResult, 2 ); return futureResult; } - private List makeToasterOutOfBreadError() { - return Arrays.asList( - RpcErrors.getRpcError( "out-of-stock", "resource-denied", null, null, - "Toaster is out of bread", - ErrorType.APPLICATION, null ) ); + private RpcError makeToasterOutOfBreadError() { + return RpcResultBuilder.newError( ErrorType.APPLICATION, "resource-denied", + "Toaster is out of bread", "out-of-stock", null, null ); } - private List makeToasterInUseError() { - return Arrays.asList( - RpcErrors.getRpcError( "", "in-use", null, ErrorSeverity.WARNING, - "Toaster is busy", ErrorType.APPLICATION, null ) ); + private RpcError makeToasterInUseError() { + return RpcResultBuilder.newWarning( ErrorType.APPLICATION, "in-use", + "Toaster is busy", null, null, null ); } private void checkStatusAndMakeToast( final MakeToastInput input, - final SettableFuture> futureResult ) { + final SettableFuture> futureResult, + final int tries ) { // Read the ToasterStatus and, if currently Up, try to write the status to Down. // If that succeeds, then we essentially have an exclusive lock and can proceed // to make toast. final ReadWriteTransaction tx = dataProvider.newReadWriteTransaction(); - ListenableFuture> readFuture = + ListenableFuture> readFuture = tx.read( LogicalDatastoreType.OPERATIONAL, TOASTER_IID ); - final ListenableFuture> commitFuture = - Futures.transform( readFuture, new AsyncFunction, - RpcResult>() { + final ListenableFuture commitFuture = + Futures.transform( readFuture, new AsyncFunction,Void>() { @Override - public ListenableFuture> apply( - Optional toasterData ) throws Exception { + public ListenableFuture apply( + final Optional toasterData ) throws Exception { ToasterStatus toasterStatus = ToasterStatus.Up; if( toasterData.isPresent() ) { - toasterStatus = ((Toaster)toasterData.get()).getToasterStatus(); + toasterStatus = toasterData.get().getToasterStatus(); } LOG.debug( "Read toaster status: {}", toasterStatus ); @@ -225,8 +215,8 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti if( outOfBread() ) { LOG.debug( "Toaster is out of bread" ); - return Futures.immediateFuture( Rpcs.getRpcResult( - false, null, makeToasterOutOfBreadError() ) ); + return Futures.immediateFailedCheckedFuture( + new TransactionCommitFailedException( "", makeToasterOutOfBreadError() ) ); } LOG.debug( "Setting Toaster status to Down" ); @@ -236,7 +226,7 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti // concurrent toasting. tx.put( LogicalDatastoreType.OPERATIONAL, TOASTER_IID, buildToaster( ToasterStatus.Down ) ); - return tx.commit(); + return tx.submit(); } LOG.debug( "Oops - already making toast!" ); @@ -244,52 +234,44 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti // Return an error since we are already making toast. This will get // propagated to the commitFuture below which will interpret the null // TransactionStatus in the RpcResult as an error condition. - return Futures.immediateFuture( Rpcs.getRpcResult( - false, null, makeToasterInUseError() ) ); + return Futures.immediateFailedCheckedFuture( + new TransactionCommitFailedException( "", makeToasterInUseError() ) ); } } ); - Futures.addCallback( commitFuture, new FutureCallback>() { + Futures.addCallback( commitFuture, new FutureCallback() { @Override - public void onSuccess( RpcResult result ) { - if( result.getResult() == TransactionStatus.COMMITED ) { - - // OK to make toast - currentMakeToastTask.set( executor.submit( - new MakeToastTask( input, futureResult ) ) ); - } else { - - LOG.debug( "Setting error result" ); - - // Either the transaction failed to commit for some reason or, more likely, - // the read above returned ToasterStatus.Down. Either way, fail the - // futureResult and copy the errors. - - futureResult.set( Rpcs.getRpcResult( false, null, result.getErrors() ) ); - } + public void onSuccess( final Void result ) { + // OK to make toast + currentMakeToastTask.set( executor.submit( new MakeToastTask( input, futureResult ) ) ); } @Override - public void onFailure( Throwable ex ) { + public void onFailure( final Throwable ex ) { if( ex instanceof OptimisticLockFailedException ) { // Another thread is likely trying to make toast simultaneously and updated the // status before us. Try reading the status again - if another make toast is // now in progress, we should get ToasterStatus.Down and fail. - LOG.debug( "Got OptimisticLockFailedException - trying again" ); + if( ( tries - 1 ) > 0 ) { + LOG.debug( "Got OptimisticLockFailedException - trying again" ); - checkStatusAndMakeToast( input, futureResult ); + checkStatusAndMakeToast( input, futureResult, tries - 1 ); + } + else { + futureResult.set( RpcResultBuilder. failed() + .withError( ErrorType.APPLICATION, ex.getMessage() ).build() ); + } } else { - LOG.error( "Failed to commit Toaster status", ex ); + LOG.debug( "Failed to commit Toaster status", ex ); - // Got some unexpected error so fail. - futureResult.set( Rpcs. getRpcResult( false, null, Arrays.asList( - RpcErrors.getRpcError( null, null, null, ErrorSeverity.ERROR, - ex.getMessage(), - ErrorType.APPLICATION, ex ) ) ) ); + // Probably already making toast. + futureResult.set( RpcResultBuilder. failed() + .withRpcErrors( ((TransactionCommitFailedException)ex).getErrorList() ) + .build() ); } } } ); @@ -312,7 +294,7 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti notificationProvider.publish( reStockedNotification ); } - return Futures.immediateFuture(Rpcs. getRpcResult(true, Collections.emptyList())); + return Futures.immediateFuture( RpcResultBuilder. success().build() ); } /** @@ -337,20 +319,14 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti WriteTransaction tx = dataProvider.newWriteOnlyTransaction(); tx.put( LogicalDatastoreType.OPERATIONAL,TOASTER_IID, buildToaster( ToasterStatus.Up ) ); - ListenableFuture> commitFuture = tx.commit(); - - Futures.addCallback( commitFuture, new FutureCallback>() { + Futures.addCallback( tx.submit(), new FutureCallback() { @Override - public void onSuccess( RpcResult result ) { - if( result.getResult() != TransactionStatus.COMMITED ) { - LOG.error( "Failed to update toaster status: " + result.getErrors() ); - } - - notifyCallback( result.getResult() == TransactionStatus.COMMITED ); + public void onSuccess( final Void result ) { + notifyCallback( true ); } @Override - public void onFailure( Throwable t ) { + public void onFailure( final Throwable t ) { // We shouldn't get an OptimisticLockFailedException (or any ex) as no // other component should be updating the operational state. LOG.error( "Failed to update toaster status", t ); @@ -358,7 +334,7 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti notifyCallback( false ); } - void notifyCallback( boolean result ) { + void notifyCallback( final boolean result ) { if( resultCallback != null ) { resultCallback.apply( result ); } @@ -410,14 +386,13 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti setToasterStatusUp( new Function() { @Override - public Void apply( Boolean result ) { + public Void apply( final Boolean result ) { currentMakeToastTask.set( null ); LOG.debug("Toast done"); - futureResult.set( Rpcs.getRpcResult( true, null, - Collections.emptyList() ) ); + futureResult.set( RpcResultBuilder.success().build() ); return null; }