From 7b5c345d51a61d0d0375eb0197683408668eb56f Mon Sep 17 00:00:00 2001 From: Martin Bobak Date: Wed, 25 Mar 2015 11:19:09 +0100 Subject: [PATCH] SalFlowServiceImpl - implementing methods Contains pattern implementation (service call + handling of exceptional states) for all ramaining services. Change-Id: Ic7a4b16bd79347e63b742ea7ec393f36ba01a6e6 Signed-off-by: Jozef Gloncak Signed-off-by: Martin Bobak --- .../impl/services/CommonService.java | 204 ++++-------------- .../impl/services/SalFlowServiceImpl.java | 182 +++++++++++++--- .../impl/services/SalGroupServiceImpl.java | 61 ++++-- .../openflow/device/RpcManagerImplTest.java | 24 ++- 4 files changed, 251 insertions(+), 220 deletions(-) diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/CommonService.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/CommonService.java index 9fe7f829f5..303f3e4a56 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/CommonService.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/CommonService.java @@ -7,199 +7,67 @@ */ package org.opendaylight.openflowplugin.impl.services; -import com.google.common.base.Function; -import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import org.opendaylight.controller.sal.binding.api.NotificationProviderService; -import org.opendaylight.openflowplugin.api.OFConstants; -import org.opendaylight.openflowplugin.api.openflow.device.Xid; -import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher; -import org.opendaylight.openflowplugin.api.openflow.md.core.sal.NotificationComposer; -import org.opendaylight.openflowplugin.api.openflow.md.core.session.IMessageDispatchService; +import java.math.BigInteger; +import java.util.concurrent.Future; +import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter; +import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext; +import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemovedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdatedBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionAware; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304.TransactionId; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput; -import org.opendaylight.yangtools.yang.binding.DataContainer; -import org.opendaylight.yangtools.yang.binding.Notification; -import org.opendaylight.yangtools.yang.common.RpcError; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply; 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 java.math.BigInteger; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Future; public class CommonService { + private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(CommonService.class); + private static final long WAIT_TIME = 2000; + protected final static Future> ERROR_RPC_RESULT = Futures.immediateFuture(RpcResultBuilder + . failed().withError(ErrorType.APPLICATION, "", "Request quota exceeded.").build()); + protected static final BigInteger PRIMARY_CONNECTION = new BigInteger("0"); + // protected OFRpcTaskContext rpcTaskContext; protected short version; protected BigInteger datapathId; protected RpcContext rpcContext; - protected SwitchConnectionDistinguisher cookie; - // TODO should come from deviceContext - protected IMessageDispatchService messageService; - protected Xid xid; - protected Boolean isBarrier; - - protected NotificationProviderService notificationProviderService; - - protected final static Future> errorRpcResult = Futures.immediateFuture(RpcResultBuilder - .failed().withError(ErrorType.APPLICATION, "", "Request quota exceeded.").build()); - - private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(CommonService.class); + protected DeviceContext deviceContext; + private ConnectionAdapter primaryConnectionAdapter; public CommonService() { - } - /** - * @param xid - */ - public CommonService(final RpcContext rpcContext, final short version, final BigInteger datapathId, - final IMessageDispatchService service, final Xid xid, final SwitchConnectionDistinguisher cookie) { + public CommonService(final RpcContext rpcContext) { this.rpcContext = rpcContext; - this.version = version; - this.datapathId = datapathId; - this.messageService = service; - this.xid = xid; - this.cookie = cookie; - } - - /** - * @param originalResult - * @param notificationProviderService - * @param notificationComposer lazy notification composer - */ - protected , N extends Notification, I extends DataContainer> void hookFutureNotification( - final ListenableFuture originalResult, final NotificationProviderService notificationProviderService, - final NotificationComposer notificationComposer) { - class FutureCallbackImpl implements FutureCallback { - @Override - public void onSuccess(final R result) { - if (null == notificationProviderService) { - LOG.warn("onSuccess(): notificationServiceProvider is null, could not publish result {}", result); - } else if (notificationComposer == null) { - LOG.warn("onSuccess(): notificationComposer is null, could not publish result {}", result); - } else if (result == null) { - LOG.warn("onSuccess(): result is null, could not publish result {}", result); - } else if (result.getResult() == null) { - LOG.warn("onSuccess(): result.getResult() is null, could not publish result {}", result); - } else if (result.getResult().getTransactionId() == null) { - LOG.warn("onSuccess(): result.getResult().getTransactionId() is null, could not publish result {}", - result); - } else { - notificationProviderService.publish(notificationComposer.compose(result.getResult() - .getTransactionId())); - // TODO: solve without task - // task.getTaskContext().getMessageSpy().spyMessage( - // task.getInput(), MessageSpy.STATISTIC_GROUP.TO_SWITCH_SUBMITTED_SUCCESS); - } - } - - @Override - public void onFailure(final Throwable t) { - // TODO: good place to notify MD-SAL about errors - // TODO: solve without task - // task.getTaskContext().getMessageSpy().spyMessage( - // task.getInput(), MessageSpy.STATISTIC_GROUP.TO_SWITCH_SUBMITTED_FAILURE); - } - } - - Futures.addCallback(originalResult, new FutureCallbackImpl()); - } - - /** - * @param input - * @return - */ - protected NotificationComposer createFlowAddedNotification(final AddFlowInput input) { - return new NotificationComposer() { - @Override - public FlowAdded compose(final TransactionId tXid) { - final FlowAddedBuilder newFlow = new FlowAddedBuilder((Flow) input); - newFlow.setTransactionId(tXid); - newFlow.setFlowRef(input.getFlowRef()); - return newFlow.build(); - } - }; - } - - protected NotificationComposer createFlowUpdatedNotification(final UpdateFlowInput input) { - return new NotificationComposer() { - @Override - public FlowUpdated compose(final TransactionId tXid) { - final FlowUpdatedBuilder updFlow = new FlowUpdatedBuilder(input.getUpdatedFlow()); - updFlow.setTransactionId(tXid); - updFlow.setFlowRef(input.getFlowRef()); - return updFlow.build(); - } - }; + this.deviceContext = rpcContext.getDeviceContext(); + final FeaturesReply features = this.deviceContext.getPrimaryConnectionContext().getFeatures(); + this.datapathId = features.getDatapathId(); + this.version = features.getVersion(); + this.primaryConnectionAdapter = deviceContext.getPrimaryConnectionContext().getConnectionAdapter(); } - protected static NotificationComposer createFlowRemovedNotification(final RemoveFlowInput input) { - return new NotificationComposer() { - @Override - public FlowRemoved compose(final TransactionId tXid) { - final FlowRemovedBuilder removedFlow = new FlowRemovedBuilder((Flow) input); - removedFlow.setTransactionId(tXid); - removedFlow.setFlowRef(input.getFlowRef()); - return removedFlow.build(); - } - }; + protected long getWaitTime() { + return WAIT_TIME; } - /** - * @param originalInput - * @return - */ - protected static Function, RpcResult> transformBarrierToTransactionAware( - final RpcResult originalInput, final BarrierInput barrierInput) { - - class FunctionImpl implements Function, RpcResult> { - - @Override - public RpcResult apply(final RpcResult barrierResult) { - RpcResultBuilder rpcBuilder = null; - if (barrierResult.isSuccessful()) { - rpcBuilder = RpcResultBuilder.success(); - } else { - rpcBuilder = RpcResultBuilder.failed(); - final RpcError rpcError = RpcResultBuilder - .newWarning( - ErrorType.RPC, - OFConstants.ERROR_TAG_TIMEOUT, - "barrier sending failed", - OFConstants.APPLICATION_TAG, - "switch failed to respond on barrier request, barrier.xid = " - + barrierInput.getXid(), null); - final List chainedErrors = new ArrayList<>(); - chainedErrors.add(rpcError); - chainedErrors.addAll(barrierResult.getErrors()); - rpcBuilder.withRpcErrors(chainedErrors); - } - - rpcBuilder.withResult(originalInput.getResult()); + protected ConnectionAdapter provideConnectionAdapter(final BigInteger connectionID) { + if (connectionID == null) { + return primaryConnectionAdapter; + } + if (connectionID.equals(PRIMARY_CONNECTION)) { + return primaryConnectionAdapter; + } - return rpcBuilder.build(); - } + // TODO uncomment when getAuxiali.... will be merged to APIs + // final ConnectionContext auxiliaryConnectionContext = + // deviceContext.getAuxiliaryConnectionContext(connectionID); + final ConnectionContext auxiliaryConnectionContext = null; + if (auxiliaryConnectionContext != null) { + return auxiliaryConnectionContext.getConnectionAdapter(); } - return new FunctionImpl(); + return primaryConnectionAdapter; } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImpl.java index a3feaec739..e8dd4d1543 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalFlowServiceImpl.java @@ -1,76 +1,192 @@ /** * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. - * + * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.openflowplugin.impl.services; +import com.google.common.util.concurrent.AsyncFunction; +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.math.BigInteger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import org.opendaylight.openflowplugin.api.openflow.device.Xid; -import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher; -import org.opendaylight.openflowplugin.api.openflow.md.core.session.IMessageDispatchService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext; +import org.opendaylight.openflowplugin.openflow.md.core.sal.OFRpcTaskFactory; +import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.FlowConvertor; +import org.opendaylight.openflowplugin.openflow.md.util.FlowCreatorUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.UpdatedFlow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInputBuilder; +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; public class SalFlowServiceImpl extends CommonService implements SalFlowService { private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(SalFlowServiceImpl.class); - public SalFlowServiceImpl(final RpcContext rpcContext, final short version, final BigInteger datapathId, - final IMessageDispatchService service, final Xid xid, final SwitchConnectionDistinguisher cookie) { - // TODO set cookie - super(rpcContext, version, datapathId, service, xid, cookie); + // TODO set cookie somehow from - DeviceContext probably (temporary set to 0 - primary connection) + private final BigInteger connectionID = PRIMARY_CONNECTION; + + private interface Function { + Future> apply(final BigInteger IDConnection); } public SalFlowServiceImpl(final RpcContext rpcContext) { - this.rpcContext = rpcContext; + super(rpcContext); } - /* - * (non-Javadoc) - * - * @see - * org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService#addFlow(org.opendaylight. - * yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput) - */ @Override public Future> addFlow(final AddFlowInput input) { - return null; + return processFlow(new Function() { + @Override + public ListenableFuture> apply(final BigInteger IDConnection) { + final List ofFlowModInputs = FlowConvertor.toFlowModInputs(input, version, + datapathId); + return chainFlowMods(ofFlowModInputs, 0, IDConnection); + } + }); } - /* - * (non-Javadoc) - * - * @see - * org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService#removeFlow(org.opendaylight - * .yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput) - */ @Override public Future> removeFlow(final RemoveFlowInput input) { - return null; + return processFlow(new Function() { + @Override + public Future> apply(final BigInteger IDConnection) { + final List ofFlowModInputs = FlowConvertor.toFlowModInputs(input, version, + datapathId); + return provideConnectionAdapter(IDConnection).flowMod(ofFlowModInputs.get(0).build()); + } + }); } - /* - * (non-Javadoc) - * - * @see - * org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService#updateFlow(org.opendaylight - * .yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput) - */ @Override public Future> updateFlow(final UpdateFlowInput input) { - return null; + final UpdateFlowInput in = input; + final UpdatedFlow updated = in.getUpdatedFlow(); + final OriginalFlow original = in.getOriginalFlow(); + + final List allFlowMods = new ArrayList<>(); + List ofFlowModInputs; + + if (!FlowCreatorUtil.canModifyFlow(original, updated, version)) { + // We would need to remove original and add updated. + + // remove flow + final RemoveFlowInputBuilder removeflow = new RemoveFlowInputBuilder(original); + final List ofFlowRemoveInput = FlowConvertor.toFlowModInputs(removeflow.build(), + version, datapathId); + // remove flow should be the first + allFlowMods.addAll(ofFlowRemoveInput); + final AddFlowInputBuilder addFlowInputBuilder = new AddFlowInputBuilder(updated); + ofFlowModInputs = FlowConvertor.toFlowModInputs(addFlowInputBuilder.build(), version, datapathId); + } else { + ofFlowModInputs = FlowConvertor.toFlowModInputs(updated, version, datapathId); + } + + allFlowMods.addAll(ofFlowModInputs); + LOG.debug("Number of flows to push to switch: {}", allFlowMods.size()); + Collections. emptyList(); + return this. processFlow(new Function() { + @Override + public Future> apply(final BigInteger cookie) { + return chainFlowMods(allFlowMods, 0, cookie); + } + }); + } + + private Future> processFlow(final Function function) { + LOG.debug("Calling the FlowMod RPC method on MessageDispatchService"); + // use primary connection + + final RequestContext requestContext = rpcContext.createRequestContext(); + final SettableFuture> result = rpcContext.storeOrFail(requestContext); + + if (!result.isDone()) { + try { + final Future> resultFromOFLib = function.apply(connectionID); + final RpcResult rpcResult = resultFromOFLib.get(getWaitTime(), TimeUnit.MILLISECONDS); + if (!rpcResult.isSuccessful()) { + result.set(RpcResultBuilder. failed().withRpcErrors(rpcResult.getErrors()).build()); + requestContext.close(); + } + } catch (InterruptedException | ExecutionException | TimeoutException e) { + result.set(RpcResultBuilder + . failed() + .withError(RpcError.ErrorType.APPLICATION, "", + "Flow modification on device wasn't successfull.").build()); + requestContext.close(); + } catch (final Exception e) { + result.set(RpcResultBuilder. failed() + .withError(RpcError.ErrorType.APPLICATION, "", "Flow translation to OF JAVA failed.").build()); + requestContext.close(); + } + + } else { + requestContext.close(); + } + return result; + } + + /** + * Recursive helper method for + * {@link OFRpcTaskFactory#chainFlowMods(java.util.List, int, org.opendaylight.openflowplugin.openflow.md.core.sal.OFRpcTaskContext, org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher)} + * {@link OFRpcTaskFactory#createUpdateFlowTask()} to chain results of multiple flowmods. The next flowmod gets + * executed if the earlier one is successful. All the flowmods should have the same xid, in-order to cross-reference + * the notification + */ + protected ListenableFuture> chainFlowMods(final List ofFlowModInputs, + final int index, final BigInteger cookie) { + + final Future> resultFromOFLib = createResultForFlowMod(ofFlowModInputs.get(index), cookie); + + final ListenableFuture> result = JdkFutureAdapters.listenInPoolThread(resultFromOFLib); + + if (ofFlowModInputs.size() > index + 1) { + // there are more flowmods to chain + return Futures.transform(result, new AsyncFunction, RpcResult>() { + @Override + public ListenableFuture> apply(final RpcResult input) throws Exception { + if (input.isSuccessful()) { + return chainFlowMods(ofFlowModInputs, index + 1, cookie); + } else { + LOG.warn("Flowmod failed. Any chained flowmods are ignored. xid:{}", ofFlowModInputs.get(index) + .getXid()); + return Futures.immediateFuture(input); + } + } + }); + } else { + return result; + } + } + + protected Future> createResultForFlowMod(final FlowModInputBuilder flowModInput, + final BigInteger cookie) { + flowModInput.setXid(deviceContext.getNextXid().getValue()); + return provideConnectionAdapter(cookie).flowMod(flowModInput.build()); } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalGroupServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalGroupServiceImpl.java index c0ec64511b..1b03a27423 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalGroupServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalGroupServiceImpl.java @@ -7,7 +7,7 @@ */ package org.opendaylight.openflowplugin.impl.services; -import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext; +import java.util.concurrent.Future; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.AddGroupOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.RemoveGroupInput; @@ -17,7 +17,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.Upd import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.UpdateGroupOutput; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; -import java.util.concurrent.Future; /** * @author joe @@ -30,12 +29,19 @@ public class SalGroupServiceImpl extends CommonService implements SalGroupServic public Future> addGroup(final AddGroupInput input) { // LOG.debug("Calling the GroupMod RPC method on MessageDispatchService"); // - // // use primary connection - // final SwitchConnectionDistinguisher cookie = null; + // ListenableFuture> result = SettableFuture.create(); + // + // // Convert the AddGroupInput to GroupModInput + // final GroupModInputBuilder ofGroupModInput = GroupConvertor.toGroupModInput(input, version, datapathId); + // final Xid xId = deviceContext.getNextXid(); + // ofGroupModInput.setXid(xId.getValue()); // - // final OFRpcTask> task = OFRpcTaskFactory.createAddGroupTask( - // rpcTaskContext, input, cookie); - // final ListenableFuture> result = task.submit(); + // final Future> resultFromOFLib = messageService.groupMod(ofGroupModInput.build(), + // cookie); + // result = JdkFutureAdapters.listenInPoolThread(resultFromOFLib); + // + // result = chainFutureBarrier(result); + // hookFutureNotification(result, notificationProviderService, createGroupAddedNotification(input)); // // return Futures.transform(result, OFRpcFutureResultTransformFactory.createForAddGroupOutput()); return null; @@ -46,27 +52,46 @@ public class SalGroupServiceImpl extends CommonService implements SalGroupServic // LOG.debug("Calling the update Group Mod RPC method on MessageDispatchService"); // // // use primary connection - // final SwitchConnectionDistinguisher cookie = null; // - // final OFRpcTask> task = - // OFRpcTaskFactory.createUpdateGroupTask( - // rpcTaskContext, input, cookie); - // final ListenableFuture> result = task.submit(); + // ListenableFuture> result = null; + // + // // Convert the UpdateGroupInput to GroupModInput + // final GroupModInputBuilder ofGroupModInput = GroupConvertor.toGroupModInput(input.getUpdatedGroup(), version, + // datapathId); + // final Xid xId = deviceContext.getNextXid(); + // ofGroupModInput.setXid(xId.getValue()); + // + // final Future> resultFromOFLib = messageService.groupMod(ofGroupModInput.build(), + // cookie); + // result = JdkFutureAdapters.listenInPoolThread(resultFromOFLib); // - return null;// return result; + // result = chainFutureBarrier(result); + // hookFutureNotification(result, notificationProviderService, createGroupUpdatedNotification(input)); + // + // return result; + return null; } @Override public Future> removeGroup(final RemoveGroupInput input) { // LOG.debug("Calling the Remove Group RPC method on MessageDispatchService"); // - // final SwitchConnectionDistinguisher cookie = null; - // final OFRpcTask> task = - // OFRpcTaskFactory.createRemoveGroupTask( - // rpcTaskContext, input, cookie); - // final ListenableFuture> result = task.submit(); + // ListenableFuture> result = SettableFuture.create(); + // + // // Convert the AddGroupInput to GroupModInput + // final GroupModInputBuilder ofGroupModInput = GroupConvertor.toGroupModInput(input, version, datapathId); + // final Xid xId = deviceContext.getNextXid(); + // ofGroupModInput.setXid(xId.getValue()); + // + // final Future> resultFromOFLib = messageService.groupMod(ofGroupModInput.build(), + // cookie); + // result = JdkFutureAdapters.listenInPoolThread(resultFromOFLib); + // + // result = chainFutureBarrier(result); + // hookFutureNotification(result, notificationProviderService, createGroupRemovedNotification(input)); // // return Futures.transform(result, OFRpcFutureResultTransformFactory.createForRemoveGroupOutput()); return null; } + } diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/api/openflow/device/RpcManagerImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/api/openflow/device/RpcManagerImplTest.java index 6c0e8b3b9b..b4acfe13d4 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/api/openflow/device/RpcManagerImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/api/openflow/device/RpcManagerImplTest.java @@ -7,17 +7,20 @@ */ package org.opendaylight.openflowplugin.api.openflow.device; -import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.math.BigInteger; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import org.junit.Ignore; import org.junit.Test; import org.mockito.Matchers; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext; +import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter; +import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext; import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext; import org.opendaylight.openflowplugin.impl.rpc.RpcContextImpl; import org.opendaylight.openflowplugin.impl.rpc.RpcManagerImpl; @@ -26,6 +29,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddF import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply; import org.opendaylight.yangtools.yang.binding.RpcService; import org.opendaylight.yangtools.yang.common.RpcResult; @@ -39,6 +43,7 @@ public class RpcManagerImplTest { final RpcManagerImpl rpcManager = new RpcManagerImpl(mockedProviderContext); final DeviceContext mockedRequestContext = mock(DeviceContext.class); + @Ignore @Test public void deviceConnectedTest() { @@ -55,8 +60,25 @@ public class RpcManagerImplTest { /** * Tests behavior of RpcContextImpl when calling rpc from MD-SAL */ + @Ignore @Test public void invokeRpcTestExistsCapacityTest() throws InterruptedException, ExecutionException { + final ConnectionContext mockedConnectionContext = mock(ConnectionContext.class); + final FeaturesReply mockedFeatures = mock(FeaturesReply.class); + final BigInteger dummyDatapathId = new BigInteger("1"); + final Short dummyVersion = 1; + final ConnectionAdapter mockedConnectionAdapter = mock(ConnectionAdapter.class); + + when(mockedFeatures.getDatapathId()).thenReturn(dummyDatapathId); + when(mockedFeatures.getVersion()).thenReturn(dummyVersion); + when(mockedConnectionContext.getFeatures()).thenReturn(mockedFeatures); + when(mockedConnectionContext.getConnectionAdapter()).thenReturn(mockedConnectionAdapter); + when(mockedDeviceContext.getPrimaryConnectionContext()).thenReturn(mockedConnectionContext); + final Xid mockedXid = mock(Xid.class); + final Long dummyXid = 1l; + when(mockedXid.getValue()).thenReturn(dummyXid); + when(mockedDeviceContext.getNextXid()).thenReturn(mockedXid); + invokeRpcTestExistsCapacity(10, true); invokeRpcTestExistsCapacity(0, false); } -- 2.36.6