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 com.google.common.annotations.VisibleForTesting;
11 import com.google.common.collect.ClassToInstanceMap;
12 import com.google.common.collect.ImmutableClassToInstanceMap;
13 import com.google.common.collect.ImmutableMap;
14 import com.google.common.collect.ImmutableSet;
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import java.util.HashSet;
19 import org.opendaylight.mdsal.binding.api.RpcProviderService;
20 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
21 import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
22 import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
23 import org.opendaylight.mdsal.dom.api.DOMRpcProviderService;
24 import org.opendaylight.yangtools.concepts.ObjectRegistration;
25 import org.opendaylight.yangtools.concepts.Registration;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.opendaylight.yangtools.yang.binding.Rpc;
28 import org.opendaylight.yangtools.yang.binding.RpcService;
29 import org.opendaylight.yangtools.yang.common.QName;
30 import org.opendaylight.yangtools.yang.common.YangConstants;
31 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
34 public class BindingDOMRpcProviderServiceAdapter extends AbstractBindingAdapter<DOMRpcProviderService>
35 implements RpcProviderService {
36 private static final ImmutableSet<YangInstanceIdentifier> GLOBAL = ImmutableSet.of(YangInstanceIdentifier.empty());
38 public BindingDOMRpcProviderServiceAdapter(final AdapterContext adapterContext,
39 final DOMRpcProviderService domRpcRegistry) {
40 super(adapterContext, domRpcRegistry);
45 public <R extends RpcService, I extends R> ObjectRegistration<I> registerRpcImplementation(final Class<R> type,
46 final I implementation) {
47 return register(currentSerializer(), type, implementation, GLOBAL);
52 public <R extends RpcService, I extends R> ObjectRegistration<I> registerRpcImplementation(final Class<R> type,
53 final I implementation, final Set<InstanceIdentifier<?>> paths) {
54 final var serializer = currentSerializer();
55 return register(serializer, type, implementation, toYangInstanceIdentifiers(serializer, paths));
59 public Registration registerRpcImplementation(final Rpc<?, ?> implementation) {
60 return register(currentSerializer(), implementation, GLOBAL);
64 public Registration registerRpcImplementation(final Rpc<?, ?> implementation,
65 final Set<InstanceIdentifier<?>> paths) {
66 final var serializer = currentSerializer();
67 return register(serializer, implementation, toYangInstanceIdentifiers(serializer, paths));
71 public Registration registerRpcImplementations(final ClassToInstanceMap<Rpc<?, ?>> implementations) {
72 return register(currentSerializer(), implementations, GLOBAL);
76 public Registration registerRpcImplementations(final ClassToInstanceMap<Rpc<?, ?>> implementations,
77 final Set<InstanceIdentifier<?>> paths) {
78 final var serializer = currentSerializer();
79 return register(serializer, implementations, toYangInstanceIdentifiers(serializer, paths));
82 private <T extends Rpc<?, ?>> Registration register(final CurrentAdapterSerializer serializer,
83 final T implementation, final Collection<YangInstanceIdentifier> rpcContextPaths) {
84 @SuppressWarnings("unchecked")
85 final var type = (Class<T>) implementation.implementedInterface();
86 return register(serializer, ImmutableClassToInstanceMap.of(type, implementation), rpcContextPaths);
89 private Registration register(final CurrentAdapterSerializer serializer,
90 final ClassToInstanceMap<Rpc<?, ?>> implementations,
91 final Collection<YangInstanceIdentifier> rpcContextPaths) {
92 final var context = serializer.getRuntimeContext();
93 final var builder = ImmutableMap.<DOMRpcIdentifier, DOMRpcImplementation>builderWithExpectedSize(
94 implementations.size());
95 for (var entry : implementations.entrySet()) {
96 final var type = entry.getKey();
97 final var def = context.getRpcDefinition(type);
99 throw new IllegalArgumentException("Cannot resolve YANG definition of " + type);
101 final var name = def.statement().argument();
102 final var impl = new BindingDOMRpcImplementationAdapter(adapterContext(), entry.getValue(), name);
104 for (var id : createDomRpcIdentifiers(Set.of(name), rpcContextPaths)) {
105 builder.put(id, impl);
109 return getDelegate().registerRpcImplementations(builder.build());
113 private <S extends RpcService, T extends S> ObjectRegistration<T> register(
114 final CurrentAdapterSerializer serializer, final Class<S> type, final T implementation,
115 final Collection<YangInstanceIdentifier> rpcContextPaths) {
116 // FIXME: do not use BindingReflections here
117 final var inputName = YangConstants.operationInputQName(BindingReflections.getQNameModule(type)).intern();
118 final var methodHandles = currentSerializer().getRpcMethods(type);
119 final var builder = ImmutableMap.<DOMRpcIdentifier, DOMRpcImplementation>builderWithExpectedSize(
120 methodHandles.size());
121 for (var entry : methodHandles.entrySet()) {
122 final var impl = new LegacyDOMRpcImplementationAdapter(adapterContext(), inputName,
123 entry.getValue().bindTo(implementation));
124 for (var id : createDomRpcIdentifiers(Set.of(entry.getKey()), rpcContextPaths)) {
125 builder.put(id, impl);
129 return new BindingRpcAdapterRegistration<>(implementation,
130 getDelegate().registerRpcImplementations(builder.build()));
133 private static Set<DOMRpcIdentifier> createDomRpcIdentifiers(final Set<QName> rpcs,
134 final Collection<YangInstanceIdentifier> paths) {
135 final Set<DOMRpcIdentifier> ret = new HashSet<>();
136 for (final YangInstanceIdentifier path : paths) {
137 for (final QName rpc : rpcs) {
138 ret.add(DOMRpcIdentifier.create(rpc, path));
144 private static Collection<YangInstanceIdentifier> toYangInstanceIdentifiers(
145 final CurrentAdapterSerializer serializer, final Set<InstanceIdentifier<?>> identifiers) {
146 final var ret = new ArrayList<YangInstanceIdentifier>(identifiers.size());
147 for (final InstanceIdentifier<?> binding : identifiers) {
148 ret.add(serializer.toCachedYangInstanceIdentifier(binding));