2 * Copyright (c) 2016 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.netconf.sal.connect.netconf.sal;
10 import com.google.common.util.concurrent.FutureCallback;
11 import com.google.common.util.concurrent.Futures;
12 import com.google.common.util.concurrent.ListenableFuture;
13 import com.google.common.util.concurrent.MoreExecutors;
14 import com.google.common.util.concurrent.SettableFuture;
15 import javax.xml.transform.dom.DOMSource;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
18 import org.opendaylight.mdsal.dom.api.DOMRpcResult;
19 import org.opendaylight.netconf.api.NetconfMessage;
20 import org.opendaylight.netconf.sal.connect.api.RemoteDeviceCommunicator;
21 import org.opendaylight.netconf.sal.connect.api.RemoteDeviceId;
22 import org.opendaylight.netconf.sal.connect.api.RemoteDeviceServices.Rpcs;
23 import org.opendaylight.netconf.sal.connect.api.RpcTransformer;
24 import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.BaseRpcSchemalessTransformer;
25 import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.SchemalessMessageTransformer;
26 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
27 import org.opendaylight.yangtools.yang.common.QName;
28 import org.opendaylight.yangtools.yang.common.RpcResult;
29 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
32 * Invokes RPC by sending netconf message via listener. Also transforms result from NetconfMessage to CompositeNode.
34 public final class SchemalessNetconfDeviceRpc implements Rpcs.Schemaless {
35 private final RemoteDeviceCommunicator listener;
36 private final BaseRpcSchemalessTransformer baseRpcTransformer;
37 private final SchemalessMessageTransformer schemalessTransformer;
38 private final RemoteDeviceId deviceId;
40 public SchemalessNetconfDeviceRpc(final RemoteDeviceId deviceId, final RemoteDeviceCommunicator listener,
41 final BaseRpcSchemalessTransformer baseRpcTransformer,
42 final SchemalessMessageTransformer messageTransformer) {
43 this.deviceId = deviceId;
44 this.listener = listener;
45 this.baseRpcTransformer = baseRpcTransformer;
46 schemalessTransformer = messageTransformer;
50 public ListenableFuture<? extends DOMRpcResult> invokeNetconf(final QName type, final ContainerNode input) {
51 if (!isBaseRpc(type)) {
52 throw new IllegalArgumentException("Cannot handle " + type);
54 return handleRpc(type, input, baseRpcTransformer);
58 public ListenableFuture<? extends DOMSource> invokeRpc(final QName type, final DOMSource input) {
59 return handleRpc(type, input, schemalessTransformer);
62 private @NonNull <I, R> ListenableFuture<R> handleRpc(final @NonNull QName type,
63 final @NonNull I input, final RpcTransformer<I, R> transformer) {
64 final var delegateFuture = listener.sendRequest(transformer.toRpcRequest(type, input), type);
65 final var ret = SettableFuture.<R>create();
66 Futures.addCallback(delegateFuture, new FutureCallback<>() {
68 public void onSuccess(final RpcResult<NetconfMessage> result) {
69 ret.set(transformer.toRpcResult(result, type));
73 public void onFailure(final Throwable cause) {
74 ret.setException(new DOMRpcImplementationNotAvailableException(cause,
75 "Unable to invoke rpc %s on device %s", type, deviceId));
78 }, MoreExecutors.directExecutor());
82 private static boolean isBaseRpc(final QName type) {
83 return NetconfMessageTransformUtil.NETCONF_URI.equals(type.getNamespace());