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 org.eclipse.jdt.annotation.NonNull;
16 import org.opendaylight.mdsal.dom.api.DOMRpcAvailabilityListener;
17 import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
18 import org.opendaylight.mdsal.dom.api.DOMRpcResult;
19 import org.opendaylight.mdsal.dom.api.DOMRpcService;
20 import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult;
21 import org.opendaylight.netconf.api.NetconfMessage;
22 import org.opendaylight.netconf.sal.connect.api.MessageTransformer;
23 import org.opendaylight.netconf.sal.connect.api.RemoteDeviceCommunicator;
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.netconf.sal.connect.util.RemoteDeviceId;
28 import org.opendaylight.yangtools.concepts.ListenerRegistration;
29 import org.opendaylight.yangtools.yang.common.RpcResult;
30 import org.opendaylight.yangtools.yang.data.api.schema.DOMSourceAnyxmlNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
32 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
35 * Invokes RPC by sending netconf message via listener. Also transforms result from NetconfMessage to CompositeNode.
37 public final class SchemalessNetconfDeviceRpc implements DOMRpcService {
39 private final RemoteDeviceCommunicator<NetconfMessage> listener;
40 private final BaseRpcSchemalessTransformer baseRpcTransformer;
41 private final SchemalessMessageTransformer schemalessTransformer;
42 private final RemoteDeviceId deviceId;
44 public SchemalessNetconfDeviceRpc(final RemoteDeviceId deviceId,
45 final RemoteDeviceCommunicator<NetconfMessage> listener,
46 final BaseRpcSchemalessTransformer baseRpcTransformer,
47 final SchemalessMessageTransformer messageTransformer) {
48 this.deviceId = deviceId;
49 this.listener = listener;
50 this.baseRpcTransformer = baseRpcTransformer;
51 this.schemalessTransformer = messageTransformer;
55 public ListenableFuture<DOMRpcResult> invokeRpc(final SchemaPath type, final NormalizedNode<?, ?> input) {
56 final MessageTransformer<NetconfMessage> transformer;
57 if (input instanceof DOMSourceAnyxmlNode) {
58 transformer = schemalessTransformer;
59 } else if (isBaseRpc(type)) {
60 transformer = baseRpcTransformer;
62 return Futures.immediateFailedFuture(new DOMRpcImplementationNotAvailableException(
63 "Unable to invoke rpc %s", type));
65 return handleRpc(type, input, transformer);
68 private ListenableFuture<DOMRpcResult> handleRpc(
69 final @NonNull SchemaPath type, final @NonNull NormalizedNode<?, ?> input,
70 final MessageTransformer<NetconfMessage> transformer) {
71 final ListenableFuture<RpcResult<NetconfMessage>> delegateFuture = listener.sendRequest(
72 transformer.toRpcRequest(type, input), type.getLastComponent());
74 final SettableFuture<DOMRpcResult> ret = SettableFuture.create();
75 Futures.addCallback(delegateFuture, new FutureCallback<RpcResult<NetconfMessage>>() {
77 public void onSuccess(final RpcResult<NetconfMessage> result) {
78 ret.set(result.isSuccessful() ? transformer.toRpcResult(result.getResult(), type)
79 : new DefaultDOMRpcResult(result.getErrors()));
83 public void onFailure(final Throwable cause) {
84 ret.setException(new DOMRpcImplementationNotAvailableException(cause,
85 "Unable to invoke rpc %s on device %s", type, deviceId));
88 }, MoreExecutors.directExecutor());
92 private static boolean isBaseRpc(final SchemaPath type) {
93 return NetconfMessageTransformUtil.NETCONF_URI.equals(type.getLastComponent().getNamespace());
97 public <T extends DOMRpcAvailabilityListener> ListenerRegistration<T> registerRpcListener(final T lsnr) {
98 throw new UnsupportedOperationException("Not available for netconf 1.0");