Rehost BindingMapping in yang.binding.contract.Naming
[mdsal.git] / binding / mdsal-binding-dom-adapter / src / main / java / org / opendaylight / mdsal / binding / dom / adapter / RpcServiceAdapter.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.mdsal.binding.dom.adapter;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.collect.ImmutableMap;
13 import java.lang.reflect.Method;
14 import java.util.Map;
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;
23
24 @Deprecated
25 final class RpcServiceAdapter extends AbstractRpcAdapter {
26     private final ImmutableMap<Method, RpcInvocationStrategy> rpcNames;
27
28     RpcServiceAdapter(final Class<? extends RpcService> type, final AdapterContext adapterContext,
29             final DOMRpcService domService) {
30         super(adapterContext, domService, type);
31
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);
39
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)
44             .map(rpc -> {
45                 final var rpcName = rpc.argument();
46                 final var inputClz = runtimeContext.getRpcInput(rpcName);
47                 final var methodName = Naming.getRpcMethodName(rpcName);
48
49                 final Method method;
50                 try {
51                     method = type.getMethod(methodName, inputClz);
52                 } catch (NoSuchMethodException e) {
53                     throw new IllegalStateException("Cannot find RPC method for " + rpc, e);
54                 }
55
56                 final var runtimeType = types.schemaTreeChild(rpcName);
57                 if (!(runtimeType instanceof RpcRuntimeType rpcType)) {
58                     throw new IllegalStateException("Unexpected run-time type " + runtimeType + " for " + rpcName);
59                 }
60
61                 return Map.entry(method, createStrategy(serializer, rpcType));
62             })
63             .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue));
64     }
65
66     @Override
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);
71     }
72 }