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.controller.md.sal.dom.broker.impl;
10 import com.google.common.annotations.VisibleForTesting;
11 import com.google.common.collect.ImmutableSet;
12 import com.google.common.util.concurrent.CheckedFuture;
13 import java.util.Collection;
14 import java.util.Collections;
17 import java.util.WeakHashMap;
18 import java.util.stream.Collectors;
19 import org.opendaylight.controller.md.sal.dom.api.DOMRpcAvailabilityListener;
20 import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
21 import org.opendaylight.controller.md.sal.dom.api.DOMRpcIdentifier;
22 import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementation;
23 import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationRegistration;
24 import org.opendaylight.controller.md.sal.dom.api.DOMRpcProviderService;
25 import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
26 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
27 import org.opendaylight.controller.md.sal.dom.spi.AbstractDOMRpcImplementationRegistration;
28 import org.opendaylight.controller.sal.core.compat.LegacyDOMRpcResultFutureAdapter;
29 import org.opendaylight.controller.sal.core.compat.MdsalDOMRpcResultFutureAdapter;
30 import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
31 import org.opendaylight.yangtools.concepts.ListenerRegistration;
32 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
33 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
34 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
35 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
37 public final class DOMRpcRouter implements AutoCloseable, DOMRpcService, DOMRpcProviderService, SchemaContextListener {
38 // This mapping is used to translate mdsal DOMRpcImplementations to their corresponding legacy
39 // DOMRpcImplementations registered thru this interface when invoking a DOMRpcAvailabilityListener.
40 private final Map<org.opendaylight.mdsal.dom.api.DOMRpcImplementation, DOMRpcImplementation> implMapping =
41 Collections.synchronizedMap(new WeakHashMap<>());
43 private final org.opendaylight.mdsal.dom.api.DOMRpcService delegateRpcService;
44 private final org.opendaylight.mdsal.dom.api.DOMRpcProviderService delegateRpcProviderService;
47 public DOMRpcRouter() {
48 org.opendaylight.mdsal.dom.broker.DOMRpcRouter delegate = new org.opendaylight.mdsal.dom.broker.DOMRpcRouter();
49 this.delegateRpcService = delegate.getRpcService();
50 this.delegateRpcProviderService = delegate.getRpcProviderService();
53 public DOMRpcRouter(final org.opendaylight.mdsal.dom.api.DOMRpcService delegateRpcService,
54 final org.opendaylight.mdsal.dom.api.DOMRpcProviderService delegateRpcProviderService) {
55 this.delegateRpcService = delegateRpcService;
56 this.delegateRpcProviderService = delegateRpcProviderService;
60 public <T extends DOMRpcImplementation> DOMRpcImplementationRegistration<T> registerRpcImplementation(
61 final T implementation, final DOMRpcIdentifier... rpcs) {
62 return registerRpcImplementation(implementation, ImmutableSet.copyOf(rpcs));
66 public synchronized <T extends DOMRpcImplementation> DOMRpcImplementationRegistration<T> registerRpcImplementation(
67 final T implementation, final Set<DOMRpcIdentifier> rpcs) {
68 org.opendaylight.mdsal.dom.api.DOMRpcImplementation delegateImpl =
69 new org.opendaylight.mdsal.dom.api.DOMRpcImplementation() {
71 public CheckedFuture<org.opendaylight.mdsal.dom.api.DOMRpcResult,
72 org.opendaylight.mdsal.dom.api.DOMRpcException> invokeRpc(
73 org.opendaylight.mdsal.dom.api.DOMRpcIdentifier rpc, NormalizedNode<?, ?> input) {
74 return new MdsalDOMRpcResultFutureAdapter(implementation.invokeRpc(convert(rpc), input));
78 public long invocationCost() {
79 return implementation.invocationCost();
83 implMapping.put(delegateImpl, implementation);
85 final org.opendaylight.mdsal.dom.api.DOMRpcImplementationRegistration
86 <org.opendaylight.mdsal.dom.api.DOMRpcImplementation> reg = delegateRpcProviderService
87 .registerRpcImplementation(delegateImpl,
88 rpcs.stream().map(DOMRpcRouter::convert).collect(Collectors.toSet()));
90 return new AbstractDOMRpcImplementationRegistration<T>(implementation) {
92 protected void removeRegistration() {
94 implMapping.remove(delegateImpl);
99 private static org.opendaylight.mdsal.dom.api.DOMRpcIdentifier convert(DOMRpcIdentifier from) {
100 return org.opendaylight.mdsal.dom.api.DOMRpcIdentifier.create(from.getType(), from.getContextReference());
103 private static DOMRpcIdentifier convert(org.opendaylight.mdsal.dom.api.DOMRpcIdentifier from) {
104 return DOMRpcIdentifier.create(from.getType(), from.getContextReference());
107 private static Collection<DOMRpcIdentifier> convert(
108 Collection<org.opendaylight.mdsal.dom.api.DOMRpcIdentifier> from) {
109 return from.stream().map(DOMRpcRouter::convert).collect(Collectors.toList());
113 public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(final SchemaPath type,
114 final NormalizedNode<?, ?> input) {
115 final CheckedFuture<org.opendaylight.mdsal.dom.api.DOMRpcResult, org.opendaylight.mdsal.dom.api.DOMRpcException>
116 future = delegateRpcService.invokeRpc(type, input);
117 return future instanceof MdsalDOMRpcResultFutureAdapter ? ((MdsalDOMRpcResultFutureAdapter)future).delegate()
118 : new LegacyDOMRpcResultFutureAdapter(future);
122 public synchronized <T extends DOMRpcAvailabilityListener> ListenerRegistration<T> registerRpcListener(
124 final ListenerRegistration<org.opendaylight.mdsal.dom.api.DOMRpcAvailabilityListener> reg =
125 delegateRpcService.registerRpcListener(new org.opendaylight.mdsal.dom.api.DOMRpcAvailabilityListener() {
127 public void onRpcAvailable(Collection<org.opendaylight.mdsal.dom.api.DOMRpcIdentifier> rpcs) {
128 listener.onRpcAvailable(convert(rpcs));
132 public void onRpcUnavailable(Collection<org.opendaylight.mdsal.dom.api.DOMRpcIdentifier> rpcs) {
133 listener.onRpcUnavailable(convert(rpcs));
137 public boolean acceptsImplementation(final org.opendaylight.mdsal.dom.api.DOMRpcImplementation impl) {
138 // If the DOMRpcImplementation wasn't registered thru this interface then the mapping won't be
139 // present - in this we can't call the listener so just assume acceptance which is the default
140 // behavior. This should be fine since a legacy listener would not be aware of implementation types
141 // registered via the new mdsal API.
142 final DOMRpcImplementation legacyImpl = implMapping.get(impl);
143 return legacyImpl != null ? listener.acceptsImplementation(legacyImpl) : true;
147 return new AbstractListenerRegistration<T>(listener) {
149 protected void removeRegistration() {
156 public void close() {
161 public void onGlobalContextUpdated(final SchemaContext context) {
162 if (delegateRpcService instanceof SchemaContextListener) {
163 ((SchemaContextListener)delegateRpcService).onGlobalContextUpdated(context);