2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.yang.binding.util;
10 import com.google.common.base.Preconditions;
11 import com.google.common.cache.CacheBuilder;
12 import com.google.common.cache.CacheLoader;
13 import com.google.common.cache.LoadingCache;
14 import com.google.common.collect.ImmutableMap;
15 import com.google.common.collect.ImmutableMap.Builder;
16 import java.lang.reflect.Method;
18 import java.util.concurrent.Future;
19 import javax.annotation.Nonnull;
20 import javax.annotation.Nullable;
21 import org.opendaylight.yangtools.yang.binding.BindingMapping;
22 import org.opendaylight.yangtools.yang.binding.DataObject;
23 import org.opendaylight.yangtools.yang.binding.RpcService;
24 import org.opendaylight.yangtools.yang.common.QName;
25 import org.opendaylight.yangtools.yang.common.RpcResult;
28 * Provides single method invocation of RPCs on supplied instance.
30 * Rpc Service invoker provides common invocation interface for any subtype of {@link RpcService}.
31 * via {@link #invokeRpc(RpcService, QName, DataObject)} method.
36 public final class RpcServiceInvoker {
38 private static final LoadingCache<Class<? extends RpcService>, RpcServiceInvoker> INVOKERS = CacheBuilder.newBuilder()
40 .build(new CacheLoader<Class<? extends RpcService>, RpcServiceInvoker>() {
43 public RpcServiceInvoker load(Class<? extends RpcService> key) throws Exception {
44 return createInvoker(key);
49 private final Map<String, RpcMethodInvoker> methodInvokers;
51 private RpcServiceInvoker(Map<String, RpcMethodInvoker> methodInvokers) {
52 this.methodInvokers = Preconditions.checkNotNull(methodInvokers);
57 * Creates RPCServiceInvoker for specified RpcService type
59 * @param type RpcService interface, which was generated from model.
60 * @return Cached instance of {@link RpcServiceInvoker} for supplied RPC type.
63 public static RpcServiceInvoker from(Class<? extends RpcService> type) {
64 Preconditions.checkArgument(type.isInterface());
65 Preconditions.checkArgument(BindingReflections.isBindingClass(type));
66 return INVOKERS.getUnchecked(type);
70 * Invokes supplied RPC on provided implementation of RPC Service.
72 * @param impl Imlementation on which RPC should be invoked.
73 * @param rpcName Name of RPC to be invoked.
74 * @param input Input data for RPC.
75 * @return Future which will complete once rpc procesing is finished.
77 public Future<RpcResult<?>> invokeRpc(@Nonnull RpcService impl, @Nonnull QName rpcName,@Nullable DataObject input ) {
78 Preconditions.checkNotNull(impl, "implemetation must be supplied");
79 return invoke(impl,BindingMapping.getMethodName(rpcName),input);
82 private static RpcServiceInvoker createInvoker(Class<? extends RpcService> key) {
83 return new RpcServiceInvoker(createInvokerMap(key));
86 private static Map<String, RpcMethodInvoker> createInvokerMap(Class<? extends RpcService> key) {
87 Builder<String, RpcMethodInvoker> ret = ImmutableMap.<String, RpcMethodInvoker>builder();
88 for(Method method : key.getMethods()) {
89 if(BindingReflections.isRpcMethod(method)) {
90 ret.put(method.getName(), RpcMethodInvoker.from(method));
97 private Future<RpcResult<?>> invoke(RpcService impl, String methodName, DataObject input) {
98 RpcMethodInvoker invoker = methodInvokers.get(methodName);
99 Preconditions.checkArgument(invoker != null,"Supplied rpc is not valid for implementation %s",impl);
100 return invoker.invokeOn(impl, input);