Make sure RequestContext has a constant XID
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / services / SalEchoServiceImpl.java
index d6f2cc8d493bdf2915073103d9eb97bd76391e74..819e9f972f070a04f47c0c83b7781dbf91cabf5f 100644 (file)
@@ -7,31 +7,26 @@
  */
 package org.opendaylight.openflowplugin.impl.services;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
-import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
-import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
-import com.google.common.util.concurrent.SettableFuture;
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SendEchoOutputBuilder;
-import org.opendaylight.openflowplugin.impl.callback.SuccessCallback;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
-import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInputBuilder;
 import com.google.common.util.concurrent.JdkFutureAdapters;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoOutput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInput;
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.Future;
 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 java.util.concurrent.Future;
+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.RpcResult;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.SalEchoService;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class SalEchoServiceImpl extends CommonService implements SalEchoService {
 
@@ -43,69 +38,48 @@ public class SalEchoServiceImpl extends CommonService implements SalEchoService
 
     @Override
     public Future<RpcResult<SendEchoOutput>> sendEcho(final SendEchoInput sendEchoInput) {
-        final RequestContext<SendEchoOutput> requestContext = requestContextStack.createRequestContext();
-        final SettableFuture<RpcResult<SendEchoOutput>> sendEchoOutput = requestContextStack
-                .storeOrFail(requestContext);
-        if (!sendEchoOutput.isDone()) {
-            final Xid xid = deviceContext.getNextXid();
-            requestContext.setXid(xid);
-
-            LOG.trace("Hooking xid {} to device context - precaution.", requestContext.getXid().getValue());
-            deviceContext.hookRequestCtx(requestContext.getXid(), requestContext);
+        final RequestContext<SendEchoOutput> requestContext = getRequestContextStack().createRequestContext();
+        if (requestContext == null) {
+            getMessageSpy().spyMessage(null, MessageSpy.STATISTIC_GROUP.TO_SWITCH_SUBMIT_FAILURE);
+            return failedFuture();
+        }
 
-            final EchoInputBuilder echoInputOFJavaBuilder = new EchoInputBuilder();
-            echoInputOFJavaBuilder.setVersion(version);
-            echoInputOFJavaBuilder.setXid(xid.getValue());
-            echoInputOFJavaBuilder.setData(sendEchoInput.getData());
-            final EchoInput echoInputOFJava = echoInputOFJavaBuilder.build();
 
-            final Future<RpcResult<EchoOutput>> rpcEchoOutputOFJava = provideConnectionAdapter(PRIMARY_CONNECTION)
-                    .echo(echoInputOFJava);
-            LOG.debug("Echo with xid {} was sent from controller", xid);
+        final DeviceContext deviceContext = getDeviceContext();
 
-            ListenableFuture<RpcResult<EchoOutput>> listenableRpcEchoOutputOFJava = JdkFutureAdapters
-                    .listenInPoolThread(rpcEchoOutputOFJava);
+        LOG.trace("Hooking xid {} to device context - precaution.", requestContext.getXid().getValue());
+        deviceContext.hookRequestCtx(requestContext.getXid(), requestContext);
 
-            // callback on OF JAVA future
-            SuccessCallback<EchoOutput, SendEchoOutput> successCallback = new SuccessCallback<EchoOutput, SendEchoOutput>(
-                    deviceContext, requestContext, listenableRpcEchoOutputOFJava) {
+        final EchoInputBuilder echoInputOFJavaBuilder = new EchoInputBuilder();
+        echoInputOFJavaBuilder.setVersion(getVersion());
+        echoInputOFJavaBuilder.setXid(requestContext.getXid().getValue());
+        echoInputOFJavaBuilder.setData(sendEchoInput.getData());
+        final EchoInput echoInputOFJava = echoInputOFJavaBuilder.build();
 
-                @Override
-                public RpcResult<SendEchoOutput> transform(RpcResult<EchoOutput> rpcResult) {
-                    EchoOutput echoOutputOFJava = rpcResult.getResult();
-                    SendEchoOutputBuilder sendEchoOutputBuilder = new SendEchoOutputBuilder();
-                    sendEchoOutputBuilder.setData(echoOutputOFJava.getData());
+        // FIXME: should be submitted via OutboundQueue
+        final Future<RpcResult<EchoOutput>> rpcEchoOutputOFJava = getPrimaryConnectionAdapter()
+                .echo(echoInputOFJava);
+        LOG.debug("Echo with xid {} was sent from controller", requestContext.getXid());
 
-                    LOG.debug("Echo with xid {} was received by controller.", rpcResult.getResult().getXid());
-                    return RpcResultBuilder.success(sendEchoOutputBuilder.build()).build();
-                }
-            };
-            Futures.addCallback(listenableRpcEchoOutputOFJava, successCallback);
-        } else {
-            messageSpy.spyMessage(requestContext, MessageSpy.STATISTIC_GROUP.TO_SWITCH_SUBMITTED_FAILURE);
-        }
+        ListenableFuture<RpcResult<EchoOutput>> listenableRpcEchoOutputOFJava = JdkFutureAdapters
+                .listenInPoolThread(rpcEchoOutputOFJava);
 
-        // callback on request context future
-        Futures.addCallback(sendEchoOutput, new FutureCallback<RpcResult<SendEchoOutput>>() {
+        // callback on OF JAVA future
+        SuccessCallback<EchoOutput, SendEchoOutput> successCallback = new SuccessCallback<EchoOutput, SendEchoOutput>(
+                deviceContext, requestContext, listenableRpcEchoOutputOFJava) {
 
             @Override
-            public void onSuccess(RpcResult<SendEchoOutput> result) {
-            }
+            public RpcResult<SendEchoOutput> transform(final RpcResult<EchoOutput> rpcResult) {
+                EchoOutput echoOutputOFJava = rpcResult.getResult();
+                SendEchoOutputBuilder sendEchoOutputBuilder = new SendEchoOutputBuilder();
+                sendEchoOutputBuilder.setData(echoOutputOFJava.getData());
 
-            @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());
-                }
+                LOG.debug("Echo with xid {} was received by controller.", rpcResult.getResult().getXid());
+                return RpcResultBuilder.success(sendEchoOutputBuilder.build()).build();
             }
-        });
+        };
+        Futures.addCallback(listenableRpcEchoOutputOFJava, successCallback);
 
-        return sendEchoOutput;
+        return requestContext.getFuture();
     }
-
 }