Changed methods in DeviceContext, created DeviceReplyProcessor interface
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / device / DeviceContextImpl.java
index b3b12af5de754e3422d06508ce2374a79e771eb0..d4595e06f8bee6a17fc05756e1ee90edf7016e1b 100644 (file)
@@ -18,29 +18,32 @@ import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceState;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
-import org.opendaylight.openflowplugin.api.openflow.device.RequestFutureContext;
-import org.opendaylight.openflowplugin.api.openflow.device.Xid;
-import org.opendaylight.openflowplugin.api.openflow.device.XidGenerator;
+import org.opendaylight.openflowplugin.api.openflow.device.*;
+import org.opendaylight.openflowplugin.api.openflow.device.exception.DeviceDataException;
 import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
 import org.opendaylight.openflowplugin.openflow.md.core.session.SwitchConnectionCookieOFImpl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.Error;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.TableFeatures;
 import org.opendaylight.yangtools.yang.binding.ChildOf;
 import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+
 import javax.annotation.Nonnull;
 import java.math.BigInteger;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.concurrent.Future;
 
 /**
  *
  */
-public class DeviceContextImpl implements DeviceContext, TransactionChainListener {
+public class DeviceContextImpl implements DeviceContext, DeviceReplyProcessor, TransactionChainListener {
 
     private static final Logger LOG = LoggerFactory.getLogger(DeviceContextImpl.class);
 
@@ -48,8 +51,9 @@ public class DeviceContextImpl implements DeviceContext, TransactionChainListene
     private final DeviceState deviceState;
     private final DataBroker dataBroker;
     private final XidGenerator xidGenerator;
+    private Map<Long, RequestContext> requests =
+            new HashMap<Long, RequestContext>();
 
-    private final Map<Xid, RequestFutureContext> requests;
     private final Map<SwitchConnectionDistinguisher, ConnectionContext> auxiliaryConnectionContexts;
     private BindingTransactionChain txChainFactory;
 
@@ -121,32 +125,92 @@ public class DeviceContextImpl implements DeviceContext, TransactionChainListene
         return xidGenerator.generate();
     }
 
-    @Override
-    public Map<Xid, RequestFutureContext> getRequests() {
+    public Map<Long, RequestContext> getRequests() {
         return requests;
     }
 
     @Override
-    public void hookRequestCtx(final Xid xid, final RequestFutureContext requestFutureContext) {
-        requests.put(xid, requestFutureContext);
+    public void hookRequestCtx(Xid xid, RequestContext requestFutureContext) {
+        // TODO Auto-generated method stub
+        requests.put(xid.getValue(), requestFutureContext);
+    }
+
+    @Override
+    public void processReply(OfHeader ofHeader) {
+        RequestContext requestContext = getRequests().get(ofHeader.getXid());
+        SettableFuture replyFuture = requestContext.getFuture();
+        getRequests().remove(ofHeader.getXid());
+        RpcResult<OfHeader> rpcResult;
+
+        if(ofHeader instanceof Error) {
+            Error error = (Error) ofHeader;
+            String message = "Operation on device failed";
+            rpcResult= RpcResultBuilder
+                    .<OfHeader>failed()
+                    .withError(RpcError.ErrorType.APPLICATION, message, new DeviceDataException(message, error))
+                    .build();
+        } else {
+            rpcResult= RpcResultBuilder
+                    .<OfHeader>success()
+                    .withResult(ofHeader)
+                    .build();
+        }
+
+        replyFuture.set(rpcResult);
+        try {
+            requestContext.close();
+        } catch (Exception e) {
+            LOG.error("Closing RequestContext failed: ", e);
+        }
     }
 
     @Override
-    public void processReply(final Xid xid, final OfHeader ofHeader) {
-        final SettableFuture replyFuture = getRequests().get(xid).getFuture();
-        replyFuture.set(ofHeader);
+    public void processReply(Xid xid, List<OfHeader> ofHeaderList) {
+        RequestContext requestContext = getRequests().get(xid.getValue());
+        SettableFuture replyFuture = requestContext.getFuture();
+        getRequests().remove(xid.getValue());
+        RpcResult<List<OfHeader>> rpcResult= RpcResultBuilder
+                                                .<List<OfHeader>>success()
+                                                .withResult(ofHeaderList)
+                                                .build();
+        replyFuture.set(rpcResult);
+        try {
+            requestContext.close();
+        } catch (Exception e) {
+            LOG.error("Closing RequestContext failed: ", e);
+        }
     }
 
     @Override
-    public void onTransactionChainFailed(final TransactionChain<?, ?> chain,
-                                         final AsyncTransaction<?, ?> transaction, final Throwable cause) {
+    public void processException(Xid xid, DeviceDataException deviceDataException) {
+        RequestContext requestContext = getRequests().get(xid.getValue());
+
+        SettableFuture replyFuture = requestContext.getFuture();
+        getRequests().remove(xid.getValue());
+        RpcResult<List<OfHeader>> rpcResult= RpcResultBuilder
+                .<List<OfHeader>>failed()
+                .withError(RpcError.ErrorType.APPLICATION, "Message processing failed", deviceDataException)
+                .build();
+        replyFuture.set(rpcResult);
+        try {
+            requestContext.close();
+        } catch (Exception e) {
+            LOG.error("Closing RequestContext failed: ", e);
+        }
+    }
+
+    @Override
+    public void onTransactionChainFailed(TransactionChain<?, ?> chain,
+            AsyncTransaction<?, ?> transaction, Throwable cause) {
         txChainFactory.close();
         txChainFactory = dataBroker.createTransactionChain(DeviceContextImpl.this);
+
     }
 
     @Override
-    public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
-        // NOOP - only yet, here is probably place for notification to get new WriteTransaction
+    public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {
+     // NOOP - only yet, here is probably place for notification to get new WriteTransaction
+
     }
 
 }