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=de5ddd9a75298f61d5c4ce15c00b9df0e170cc92;hb=c46e223995956f1f759c551163c212947c1e2fb7;hpb=75f9ebff528344841c86e08d302340638db20858 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 de5ddd9a75..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 @@ -20,10 +20,10 @@ 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.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.DisplayString; import org.opendaylight.yang.gen.v1.http.netconfcentral.org.ns.toaster.rev091120.MakeToastInput; @@ -100,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. @@ -170,7 +169,7 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti final SettableFuture> futureResult = SettableFuture.create(); - checkStatusAndMakeToast( input, futureResult ); + checkStatusAndMakeToast( input, futureResult, 2 ); return futureResult; } @@ -186,27 +185,27 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti } 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 ); @@ -216,8 +215,8 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti if( outOfBread() ) { LOG.debug( "Toaster is out of bread" ); - return Futures.immediateFuture( RpcResultBuilder.failed() - .withRpcError( makeToasterOutOfBreadError() ).build() ); + return Futures.immediateFailedCheckedFuture( + new TransactionCommitFailedException( "", makeToasterOutOfBreadError() ) ); } LOG.debug( "Setting Toaster status to Down" ); @@ -227,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!" ); @@ -235,51 +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( RpcResultBuilder.failed() - .withRpcError( makeToasterInUseError() ).build() ); + 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( RpcResultBuilder.failed().withRpcErrors( - result.getErrors() ).build() ); - } + 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. + // Probably already making toast. futureResult.set( RpcResultBuilder. failed() - .withError( ErrorType.APPLICATION, ex.getMessage() ).build() ); + .withRpcErrors( ((TransactionCommitFailedException)ex).getErrorList() ) + .build() ); } } } ); @@ -327,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 ); @@ -348,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 ); } @@ -400,7 +386,7 @@ public class OpendaylightToaster implements ToasterService, ToasterProviderRunti setToasterStatusUp( new Function() { @Override - public Void apply( Boolean result ) { + public Void apply( final Boolean result ) { currentMakeToastTask.set( null );