Cleanup RequestContextStack
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / rpc / RpcContextImpl.java
index d971cdcafef4e713ca8b57514469ee27899539b5..ab39f92f3acd2e1f9e65e2beea69832dd3e86899 100644 (file)
@@ -1,83 +1,93 @@
 /**
  * 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.rpc;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Future;
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.concurrent.Semaphore;
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
-import org.opendaylight.openflowplugin.api.openflow.device.DeviceContext;
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
+import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
-import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeContext;
+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.KeyedInstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.RpcService;
-import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class RpcContextImpl implements RpcContext {
-
-    final ProviderContext providerContext;
+    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 List<RequestContext> requestContexts = new ArrayList<>();
-    private DeviceContext deviceContext;
-    private final List<RoutedRpcRegistration> rpcRegistrations = new ArrayList<>();
-
-    private int maxRequestsPerDevice;
+    private final KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier;
+    private final Collection<RoutedRpcRegistration<?>> rpcRegistrations = new HashSet<>();
 
-    public RpcContextImpl(final ProviderContext providerContext) {
-        this.providerContext = providerContext;
+    public RpcContextImpl(final MessageSpy messageSpy, final RpcProviderRegistry rpcProviderRegistry, final KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier, final int maxRequests) {
+        this.messageSpy = messageSpy;
+        this.rpcProviderRegistry = rpcProviderRegistry;
+        this.nodeInstanceIdentifier = nodeInstanceIdentifier;
+        tracker = new Semaphore(maxRequests, true);
     }
 
     /**
-     * 
      * @see org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext#registerRpcServiceImplementation(java.lang.Class,
-     *      org.opendaylight.yangtools.yang.binding.RpcService)
+     * org.opendaylight.yangtools.yang.binding.RpcService)
      */
     @Override
     public <S extends RpcService> void registerRpcServiceImplementation(final Class<S> serviceClass,
-            final S serviceInstance) {
-        rpcRegistrations.add(providerContext.addRoutedRpcImplementation(serviceClass, serviceInstance));
-    }
-
-    @Override
-    public Future<RpcResult<? extends DataObject>> addNewRequest(final DataObject data) {
-        return null;
+                                                                        final S serviceInstance) {
+        final RoutedRpcRegistration<S> routedRpcReg = rpcProviderRegistry.addRoutedRpcImplementation(serviceClass, serviceInstance);
+        routedRpcReg.registerPath(NodeContext.class, nodeInstanceIdentifier);
+        rpcRegistrations.add(routedRpcReg);
+        LOG.debug("Registration of service {} for device {}.", serviceClass, nodeInstanceIdentifier);
     }
 
     /**
      * Unregisters all services.
-     * 
+     *
      * @see java.lang.AutoCloseable#close()
      */
     @Override
-    public void close() throws Exception {
-        for (final RoutedRpcRegistration rpcRegistration : rpcRegistrations) {
+    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) {
+    public <T> RequestContext<T> createRequestContext() {
+        if (!tracker.tryAcquire()) {
+            LOG.trace("Device queue {} at capacity", this);
+            return null;
+        }
 
+        return new AbstractRequestContext<T>() {
+            @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);
+            }
+        };
     }
 
-    public boolean isRequestContextCapacityEmpty() {
-        return requestContexts.size() <= maxRequestsPerDevice;
+    @Override
+    public void onDeviceDisconnected(final ConnectionContext connectionContext) {
+        for (RoutedRpcRegistration<?> registration : rpcRegistrations) {
+            registration.close();
+        }
     }
-
-
 }