From: Robert Varga Date: Fri, 15 May 2015 21:24:50 +0000 (+0200) Subject: Cleanup RequestContextStack X-Git-Tag: release/lithium~167 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=e4faef067c5ed399ccdd686d26c09a0b7a6cf4b7;p=openflowplugin.git Cleanup RequestContextStack Instead of exposing the limits as a tweakable API, we should specify the limit at instantiation as an implementation-specific thing. We document that RequestContextStack.createRequestContext() can return null and let callers deal with that. This change allows us to implement RpcContext throttling using a simple counting Semaphore, which is more scalable and efficient than an explicit queue. To do that, we turn RequestContextImpl into AbstractRequestContext, which is subclassed as needed by the various RequestContextStack implementations. Change-Id: Ibbeafad6cd7f740284264cca22412e11696cede8 Signed-off-by: Robert Varga --- diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/RequestContext.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/RequestContext.java index d21a46fa04..7ee4225247 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/RequestContext.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/RequestContext.java @@ -8,6 +8,7 @@ package org.opendaylight.openflowplugin.api.openflow.device; + /** * Request context handles all requests on device. Number of requests is limited by request quota. When this quota is * exceeded all rpc's will end up with exception. @@ -41,4 +42,6 @@ public interface RequestContext extends RequestFutureContext, AutoCloseabl */ void setWaitTimeout(long waitTimeout); + @Override + void close(); } diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/RequestContextStack.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/RequestContextStack.java index 7cde91601c..00a0a586a7 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/RequestContextStack.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/device/RequestContextStack.java @@ -5,33 +5,18 @@ * 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.api.openflow.device; -import com.google.common.util.concurrent.SettableFuture; -import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; -import org.opendaylight.yangtools.yang.common.RpcResult; +import javax.annotation.Nullable; /** * Created by Martin Bobak <mbobak@cisco.com> on 1.4.2015. */ public interface RequestContextStack { - - void forgetRequestContext(RequestContext requestContext); - - /** - * Method adds request to request queue which has limited quota. After number of requests exceeds quota limit future - * will be done immediately and will contain information about exceeded request quota. - * - * @param data - */ - SettableFuture> storeOrFail(RequestContext data); - /** * Method returns new request context for current request. * - * @return + * @return A request context, or null if one cannot be created. */ - RequestContext createRequestContext(); - + @Nullable RequestContext createRequestContext(); } diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/rpc/RpcContext.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/rpc/RpcContext.java index 94ce2b2909..cb14a13669 100644 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/rpc/RpcContext.java +++ b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/rpc/RpcContext.java @@ -19,16 +19,5 @@ import org.opendaylight.yangtools.yang.binding.RpcService; * Created by Martin Bobak <mbobak@cisco.com> on 25.2.2015. */ public interface RpcContext extends RequestContextStack, AutoCloseable, DeviceDisconnectedHandler { - void registerRpcServiceImplementation(Class serviceClass, S serviceInstance); - - - /** - * Method for setting request quota value. When the Request Context quota is exceeded, incoming RPCs fail - * immediately, with a well-defined error. - * - * @param maxRequestsPerDevice - */ - void setRequestContextQuota(int maxRequestsPerDevice); - } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java index 0560e945d5..c02764b2f7 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/DeviceManagerImpl.java @@ -11,7 +11,6 @@ import com.google.common.base.Preconditions; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.SettableFuture; import io.netty.util.HashedWheelTimer; import java.math.BigInteger; import java.util.ArrayList; @@ -52,7 +51,7 @@ import org.opendaylight.openflowplugin.impl.common.NodeStaticReplyTranslatorUtil import org.opendaylight.openflowplugin.impl.connection.OutboundQueueProviderImpl; import org.opendaylight.openflowplugin.impl.connection.ThrottledNotificationsOffererImpl; import org.opendaylight.openflowplugin.impl.device.listener.OpenflowProtocolListenerFullImpl; -import org.opendaylight.openflowplugin.impl.rpc.RequestContextImpl; +import org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext; import org.opendaylight.openflowplugin.impl.util.DeviceStateUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeBuilder; @@ -136,19 +135,14 @@ public class DeviceManagerImpl implements DeviceManager, AutoCloseable { this.messageIntelligenceAgency = messageIntelligenceAgency; emptyRequestContextStack = new RequestContextStack() { - @Override - public void forgetRequestContext(final RequestContext requestContext) { - //NOOP - } - - @Override - public SettableFuture> storeOrFail(final RequestContext data) { - return data.getFuture(); - } - @Override public RequestContext createRequestContext() { - return new RequestContextImpl<>(this); + return new AbstractRequestContext() { + @Override + public void close() { + //NOOP + } + }; } }; } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RequestContextImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/AbstractRequestContext.java similarity index 68% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RequestContextImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/AbstractRequestContext.java index 5af5880f10..4208ca9f3d 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RequestContextImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/AbstractRequestContext.java @@ -9,27 +9,16 @@ package org.opendaylight.openflowplugin.impl.rpc; import com.google.common.util.concurrent.SettableFuture; 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.yangtools.yang.common.RpcResult; -/** - * @author joe - */ -public class RequestContextImpl implements RequestContext { - - private final RequestContextStack requestContextStack; +public abstract class AbstractRequestContext implements RequestContext { private SettableFuture> rpcResultFuture; private long waitTimeout; private Xid xid; - public RequestContextImpl(RequestContextStack requestContextStack) { - this.requestContextStack = requestContextStack; - } + protected AbstractRequestContext() { - @Override - public void close() { - requestContextStack.forgetRequestContext(this); } @Override @@ -46,7 +35,7 @@ public class RequestContextImpl implements RequestContext { } @Override - public void setXid(Xid xid) { + public void setXid(final Xid xid) { this.xid = xid; } @@ -56,7 +45,7 @@ public class RequestContextImpl implements RequestContext { } @Override - public void setWaitTimeout(long waitTimeout) { + public void setWaitTimeout(final long waitTimeout) { this.waitTimeout = waitTimeout; } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImpl.java index 0c12637e54..ab39f92f3a 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcContextImpl.java @@ -7,10 +7,9 @@ */ package org.opendaylight.openflowplugin.impl.rpc; -import com.google.common.util.concurrent.SettableFuture; import java.util.Collection; import java.util.HashSet; -import javax.annotation.concurrent.GuardedBy; +import java.util.concurrent.Semaphore; import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration; import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext; @@ -22,30 +21,24 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; import org.opendaylight.yangtools.yang.binding.RpcService; -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; public class RpcContextImpl implements RpcContext { - private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(RpcContextImpl.class); - private MessageSpy messagSpy; - final RpcProviderRegistry rpcProviderRegistry; + private static final Logger LOG = LoggerFactory.getLogger(RpcContextImpl.class); + private final RpcProviderRegistry rpcProviderRegistry; + private final MessageSpy messageSpy; + private final Semaphore tracker; // TODO: add private Sal salBroker private final KeyedInstanceIdentifier nodeInstanceIdentifier; private final Collection> rpcRegistrations = new HashSet<>(); - - @GuardedBy("requestsList") - private final Collection> requestsList = new HashSet>(); - - private int maxRequestsPerDevice; - - public RpcContextImpl(final MessageSpy messagSpy, final RpcProviderRegistry rpcProviderRegistry, final KeyedInstanceIdentifier nodeInstanceIdentifier) { - this.messagSpy = messagSpy; + public RpcContextImpl(final MessageSpy messageSpy, final RpcProviderRegistry rpcProviderRegistry, final KeyedInstanceIdentifier nodeInstanceIdentifier, final int maxRequests) { + this.messageSpy = messageSpy; this.rpcProviderRegistry = rpcProviderRegistry; this.nodeInstanceIdentifier = nodeInstanceIdentifier; + tracker = new Semaphore(maxRequests, true); } /** @@ -61,64 +54,34 @@ public class RpcContextImpl implements RpcContext { LOG.debug("Registration of service {} for device {}.", serviceClass, nodeInstanceIdentifier); } - @Override - public SettableFuture> storeOrFail(final RequestContext requestContext) { - final SettableFuture> rpcResultFuture = requestContext.getFuture(); - - final boolean success; - // FIXME: use a fixed-size collection, with lockless reserve/set queue - synchronized (requestsList) { - if (requestsList.size() < maxRequestsPerDevice) { - requestsList.add(requestContext); - success = true; - } else { - success = false; - } - } - - if (!success) { - final RpcResult rpcResult = RpcResultBuilder.failed() - .withError(RpcError.ErrorType.APPLICATION, "", "Device's request queue is full.").build(); - rpcResultFuture.set(rpcResult); - } - - return rpcResultFuture; - } - /** * Unregisters all services. * * @see java.lang.AutoCloseable#close() */ @Override - public void close() throws Exception { + public void close() { for (final RoutedRpcRegistration rpcRegistration : rpcRegistrations) { rpcRegistration.unregisterPath(NodeContext.class, nodeInstanceIdentifier); rpcRegistration.close(); } } - /** - * @see org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext#setRequestContextQuota(int) - */ - @Override - public void setRequestContextQuota(final int maxRequestsPerDevice) { - this.maxRequestsPerDevice = maxRequestsPerDevice; - } - @Override - public void forgetRequestContext(final RequestContext requestContext) { - synchronized (requestsList) { - requestsList.remove(requestContext); - LOG.trace("Removed request context with xid {}. Context request in list {}.", - requestContext.getXid().getValue(), requestsList.size()); - messagSpy.spyMessage(RpcContextImpl.class, MessageSpy.STATISTIC_GROUP.REQUEST_STACK_FREED); + public RequestContext createRequestContext() { + if (!tracker.tryAcquire()) { + LOG.trace("Device queue {} at capacity", this); + return null; } - } - @Override - public RequestContext createRequestContext() { - return new RequestContextImpl(this); + return new AbstractRequestContext() { + @Override + public void close() { + tracker.release(); + LOG.trace("Removed request context with xid {}", getXid().getValue()); + messageSpy.spyMessage(RpcContextImpl.class, MessageSpy.STATISTIC_GROUP.REQUEST_STACK_FREED); + } + }; } @Override @@ -126,9 +89,5 @@ public class RpcContextImpl implements RpcContext { for (RoutedRpcRegistration registration : rpcRegistrations) { registration.close(); } - - synchronized (requestsList) { - requestsList.clear(); - } } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImpl.java index f8e7a2506e..a619261a1a 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/rpc/RpcManagerImpl.java @@ -33,8 +33,7 @@ public class RpcManagerImpl implements RpcManager { @Override public void onDeviceContextLevelUp(final DeviceContext deviceContext) { - final RpcContext rpcContext = new RpcContextImpl(deviceContext.getMessageSpy(), rpcProviderRegistry, deviceContext.getDeviceState().getNodeInstanceIdentifier()); - rpcContext.setRequestContextQuota(maxRequestsQuota.intValue()); + final RpcContext rpcContext = new RpcContextImpl(deviceContext.getMessageSpy(), rpcProviderRegistry, deviceContext.getDeviceState().getNodeInstanceIdentifier(), maxRequestsQuota.intValue()); deviceContext.setDeviceDisconnectedHandler(rpcContext); MdSalRegistratorUtils.registerServices(rpcContext, deviceContext); // finish device initialization cycle back to DeviceManager 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 3fb28d3450..eff804bc09 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 @@ -10,9 +10,7 @@ package org.opendaylight.openflowplugin.impl.services; import com.google.common.base.Function; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.SettableFuture; 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; @@ -21,7 +19,7 @@ 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.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FeaturesReply; -import org.opendaylight.yangtools.yang.common.RpcError.ErrorType; +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; @@ -29,10 +27,6 @@ import org.slf4j.Logger; public abstract class CommonService { private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(CommonService.class); private static final long WAIT_TIME = 2000; - private final static Future> ERROR_RPC_RESULT = Futures.immediateFuture(RpcResultBuilder - .failed().withError(ErrorType.APPLICATION, "", "Request quota exceeded.").build()); - - private static final BigInteger PRIMARY_CONNECTION = BigInteger.ZERO; private final short version; @@ -43,7 +37,7 @@ public abstract class CommonService { private final MessageSpy messageSpy; - public CommonService(final RequestContextStack requestContextStack, DeviceContext deviceContext) { + public CommonService(final RequestContextStack requestContextStack, final DeviceContext deviceContext) { this.requestContextStack = requestContextStack; this.deviceContext = deviceContext; final FeaturesReply features = this.deviceContext.getPrimaryConnectionContext().getFeatures(); @@ -132,12 +126,11 @@ public abstract class CommonService { final DataCrateBuilder dataCrateBuilder) { LOG.trace("Handling general service call"); - final RequestContext requestContext = requestContextStack.createRequestContext(); - final SettableFuture> result = requestContextStack.storeOrFail(requestContext); - if (result.isDone()) { + final RequestContext requestContext = createRequestContext(); + if (requestContext == null) { LOG.trace("Request context refused."); - deviceContext.getMessageSpy().spyMessage(requestContext.getClass(), MessageSpy.STATISTIC_GROUP.TO_SWITCH_DISREGARDED); - return result; + deviceContext.getMessageSpy().spyMessage(null, MessageSpy.STATISTIC_GROUP.TO_SWITCH_DISREGARDED); + return failedFuture(); } Long reservedXid = deviceContext.getReservedXid(); @@ -145,9 +138,8 @@ public abstract class CommonService { //retry reservedXid = deviceContext.getReservedXid(); if (null == reservedXid) { - RequestContextUtil.closeRequestContextWithRpcError(requestContext, "Outbound queue wasn't able to reserve XID."); deviceContext.getMessageSpy().spyMessage(requestContext.getClass(), MessageSpy.STATISTIC_GROUP.TO_SWITCH_RESERVATION_REJECTED); - return result; + return RequestContextUtil.closeRequestContextWithRpcError(requestContext, "Outbound queue wasn't able to reserve XID."); } } final Xid xid = new Xid(reservedXid); @@ -162,8 +154,17 @@ public abstract class CommonService { messageSpy.spyMessage(requestContext.getClass(), MessageSpy.STATISTIC_GROUP.TO_SWITCH_READY_FOR_SUBMIT); function.apply(dataCrate); - return result; + return requestContext.getFuture(); } + protected final RequestContext createRequestContext() { + return requestContextStack.createRequestContext(); + } + + protected static ListenableFuture> failedFuture() { + final RpcResult rpcResult = RpcResultBuilder.failed() + .withError(RpcError.ErrorType.APPLICATION, "", "Request quota exceeded").build(); + return Futures.immediateFuture(rpcResult); + } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/FlowCapableTransactionServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/FlowCapableTransactionServiceImpl.java index 4fc6821f18..856c3ad597 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/FlowCapableTransactionServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/FlowCapableTransactionServiceImpl.java @@ -7,11 +7,9 @@ */ package org.opendaylight.openflowplugin.impl.services; -import com.google.common.util.concurrent.FutureCallback; 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 org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; @@ -24,7 +22,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev150304. import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput; -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; @@ -38,74 +35,51 @@ public class FlowCapableTransactionServiceImpl extends CommonService implements } @Override - public Future> sendBarrier(SendBarrierInput input) { + public Future> sendBarrier(final SendBarrierInput input) { final RequestContext requestContext = getRequestContextStack().createRequestContext(); - final SettableFuture> sendBarrierOutput = getRequestContextStack() - .storeOrFail(requestContext); - if (!sendBarrierOutput.isDone()) { - final DeviceContext deviceContext = getDeviceContext(); - final Long reservedXid = deviceContext.getReservedXid(); - if (null == reservedXid){ - RequestContextUtil.closeRequestContextWithRpcError(requestContext, "Outbound queue wasn't able to reserve XID."); - return sendBarrierOutput; - } - final Xid xid = new Xid(reservedXid); - requestContext.setXid(xid); - - final BarrierInputBuilder barrierInputOFJavaBuilder = new BarrierInputBuilder(); - barrierInputOFJavaBuilder.setVersion(getVersion()); - barrierInputOFJavaBuilder.setXid(xid.getValue()); + if (requestContext == null) { + getMessageSpy().spyMessage(null, MessageSpy.STATISTIC_GROUP.TO_SWITCH_SUBMIT_FAILURE); + return failedFuture(); + } - LOG.trace("Hooking xid {} to device context - precaution.", requestContext.getXid().getValue()); - deviceContext.hookRequestCtx(requestContext.getXid(), requestContext); + final DeviceContext deviceContext = getDeviceContext(); + final Long reservedXid = deviceContext.getReservedXid(); + if (null == reservedXid) { + return RequestContextUtil.closeRequestContextWithRpcError(requestContext, "Outbound queue wasn't able to reserve XID."); + } + final Xid xid = new Xid(reservedXid); + requestContext.setXid(xid); - final BarrierInput barrierInputOFJava = barrierInputOFJavaBuilder.build(); + final BarrierInputBuilder barrierInputOFJavaBuilder = new BarrierInputBuilder(); + barrierInputOFJavaBuilder.setVersion(getVersion()); + barrierInputOFJavaBuilder.setXid(xid.getValue()); - final Future> barrierOutputOFJava = getPrimaryConnectionAdapter() - .barrier(barrierInputOFJava); - LOG.debug("Barrier with xid {} was sent from controller.", xid); + LOG.trace("Hooking xid {} to device context - precaution.", requestContext.getXid().getValue()); + deviceContext.hookRequestCtx(requestContext.getXid(), requestContext); - ListenableFuture> listenableBarrierOutputOFJava = JdkFutureAdapters - .listenInPoolThread(barrierOutputOFJava); + final BarrierInput barrierInputOFJava = barrierInputOFJavaBuilder.build(); - // callback on OF JAVA future - SuccessCallback successCallback = new SuccessCallback( - deviceContext, requestContext, listenableBarrierOutputOFJava) { + // FIXME: should be submitted through OutboundQueue + final Future> barrierOutputOFJava = getPrimaryConnectionAdapter() + .barrier(barrierInputOFJava); + LOG.debug("Barrier with xid {} was sent from controller.", xid); - @Override - public RpcResult transform(RpcResult rpcResult) { - //no transformation, because output for request context is Void - LOG.debug("Barrier reply with xid {} was obtained by controller.", rpcResult.getResult().getXid()); - return RpcResultBuilder.success().build(); - } - }; - Futures.addCallback(listenableBarrierOutputOFJava, successCallback); - } else { - getMessageSpy().spyMessage(requestContext, MessageSpy.STATISTIC_GROUP.TO_SWITCH_SUBMIT_FAILURE); - } + ListenableFuture> listenableBarrierOutputOFJava = JdkFutureAdapters + .listenInPoolThread(barrierOutputOFJava); - //callback on request context future - Futures.addCallback(sendBarrierOutput, new FutureCallback>() { + // callback on OF JAVA future + SuccessCallback successCallback = new SuccessCallback( + deviceContext, requestContext, listenableBarrierOutputOFJava) { @Override - public void onSuccess(RpcResult result) { + public RpcResult transform(final RpcResult rpcResult) { + //no transformation, because output for request context is Void + LOG.debug("Barrier reply with xid {} was obtained by controller.", rpcResult.getResult().getXid()); + return RpcResultBuilder.success().build(); } + }; + Futures.addCallback(listenableBarrierOutputOFJava, successCallback); - @Override - public void onFailure(Throwable t) { - if (sendBarrierOutput.isCancelled()) { - requestContext.getFuture().set( - RpcResultBuilder.failed() - .withError(ErrorType.APPLICATION, "Barrier response wasn't obtained until barrier.") - .build()); - LOG.debug("Barrier reply with xid {} wasn't obtained by controller.", requestContext.getXid()); - - } - } - }); - - return sendBarrierOutput; - + return requestContext.getFuture(); } - } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/NodeConfigServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/NodeConfigServiceImpl.java index 9d9a84e7b7..c7adfc5fa0 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/NodeConfigServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/NodeConfigServiceImpl.java @@ -9,7 +9,6 @@ package org.opendaylight.openflowplugin.impl.services; 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 org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; @@ -22,48 +21,41 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev13 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInputBuilder; import org.opendaylight.yangtools.yang.common.RpcResult; -/** - * @author joe - */ public class NodeConfigServiceImpl extends CommonService implements NodeConfigService { - private final RequestContextStack requestContextStack; + // FIXME: should be only in CommonService private final DeviceContext deviceContext; public NodeConfigServiceImpl(final RequestContextStack requestContextStack, final DeviceContext deviceContext) { super(requestContextStack, deviceContext); - this.requestContextStack = requestContextStack; this.deviceContext = deviceContext; } - @Override public Future> setConfig(final SetConfigInput input) { - final RequestContext requestContext = requestContextStack.createRequestContext(); - final SettableFuture> result = requestContextStack.storeOrFail(requestContext); - if (!result.isDone()) { - SetConfigInputBuilder builder = new SetConfigInputBuilder(); - SwitchConfigFlag flag = SwitchConfigFlag.valueOf(input.getFlag()); - final Long reserverXid = deviceContext.getReservedXid(); - if (null == reserverXid){ - RequestContextUtil.closeRequestContextWithRpcError(requestContext, "Outbound queue wasn't able to reserve XID."); - return result; - } + final RequestContext requestContext = createRequestContext(); + if (requestContext == null) { + return failedFuture(); + } + + SetConfigInputBuilder builder = new SetConfigInputBuilder(); + SwitchConfigFlag flag = SwitchConfigFlag.valueOf(input.getFlag()); + final Long reserverXid = deviceContext.getReservedXid(); + if (null == reserverXid) { + return RequestContextUtil.closeRequestContextWithRpcError(requestContext, "Outbound queue wasn't able to reserve XID."); + } - final Xid xid = new Xid(reserverXid); - builder.setXid(xid.getValue()); - builder.setFlags(flag); - builder.setMissSendLen(input.getMissSearchLength()); - builder.setVersion(getVersion()); - ListenableFuture> futureResultFromOfLib; - synchronized (deviceContext) { - futureResultFromOfLib = JdkFutureAdapters.listenInPoolThread(deviceContext.getPrimaryConnectionContext().getConnectionAdapter().setConfig(builder.build())); - } - OFJResult2RequestCtxFuture OFJResult2RequestCtxFuture = new OFJResult2RequestCtxFuture<>(requestContext, deviceContext); - OFJResult2RequestCtxFuture.processResultFromOfJava(futureResultFromOfLib); - } else { - RequestContextUtil.closeRequstContext(requestContext); + final Xid xid = new Xid(reserverXid); + builder.setXid(xid.getValue()); + builder.setFlags(flag); + builder.setMissSendLen(input.getMissSearchLength()); + builder.setVersion(getVersion()); + ListenableFuture> futureResultFromOfLib; + synchronized (deviceContext) { + futureResultFromOfLib = JdkFutureAdapters.listenInPoolThread(deviceContext.getPrimaryConnectionContext().getConnectionAdapter().setConfig(builder.build())); } - return result; + OFJResult2RequestCtxFuture OFJResult2RequestCtxFuture = new OFJResult2RequestCtxFuture<>(requestContext, deviceContext); + OFJResult2RequestCtxFuture.processResultFromOfJava(futureResultFromOfLib); + return requestContext.getFuture(); } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/RequestContextUtil.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/RequestContextUtil.java index 05d45d25b6..fb9969e468 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/RequestContextUtil.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/RequestContextUtil.java @@ -7,8 +7,10 @@ */ package org.opendaylight.openflowplugin.impl.services; +import com.google.common.util.concurrent.SettableFuture; import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; 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; @@ -21,11 +23,11 @@ public final class RequestContextUtil { } - public static void closeRequestContextWithRpcError(final RequestContext requestContext, String errorMessage) { - - RpcResultBuilder rpcResultBuilder = RpcResultBuilder.failed().withRpcError(RpcResultBuilder.newError(RpcError.ErrorType.APPLICATION, "", errorMessage)); + public static SettableFuture> closeRequestContextWithRpcError(final RequestContext requestContext, final String errorMessage) { + RpcResultBuilder rpcResultBuilder = RpcResultBuilder.failed().withRpcError(RpcResultBuilder.newError(RpcError.ErrorType.APPLICATION, "", errorMessage)); requestContext.getFuture().set(rpcResultBuilder.build()); closeRequstContext(requestContext); + return requestContext.getFuture(); } public static void closeRequstContext(final RequestContext requestContext) { diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalEchoServiceImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalEchoServiceImpl.java index 616c40550a..c168b4e18a 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalEchoServiceImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/SalEchoServiceImpl.java @@ -7,11 +7,9 @@ */ package org.opendaylight.openflowplugin.impl.services; -import com.google.common.util.concurrent.FutureCallback; 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 org.opendaylight.openflowplugin.api.openflow.device.DeviceContext; import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; @@ -26,7 +24,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.echo.service.rev150305.Send 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; @@ -43,77 +40,54 @@ public class SalEchoServiceImpl extends CommonService implements SalEchoService @Override public Future> sendEcho(final SendEchoInput sendEchoInput) { final RequestContext requestContext = getRequestContextStack().createRequestContext(); - final SettableFuture> 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); + if (requestContext == null) { + getMessageSpy().spyMessage(null, MessageSpy.STATISTIC_GROUP.TO_SWITCH_SUBMIT_FAILURE); + return failedFuture(); + } - final EchoInputBuilder echoInputOFJavaBuilder = new EchoInputBuilder(); - echoInputOFJavaBuilder.setVersion(getVersion()); - echoInputOFJavaBuilder.setXid(xid.getValue()); - echoInputOFJavaBuilder.setData(sendEchoInput.getData()); - final EchoInput echoInputOFJava = echoInputOFJavaBuilder.build(); - final Future> rpcEchoOutputOFJava = getPrimaryConnectionAdapter() - .echo(echoInputOFJava); - LOG.debug("Echo with xid {} was sent from controller", xid); + final DeviceContext deviceContext = getDeviceContext(); + Long reserverXid = deviceContext.getReservedXid(); + if (null == reserverXid) { + reserverXid = deviceContext.getReservedXid(); + return RequestContextUtil.closeRequestContextWithRpcError(requestContext, "Outbound queue wasn't able to reserve XID."); + } + final Xid xid = new Xid(reserverXid); + requestContext.setXid(xid); - ListenableFuture> 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 successCallback = new SuccessCallback( - deviceContext, requestContext, listenableRpcEchoOutputOFJava) { + final EchoInputBuilder echoInputOFJavaBuilder = new EchoInputBuilder(); + echoInputOFJavaBuilder.setVersion(getVersion()); + echoInputOFJavaBuilder.setXid(xid.getValue()); + echoInputOFJavaBuilder.setData(sendEchoInput.getData()); + final EchoInput echoInputOFJava = echoInputOFJavaBuilder.build(); - @Override - public RpcResult transform(RpcResult rpcResult) { - EchoOutput echoOutputOFJava = rpcResult.getResult(); - SendEchoOutputBuilder sendEchoOutputBuilder = new SendEchoOutputBuilder(); - sendEchoOutputBuilder.setData(echoOutputOFJava.getData()); + // FIXME: should be submitted via OutboundQueue + final Future> rpcEchoOutputOFJava = getPrimaryConnectionAdapter() + .echo(echoInputOFJava); + LOG.debug("Echo with xid {} was sent from controller", xid); - 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); - } + ListenableFuture> listenableRpcEchoOutputOFJava = JdkFutureAdapters + .listenInPoolThread(rpcEchoOutputOFJava); - // callback on request context future - Futures.addCallback(sendEchoOutput, new FutureCallback>() { + // callback on OF JAVA future + SuccessCallback successCallback = new SuccessCallback( + deviceContext, requestContext, listenableRpcEchoOutputOFJava) { @Override - public void onSuccess(RpcResult result) { - } + public RpcResult transform(final RpcResult 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.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(); } - } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java index 7be9e11d1f..27ee72b5cd 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/StatisticsContextImpl.java @@ -21,11 +21,10 @@ 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.statistics.StatisticsContext; -import org.opendaylight.openflowplugin.impl.rpc.RequestContextImpl; +import org.opendaylight.openflowplugin.impl.rpc.AbstractRequestContext; import org.opendaylight.openflowplugin.impl.services.RequestContextUtil; import org.opendaylight.openflowplugin.impl.statistics.services.dedicated.StatisticsGatheringService; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.MultipartType; -import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,17 +34,15 @@ import org.slf4j.LoggerFactory; public class StatisticsContextImpl implements StatisticsContext { private static final Logger LOG = LoggerFactory.getLogger(StatisticsContextImpl.class); - public static final String CONNECTION_CLOSED = "Connection closed."; + private static final String CONNECTION_CLOSED = "Connection closed."; private final Collection> requestContexts = new HashSet<>(); private final DeviceContext deviceContext; - private final StatisticsGatheringService statisticsGatheringService; public StatisticsContextImpl(final DeviceContext deviceContext) { this.deviceContext = deviceContext; statisticsGatheringService = new StatisticsGatheringService(this, deviceContext); - } @Override @@ -104,25 +101,21 @@ public class StatisticsContextImpl implements StatisticsContext { return resultingFuture; } - @Override - public void forgetRequestContext(final RequestContext requestContext) { - requestContexts.remove(requestContext); - } - - @Override - public SettableFuture> storeOrFail(final RequestContext data) { - requestContexts.add(data); - return data.getFuture(); - } - @Override public RequestContext createRequestContext() { - return new RequestContextImpl<>(this); + final AbstractRequestContext ret = new AbstractRequestContext() { + @Override + public void close() { + requestContexts.remove(this); + } + }; + requestContexts.add(ret); + return ret; } @Override - public void close() throws Exception { - for (final RequestContext requestContext : requestContexts) { + public void close() { + for (final RequestContext requestContext : requestContexts) { RequestContextUtil.closeRequestContextWithRpcError(requestContext, CONNECTION_CLOSED); } } diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/api/openflow/device/RpcContextImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/api/openflow/device/RpcContextImplTest.java index 252a80d9d0..cccb2137cf 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/api/openflow/device/RpcContextImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/api/openflow/device/RpcContextImplTest.java @@ -7,13 +7,8 @@ */ package org.opendaylight.openflowplugin.api.openflow.device; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.util.Iterator; -import java.util.concurrent.Future; +import static org.junit.Assert.assertNull; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -23,15 +18,12 @@ import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy; import org.opendaylight.openflowplugin.impl.rpc.RpcContextImpl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; -import org.opendaylight.yangtools.yang.common.RpcError; -import org.opendaylight.yangtools.yang.common.RpcResult; /** * @author joe @@ -47,16 +39,12 @@ public class RpcContextImplTest { @Mock private MessageSpy messageSpy; - private RpcContext rpcContext; - - private static final String QUEUE_IS_FULL = "Device's request queue is full."; + private KeyedInstanceIdentifier nodeInstanceIdentifier; @Before public void setup() { NodeId nodeId = new NodeId("openflow:1"); - KeyedInstanceIdentifier nodeInstanceIdentifier = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(nodeId)); - - rpcContext = new RpcContextImpl(messageSpy, mockedRpcProviderRegistry, nodeInstanceIdentifier); + nodeInstanceIdentifier = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(nodeId)); } @Test @@ -66,25 +54,16 @@ public class RpcContextImplTest { @Test public void testStoreOrFail() throws Exception { + final RpcContext rpcContext = new RpcContextImpl(messageSpy, mockedRpcProviderRegistry, nodeInstanceIdentifier, 100); RequestContext requestContext = rpcContext.createRequestContext(); - rpcContext.setRequestContextQuota(100); - Future> resultFuture = rpcContext.storeOrFail(requestContext); - assertNotNull(resultFuture); - assertFalse(resultFuture.isDone()); + assertNotNull(requestContext); + } @Test public void testStoreOrFailThatFails() throws Exception { + final RpcContext rpcContext = new RpcContextImpl(messageSpy, mockedRpcProviderRegistry, nodeInstanceIdentifier, 0); RequestContext requestContext = rpcContext.createRequestContext(); - rpcContext.setRequestContextQuota(0); - Future> resultFuture = rpcContext.storeOrFail(requestContext); - assertNotNull(resultFuture); - assertTrue(resultFuture.isDone()); - RpcResult updateFlowOutputRpcResult = resultFuture.get(); - assertNotNull(updateFlowOutputRpcResult); - assertEquals(1, updateFlowOutputRpcResult.getErrors().size()); - Iterator iterator = updateFlowOutputRpcResult.getErrors().iterator(); - assertEquals(QUEUE_IS_FULL, iterator.next().getMessage()); + assertNull(requestContext); } - } 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 3cd4f4fb0d..3fea20faaf 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 @@ -96,9 +96,8 @@ public class RpcManagerImplTest { // TODO: how to invoke service remotely? NodeId nodeId = new NodeId("openflow:1"); KeyedInstanceIdentifier nodeInstanceIdentifier = InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(nodeId)); - final RpcContextImpl rpcContext = new RpcContextImpl(messageSpy, mockedProviderContext, nodeInstanceIdentifier); + final RpcContextImpl rpcContext = new RpcContextImpl(messageSpy, mockedProviderContext, nodeInstanceIdentifier, capacity); when(mockedProviderContext.getRpcService(SalFlowService.class)).thenReturn(new SalFlowServiceImpl(rpcContext, mockedDeviceContext)); - rpcContext.setRequestContextQuota(capacity); final SalFlowService salFlowService = mockedProviderContext.getRpcService(SalFlowService.class); final Future> addedFlow = salFlowService.addFlow(prepareTestingAddFlow()); diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/RequestContextImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/AbstractRequestContextTest.java similarity index 50% rename from openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/RequestContextImplTest.java rename to openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/AbstractRequestContextTest.java index ea2c4eb9e3..a791db22fa 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/RequestContextImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/rpc/AbstractRequestContextTest.java @@ -9,41 +9,29 @@ package org.opendaylight.openflowplugin.impl.rpc; import static org.junit.Assert.assertNotNull; -import static org.mockito.Mockito.verify; - -import com.google.common.util.concurrent.SettableFuture; +import java.util.concurrent.Future; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Matchers; -import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import org.opendaylight.openflowplugin.api.openflow.device.RequestContext; -import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext; @RunWith(MockitoJUnitRunner.class) -public class RequestContextImplTest { - - @Mock - RpcContext rpcContext; - - RequestContext requestContext; +public class AbstractRequestContextTest { + private AbstractRequestContext requestContext; @Before public void setup() { - requestContext = new RequestContextImpl<>(rpcContext); + requestContext = new AbstractRequestContext() { + @Override + public void close() { + // No-op + } + }; } @Test public void testCreateRequestFuture() throws Exception { - SettableFuture future = requestContext.getFuture(); + Future future = requestContext.getFuture(); assertNotNull(future); } - - @Test - public void testClose() throws Exception { - requestContext.close(); - verify(rpcContext).forgetRequestContext(Matchers.any(RequestContext.class)); - } - } \ No newline at end of file