/* * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.netconf.sal.connect.netconf.sal; import static java.util.Objects.requireNonNull; import com.google.common.collect.Collections2; import com.google.common.util.concurrent.FluentFuture; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.SettableFuture; import javax.annotation.Nonnull; import org.opendaylight.mdsal.dom.api.DOMRpcAvailabilityListener; import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier; import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException; import org.opendaylight.mdsal.dom.api.DOMRpcResult; import org.opendaylight.mdsal.dom.api.DOMRpcService; import org.opendaylight.mdsal.dom.spi.DefaultDOMRpcResult; import org.opendaylight.netconf.api.NetconfMessage; import org.opendaylight.netconf.sal.connect.api.MessageTransformer; import org.opendaylight.netconf.sal.connect.api.RemoteDeviceCommunicator; import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.concepts.NoOpListenerRegistration; import org.opendaylight.yangtools.yang.common.RpcResult; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.model.api.SchemaPath; /** * Invokes RPC by sending netconf message via listener. Also transforms result from NetconfMessage to CompositeNode. */ public final class NetconfDeviceRpc implements DOMRpcService { private final RemoteDeviceCommunicator communicator; private final MessageTransformer transformer; private final SchemaContext schemaContext; public NetconfDeviceRpc(final SchemaContext schemaContext, final RemoteDeviceCommunicator communicator, final MessageTransformer transformer) { this.communicator = communicator; this.transformer = transformer; this.schemaContext = requireNonNull(schemaContext); } @Override public FluentFuture invokeRpc(final SchemaPath type, final NormalizedNode input) { final FluentFuture> delegateFuture = communicator.sendRequest( transformer.toRpcRequest(type, input), type.getLastComponent()); final SettableFuture ret = SettableFuture.create(); delegateFuture.addCallback(new FutureCallback>() { @Override public void onSuccess(RpcResult result) { ret.set(result.isSuccessful() ? transformer.toRpcResult(result.getResult(), type) : new DefaultDOMRpcResult(result.getErrors())); } @Override public void onFailure(Throwable cause) { ret.setException(new DOMRpcImplementationNotAvailableException(cause, "Unable to invoke rpc %s", type)); } }, MoreExecutors.directExecutor()); return ret; } @Nonnull @Override public ListenerRegistration registerRpcListener( @Nonnull final T listener) { listener.onRpcAvailable(Collections2.transform(schemaContext.getOperations(), input -> DOMRpcIdentifier.create(input.getPath()))); // NOOP, no rpcs appear and disappear in this implementation return NoOpListenerRegistration.of(listener); } }