+
+ static final class RpcInvocation {
+ private static final Logger LOG = LoggerFactory.getLogger(RpcInvocation.class);
+
+ static FluentFuture<DOMRpcResult> invoke(final AbstractDOMRpcRoutingTableEntry entry,
+ final NormalizedNode<?, ?> input) {
+ if (entry instanceof UnknownDOMRpcRoutingTableEntry) {
+ return FluentFutures.immediateFailedFluentFuture(
+ new DOMRpcImplementationNotAvailableException("SchemaPath %s is not resolved to an RPC",
+ entry.getSchemaPath()));
+ } else if (entry instanceof RoutedDOMRpcRoutingTableEntry) {
+ return invokeRoutedRpc((RoutedDOMRpcRoutingTableEntry) entry, input);
+ } else if (entry instanceof GlobalDOMRpcRoutingTableEntry) {
+ return invokeGlobalRpc((GlobalDOMRpcRoutingTableEntry) entry, input);
+ }
+
+ return FluentFutures.immediateFailedFluentFuture(
+ new DOMRpcImplementationNotAvailableException("Unsupported RPC entry."));
+ }
+
+ private static FluentFuture<DOMRpcResult> invokeRoutedRpc(final RoutedDOMRpcRoutingTableEntry entry,
+ final NormalizedNode<?, ?> input) {
+ final Optional<NormalizedNode<?, ?>> maybeKey = NormalizedNodes.findNode(input,
+ entry.getRpcId().getContextReference());
+
+ // Routing key is present, attempt to deliver as a routed RPC
+ if (maybeKey.isPresent()) {
+ final NormalizedNode<?, ?> key = maybeKey.get();
+ final Object value = key.getValue();
+ if (value instanceof YangInstanceIdentifier) {
+ final YangInstanceIdentifier iid = (YangInstanceIdentifier) value;
+
+ // Find a DOMRpcImplementation for a specific iid
+ final List<DOMRpcImplementation> specificImpls = entry.getImplementations(iid);
+ if (specificImpls != null) {
+ return specificImpls.get(0)
+ .invokeRpc(DOMRpcIdentifier.create(entry.getSchemaPath(), iid), input);
+ }
+
+ LOG.debug("No implementation for context {} found will now look for wildcard id", iid);
+
+ // Find a DOMRpcImplementation for a wild card. Usually remote-rpc-connector would register an
+ // implementation this way
+ final List<DOMRpcImplementation> mayBeRemoteImpls =
+ entry.getImplementations(YangInstanceIdentifier.EMPTY);
+
+ if (mayBeRemoteImpls != null) {
+ return mayBeRemoteImpls.get(0)
+ .invokeRpc(DOMRpcIdentifier.create(entry.getSchemaPath(), iid), input);
+ }
+
+ } else {
+ LOG.warn("Ignoring wrong context value {}", value);
+ }
+ }
+
+ final List<DOMRpcImplementation> impls = entry.getImplementations(null);
+ if (impls != null) {
+ return impls.get(0).invokeRpc(entry.getRpcId(), input);
+ }
+
+ return FluentFutures.immediateFailedFluentFuture(
+ new DOMRpcImplementationNotAvailableException("No implementation of RPC %s available",
+ entry.getSchemaPath()));
+ }
+
+ private static FluentFuture<DOMRpcResult> invokeGlobalRpc(final GlobalDOMRpcRoutingTableEntry entry,
+ final NormalizedNode<?, ?> input) {
+ return entry.getImplementations(YangInstanceIdentifier.EMPTY).get(0).invokeRpc(entry.getRpcId(), input);
+ }
+ }