Merge "SONAR TD - Group actions redundancy"
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / services / SalEchoServiceImpl.java
index 616c40550ad0d4f407be6f01853683482b457446..750a63a77269be2fb044e21f4921c6e5786d8728 100644 (file)
  */
 package org.opendaylight.openflowplugin.impl.services;
 
-import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.base.Function;
+import com.google.common.base.Preconditions;
 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.SettableFuture;
 import java.util.concurrent.Future;
+import javax.annotation.Nullable;
 import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContextStack;
-import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
-import org.opendaylight.openflowplugin.impl.callback.SuccessCallback;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SalEchoService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SendEchoInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SendEchoOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SendEchoOutputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput;
-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;
 
-public class SalEchoServiceImpl extends CommonService implements SalEchoService {
+public final class SalEchoServiceImpl implements SalEchoService {
 
-    private static final Logger LOG = LoggerFactory.getLogger(SalEchoServiceImpl.class);
+    private final EchoService echoService;
 
     public SalEchoServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext) {
-        super(requestContextStack, deviceContext);
+        echoService = new EchoService(requestContextStack, deviceContext);
     }
 
     @Override
     public Future<RpcResult<SendEchoOutput>> sendEcho(final SendEchoInput sendEchoInput) {
-        final RequestContext<SendEchoOutput> requestContext = getRequestContextStack().createRequestContext();
-        final SettableFuture<RpcResult<SendEchoOutput>> sendEchoOutput = getRequestContextStack()
-                .storeOrFail(requestContext);
-        if (!sendEchoOutput.isDone()) {
-            final DeviceContext deviceContext = getDeviceContext();
-            Long reserverXid = deviceContext.getReservedXid();
-            if (null == reserverXid) {
-                if (null == reserverXid) {
-                    reserverXid = deviceContext.getReservedXid();
-                    RequestContextUtil.closeRequestContextWithRpcError(requestContext, "Outbound queue wasn't able to reserve XID.");
-                    return sendEchoOutput;
-                }
-            }
-            final Xid xid = new Xid(reserverXid);
-            requestContext.setXid(xid);
-
-            LOG.trace("Hooking xid {} to device context - precaution.", requestContext.getXid().getValue());
-            deviceContext.hookRequestCtx(requestContext.getXid(), requestContext);
-
-            final EchoInputBuilder echoInputOFJavaBuilder = new EchoInputBuilder();
-            echoInputOFJavaBuilder.setVersion(getVersion());
-            echoInputOFJavaBuilder.setXid(xid.getValue());
-            echoInputOFJavaBuilder.setData(sendEchoInput.getData());
-            final EchoInput echoInputOFJava = echoInputOFJavaBuilder.build();
-
-            final Future<RpcResult<EchoOutput>> rpcEchoOutputOFJava = getPrimaryConnectionAdapter()
-                    .echo(echoInputOFJava);
-            LOG.debug("Echo with xid {} was sent from controller", xid);
-
-            ListenableFuture<RpcResult<EchoOutput>> listenableRpcEchoOutputOFJava = JdkFutureAdapters
-                    .listenInPoolThread(rpcEchoOutputOFJava);
-
-            // callback on OF JAVA future
-            SuccessCallback<EchoOutput, SendEchoOutput> successCallback = new SuccessCallback<EchoOutput, SendEchoOutput>(
-                    deviceContext, requestContext, listenableRpcEchoOutputOFJava) {
-
-                @Override
-                public RpcResult<SendEchoOutput> transform(RpcResult<EchoOutput> rpcResult) {
-                    EchoOutput echoOutputOFJava = rpcResult.getResult();
-                    SendEchoOutputBuilder sendEchoOutputBuilder = new SendEchoOutputBuilder();
-                    sendEchoOutputBuilder.setData(echoOutputOFJava.getData());
-
-                    LOG.debug("Echo with xid {} was received by controller.", rpcResult.getResult().getXid());
-                    return RpcResultBuilder.success(sendEchoOutputBuilder.build()).build();
-                }
-            };
-            Futures.addCallback(listenableRpcEchoOutputOFJava, successCallback);
-        } else {
-            getMessageSpy().spyMessage(requestContext, MessageSpy.STATISTIC_GROUP.TO_SWITCH_SUBMIT_FAILURE);
-        }
-
-        // callback on request context future
-        Futures.addCallback(sendEchoOutput, new FutureCallback<RpcResult<SendEchoOutput>>() {
-
-            @Override
-            public void onSuccess(RpcResult<SendEchoOutput> result) {
-            }
+        final EchoInputBuilder echoInputBld = new EchoInputBuilder()
+                .setData(sendEchoInput.getData());
+        return transform(echoService.handleServiceCall(echoInputBld));
+    }
 
+    private Future<RpcResult<SendEchoOutput>> transform(final ListenableFuture<RpcResult<EchoOutput>> rpcResultListenableFuture) {
+        return Futures.transform(rpcResultListenableFuture, new Function<RpcResult<EchoOutput>, RpcResult<SendEchoOutput>>() {
+            @Nullable
             @Override
-            public void onFailure(Throwable t) {
-                if (sendEchoOutput.isCancelled()) {
-                    requestContext.getFuture().set(
-                            RpcResultBuilder.<SendEchoOutput>failed()
-                                    .withError(ErrorType.APPLICATION, "Echo response wasn't obtained until barrier.")
-                                    .build());
-                    LOG.debug("Echo reply with xid {} wasn't received by controller until barrier.",
-                            requestContext.getXid());
+            public RpcResult<SendEchoOutput> apply(@Nullable final RpcResult<EchoOutput> input) {
+                Preconditions.checkNotNull(input, "echoOutput value is never expected to be NULL");
+                final RpcResult<SendEchoOutput> rpcOutput;
+                if (input.isSuccessful()) {
+                    final SendEchoOutput sendEchoOutput = new SendEchoOutputBuilder()
+                            .setData(input.getResult().getData())
+                            .build();
+                    rpcOutput = RpcResultBuilder.success(sendEchoOutput).build();
+                } else {
+                    rpcOutput = RpcResultBuilder.<SendEchoOutput>failed()
+                            .withRpcErrors(input.getErrors())
+                            .build();
                 }
+                return rpcOutput;
             }
         });
-
-        return sendEchoOutput;
     }
 
 }