56c7270b6b101481fa932cc11cd6789fb0653645
[openflowplugin.git] / openflowplugin-impl / src / main / java / org / opendaylight / openflowplugin / impl / rpc / RpcContextImpl.java
1 /**
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.openflowplugin.impl.rpc;
9
10 import com.google.common.util.concurrent.SettableFuture;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.List;
14 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration;
15 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
16 import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionContext;
17 import org.opendaylight.openflowplugin.api.openflow.device.RequestContext;
18 import org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeContext;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
22 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
23 import org.opendaylight.yangtools.yang.binding.RpcService;
24 import org.opendaylight.yangtools.yang.common.RpcError;
25 import org.opendaylight.yangtools.yang.common.RpcResult;
26 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
27 import org.slf4j.Logger;
28
29 public class RpcContextImpl implements RpcContext {
30
31     private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(RpcContextImpl.class);
32     final RpcProviderRegistry rpcProviderRegistry;
33
34     // TODO: add private Sal salBroker
35     private final KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier;
36     private final List<RoutedRpcRegistration> rpcRegistrations = new ArrayList<>();
37     private final List<RequestContext<?>> synchronizedRequestsList = Collections
38             .<RequestContext<?>>synchronizedList(new ArrayList<RequestContext<?>>());
39
40     private int maxRequestsPerDevice;
41
42     public RpcContextImpl(final RpcProviderRegistry rpcProviderRegistry, final KeyedInstanceIdentifier<Node, NodeKey> nodeInstanceIdentifier) {
43         this.rpcProviderRegistry = rpcProviderRegistry;
44         this.nodeInstanceIdentifier = nodeInstanceIdentifier;
45     }
46
47     /**
48      * @see org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext#registerRpcServiceImplementation(java.lang.Class,
49      * org.opendaylight.yangtools.yang.binding.RpcService)
50      */
51     @Override
52     public <S extends RpcService> void registerRpcServiceImplementation(final Class<S> serviceClass,
53                                                                         final S serviceInstance) {
54         final RoutedRpcRegistration<S> routedRpcReg = rpcProviderRegistry.addRoutedRpcImplementation(serviceClass, serviceInstance);
55         routedRpcReg.registerPath(NodeContext.class, nodeInstanceIdentifier);
56         rpcRegistrations.add(routedRpcReg);
57         LOG.debug("Registration of service {} for device {}.",serviceClass, nodeInstanceIdentifier);
58     }
59
60     @Override
61     public <T> SettableFuture<RpcResult<T>> storeOrFail(final RequestContext<T> requestContext) {
62         final SettableFuture<RpcResult<T>> rpcResultFuture = requestContext.getFuture();
63
64         if (synchronizedRequestsList.size() < maxRequestsPerDevice) {
65             synchronizedRequestsList.add(requestContext);
66         } else {
67             final RpcResult<T> rpcResult = RpcResultBuilder.<T>failed()
68                     .withError(RpcError.ErrorType.APPLICATION, "", "Device's request queue is full.").build();
69             rpcResultFuture.set(rpcResult);
70         }
71         return rpcResultFuture;
72     }
73
74     /**
75      * Unregisters all services.
76      *
77      * @see java.lang.AutoCloseable#close()
78      */
79     @Override
80     public void close() throws Exception {
81         for (final RoutedRpcRegistration<?> rpcRegistration : rpcRegistrations) {
82             rpcRegistration.unregisterPath(NodeContext.class, nodeInstanceIdentifier);
83             rpcRegistration.close();
84         }
85     }
86
87     /**
88      * @see org.opendaylight.openflowplugin.api.openflow.rpc.RpcContext#setRequestContextQuota(int)
89      */
90     @Override
91     public void setRequestContextQuota(final int maxRequestsPerDevice) {
92         this.maxRequestsPerDevice = maxRequestsPerDevice;
93     }
94
95     @Override
96     public <T> void forgetRequestContext(final RequestContext<T> requestContext) {
97         synchronizedRequestsList.remove(requestContext);
98         LOG.trace("Removed request context with xid {}. Context request in list {}.",
99                 requestContext.getXid().getValue(), synchronizedRequestsList.size());
100     }
101
102
103     @Override
104     public <T> RequestContext<T> createRequestContext() {
105         return new RequestContextImpl<T>(this);
106     }
107
108     public boolean isRequestContextCapacityEmpty() {
109         return synchronizedRequestsList.size() <= maxRequestsPerDevice;
110     }
111
112     @Override
113     public void onDeviceDisconnected(final ConnectionContext connectionContext) {
114         for (RoutedRpcRegistration registration : rpcRegistrations) {
115             registration.close();
116         }
117
118         synchronizedRequestsList.clear();
119     }
120 }