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);
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;
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
+
}
}