+ static final class OperationInvocation {
+ private static final Logger LOG = LoggerFactory.getLogger(OperationInvocation.class);
+
+ static ListenableFuture<? extends DOMActionResult> invoke(final DOMActionRoutingTableEntry entry,
+ final Absolute type, final DOMDataTreeIdentifier path, final ContainerNode input) {
+ List<DOMActionImplementation> impls = entry.getImplementations(path);
+ if (impls == null) {
+ impls = entry.getImplementations(
+ new DOMDataTreeIdentifier(path.getDatastoreType(), YangInstanceIdentifier.empty()));
+ if (impls == null) {
+ return Futures.immediateFailedFuture(new DOMActionNotAvailableException(
+ "No implementation of Action %s available for %s", type, path));
+ }
+ }
+
+ return impls.get(0).invokeAction(type, path, input);
+ }
+
+ static ListenableFuture<? extends DOMRpcResult> invoke(final AbstractDOMRpcRoutingTableEntry entry,
+ final NormalizedNode input) {
+ if (entry instanceof UnknownDOMRpcRoutingTableEntry) {
+ return Futures.immediateFailedFuture(
+ new DOMRpcImplementationNotAvailableException("%s is not resolved to an RPC", entry.getType()));
+ } else if (entry instanceof RoutedDOMRpcRoutingTableEntry) {
+ return invokeRoutedRpc((RoutedDOMRpcRoutingTableEntry) entry, input);
+ } else if (entry instanceof GlobalDOMRpcRoutingTableEntry) {
+ return invokeGlobalRpc((GlobalDOMRpcRoutingTableEntry) entry, input);
+ }
+
+ return Futures.immediateFailedFuture(
+ new DOMRpcImplementationNotAvailableException("Unsupported RPC entry."));
+ }
+
+ private static ListenableFuture<? extends 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.body();
+ 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.getType(), 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.getType(), 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 Futures.immediateFailedFuture(
+ new DOMRpcImplementationNotAvailableException("No implementation of RPC %s available",
+ entry.getType()));
+ }
+
+ private static ListenableFuture<? extends DOMRpcResult> invokeGlobalRpc(
+ final GlobalDOMRpcRoutingTableEntry entry, final NormalizedNode input) {
+ return entry.getImplementations(YangInstanceIdentifier.empty()).get(0).invokeRpc(entry.getRpcId(), input);
+ }
+ }