2 * Copyright (c) 2015 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.mdsal.binding.dom.adapter;
10 import static java.util.Objects.requireNonNull;
12 import com.google.common.collect.ImmutableMap;
13 import java.lang.reflect.Method;
15 import java.util.Map.Entry;
16 import org.opendaylight.mdsal.binding.runtime.api.RpcRuntimeType;
17 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
18 import org.opendaylight.mdsal.dom.api.DOMRpcService;
19 import org.opendaylight.yangtools.yang.binding.RpcInput;
20 import org.opendaylight.yangtools.yang.binding.RpcService;
21 import org.opendaylight.yangtools.yang.binding.contract.Naming;
22 import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement;
25 final class RpcServiceAdapter extends AbstractRpcAdapter {
26 private final ImmutableMap<Method, RpcInvocationStrategy> rpcNames;
28 RpcServiceAdapter(final Class<? extends RpcService> type, final AdapterContext adapterContext,
29 final DOMRpcService domService) {
30 super(adapterContext, domService, type);
32 // FIXME: This should be probably part of BindingRuntimeContext and RpcServices perhaps should have their own
33 // RuntimeType. At any rate, we are dancing around to reconstruct information RpcServiceRuntimeType would
34 // carry and the runtime context would bind to actual classes.
35 final var serializer = adapterContext.currentSerializer();
36 final var runtimeContext = serializer.getRuntimeContext();
37 final var types = runtimeContext.getTypes();
38 final var qnameModule = BindingReflections.getQNameModule(type);
40 // We are dancing a bit here to reconstruct things a RpcServiceRuntimeType could easily hold
41 final var module = runtimeContext.getEffectiveModelContext().findModuleStatement(qnameModule)
42 .orElseThrow(() -> new IllegalStateException("No module found for " + qnameModule + " service " + type));
43 rpcNames = module.streamEffectiveSubstatements(RpcEffectiveStatement.class)
45 final var rpcName = rpc.argument();
46 final var inputClz = runtimeContext.getRpcInput(rpcName);
47 final var methodName = Naming.getRpcMethodName(rpcName);
51 method = type.getMethod(methodName, inputClz);
52 } catch (NoSuchMethodException e) {
53 throw new IllegalStateException("Cannot find RPC method for " + rpc, e);
56 final var runtimeType = types.schemaTreeChild(rpcName);
57 if (!(runtimeType instanceof RpcRuntimeType rpcType)) {
58 throw new IllegalStateException("Unexpected run-time type " + runtimeType + " for " + rpcName);
61 return Map.entry(method, createStrategy(serializer, rpcType));
63 .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue));
67 public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
68 final var strategy = rpcNames.get(method);
69 return strategy != null ? strategy.invoke((RpcInput) requireNonNull(args[0]))
70 : defaultInvoke(proxy, method, args);