--- /dev/null
+/*
+ * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.mdsal.dom.api;
+
+import com.google.common.annotations.Beta;
+import java.util.EventListener;
+import java.util.Set;
+import java.util.concurrent.Executor;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+/**
+ * An {@link DOMOperationServiceExtension} exposed by {@link DOMOperationService}s which allow their users to listen
+ * for operations becoming available.
+ *
+ * @author Robert Varga
+ */
+@Beta
+@NonNullByDefault
+public interface DOMOperationAvailabilityExtension extends DOMOperationServiceExtension {
+ /**
+ * Register a {@link AvailabilityListener} with this service to receive notifications about operation
+ * implementations becoming (un)available. The listener will be invoked with the current implementations reported
+ * and will be kept uptodate as implementations come and go.
+ *
+ * <p>
+ * Users should note that using a listener does not necessarily mean that
+ * {@link DOMOperationService#invokeRpc(QName, NormalizedNode, DOMOperationCallback, Executor)} and
+ * {@link DOMOperationService#invokeAction(SchemaPath, DOMDataTreeIdentifier, NormalizedNode)} will not report
+ * a failure due to {@link DOMOperationNotAvailableException} and need to be ready to handle it.
+ *
+ * <p>
+ * Implementations are encouraged to take reasonable precautions to prevent this scenario from occurring.
+ *
+ * @param listener {@link AvailabilityListener} instance to register
+ * @return A {@link ListenerRegistration} representing this registration. Performing a
+ * {@link ListenerRegistration#close()} will cancel it.
+ * @throws NullPointerException if {@code listener} is null
+ */
+ <T extends AvailabilityListener> ListenerRegistration<T> registerAvailabilityListener(T listener);
+
+ /**
+ * An {@link EventListener} used to track Operation implementations becoming (un)available
+ * to a {@link DOMOperationService}.
+ */
+ interface AvailabilityListener extends EventListener {
+ /**
+ * Method invoked whenever an operation type becomes available or unavailable. There are two sets reported,
+ * removed and added. To reconstruct the state, first apply removed and then added operations, like this:
+ *
+ * <code>
+ * Set<AvailableOperation<?>> operations;
+ * operations.removeAll(removed);
+ * operations.addAll(added);
+ * </code>
+ *
+ * @param removed operations which disappeared
+ * @param added operations which became available
+ */
+ void onOperationsChanged(Set<DOMOperationInstance<?>> removed, Set<DOMOperationInstance<?>> added);
+
+ /**
+ * Implementation filtering method. This method is useful for forwarding operation implementations,
+ * which need to ensure they do not re-announce their own implementations. Without this method
+ * a forwarder which registers an implementation would be notified of its own implementation,
+ * potentially re-exporting it as local -- hence creating a forwarding loop.
+ *
+ * @param impl Operation implementation being registered
+ * @return False if the implementation should not be reported, defaults to true.
+ */
+ default boolean acceptsImplementation(final DOMOperationImplementation impl) {
+ return true;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.mdsal.dom.api;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.annotations.Beta;
+import com.google.common.util.concurrent.SettableFuture;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Consumer;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.yangtools.concepts.CheckedValue;
+
+/**
+ * A callback to be executed when an operation invocation completes. This interface is modeled as a {@link Consumer}
+ * of {@link CheckedValue}, which needs to be unwrapped.
+ *
+ * <p>
+ * Alternatively, you can use {@link #of(Consumer, Consumer)} utility method, which provides the equivalent
+ * dispatch with a nicer interface:
+ * <code>
+ * DOMOperationCallback callback = DOMOperationCallback.of((success) -> {
+ * // ... code to handle success ...
+ * }, (failure) -> {
+ * // ... code to handle failure ...
+ * });
+ * </code>
+ *
+ * <p>
+ * Finally, you can create a bridging {@link DOMOperationCallback} through either
+ * {@link #completingFuture(SettableFuture)} or {@link #completingFuture(CompletableFuture)}.
+ *
+ * @author Robert Varga
+ */
+@Beta
+@NonNullByDefault
+@FunctionalInterface
+public interface DOMOperationCallback extends Consumer<CheckedValue<DOMOperationResult, DOMOperationException>> {
+ /**
+ * Create a DOMOperationCallback composed of two separate consumers, one for success and one for failure.
+ *
+ * @param onSuccess Callback to invoke on success
+ * @param onFailure Callback to invoke on failure
+ * @return A {@link DOMOperationCallback} which delegates to provided methods
+ * @throws NullPointerException if any of the arguments is null
+ */
+ static DOMOperationCallback of(final Consumer<DOMOperationResult> onSuccess,
+ final Consumer<DOMOperationException> onFailure) {
+ requireNonNull(onSuccess);
+ requireNonNull(onFailure);
+ return result -> {
+ if (result.isPresent()) {
+ onSuccess.accept(result.get());
+ } else {
+ onFailure.accept(result.getException());
+ }
+ };
+ }
+
+ /**
+ * Create a {@link DOMOperationCallback} which completes the specified future.
+ *
+ * @param future {@link CompletableFuture} to complete
+ * @return A {@link DOMOperationCallback}
+ * @throws NullPointerException if any of the arguments is null
+ */
+ static DOMOperationCallback completingFuture(final CompletableFuture<DOMOperationResult> future) {
+ requireNonNull(future);
+ return of(future::complete, future::completeExceptionally);
+ }
+
+ /**
+ * Create a {@link DOMOperationCallback} which completes the specified future.
+ *
+ * @param future {@link SettableFuture} to complete
+ * @return A {@link DOMOperationCallback}
+ * @throws NullPointerException if any of the arguments is null
+ */
+ static DOMOperationCallback completingFuture(final SettableFuture<DOMOperationResult> future) {
+ requireNonNull(future);
+ return of(future::set, future::setException);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.mdsal.dom.api;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Base class for failures that can occur during operation invocation. This covers transport and protocol-level
+ * failures, not implementation-reported errors, which are part of {@link DOMOperationResult}.
+ *
+ * @author Robert Varga
+ */
+@Beta
+@NonNullByDefault
+public abstract class DOMOperationException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Construct an new instance with a message and an empty cause.
+ *
+ * @param message Exception message
+ */
+ protected DOMOperationException(final String message) {
+ super(message);
+ }
+
+ /**
+ * Construct an new instance with a message and a cause.
+ *
+ * @param message Exception message
+ * @param cause Chained cause
+ */
+ protected DOMOperationException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.mdsal.dom.api;
+
+import com.google.common.annotations.Beta;
+import java.util.concurrent.Executor;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+/**
+ * Interface implemented by an individual operation implementation. This API allows for dispatch implementations, e.g.
+ * an individual object handling a multitude of operations.
+ *
+ * @author Robert Varga
+ */
+@Beta
+@NonNullByDefault
+public interface DOMOperationImplementation {
+ /**
+ * An implementation of an {@code action}.
+ */
+ @FunctionalInterface
+ interface Action {
+ /**
+ * Initiate invocation of the RPC. Implementations of this method are expected to not block.
+ *
+ * @param type SchemaPath of the action to be invoked. This path refers to an effective action instantiated on
+ * top of the conceptual {@link StoreTreeNode}.
+ * @param path {@link DOMDataTreeIdentifier} of parent data node which action attached to.
+ * @param input Input arguments
+ * @param callback Callback to invoke with the invocation result
+ * @param callbackExecutor Executor to use for executing the callback
+ * @throws NullPointerException if any of the arguments is null
+ */
+ void invokeAction(SchemaPath type, DOMDataTreeIdentifier path, NormalizedNode<?, ?> input,
+ DOMOperationCallback callback, Executor callbackExecutor);
+ }
+
+ /**
+ * An implementation of an {@code rpc}.
+ */
+ @FunctionalInterface
+ interface Rpc {
+ /**
+ * Initiate invocation of the RPC. Implementations of this method are expected to not block.
+ *
+ * @param type QName of the RPC to be invoked
+ * @param input Input arguments
+ * @param callback Callback to invoke with the invocation result
+ * @param callbackExecutor Executor to use for executing the callback
+ * @throws NullPointerException if any of the arguments is null
+ */
+ void invokeRpc(QName type, NormalizedNode<?, ?> input, DOMOperationCallback callback,
+ Executor callbackExecutor);
+ }
+
+ /**
+ * Return the relative invocation cost of this implementation. Default implementation returns 0.
+ *
+ * @return Non-negative cost of invoking this implementation.
+ */
+ default long invocationCost() {
+ return 0;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.mdsal.dom.api;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+import com.google.common.collect.ImmutableSet;
+import java.util.Objects;
+import java.util.Set;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.yangtools.concepts.Immutable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+/**
+ * An operation (RPC or action) which is subject to availability. This is a common superclass for {@link Action} and
+ * {@link Rpc}.
+ *
+ * @param <T> type of operation type
+ */
+public abstract class DOMOperationInstance<T> implements Immutable {
+ public static final class Action extends DOMOperationInstance<SchemaPath> {
+ private final Set<DOMDataTreeIdentifier> dataTrees;
+
+ Action(final SchemaPath type, final Set<DOMDataTreeIdentifier> dataTrees) {
+ super(type);
+ this.dataTrees = ImmutableSet.copyOf(dataTrees);
+ checkArgument(!dataTrees.isEmpty());
+ }
+
+ /**
+ * Return the set of data trees on which this action is available. Note that
+ * {@link DOMDataTreeIdentifier#getRootIdentifier()} may be a wildcard.
+ *
+ * @return Set of trees on which this action is available.
+ */
+ public Set<DOMDataTreeIdentifier> getDataTrees() {
+ return dataTrees;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getType(), dataTrees);
+ }
+
+ @Override
+ public boolean equals(final @Nullable Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof Action)) {
+ return false;
+ }
+ final Action other = (Action) obj;
+ return getType().equals(other.getType()) && dataTrees.equals(other.dataTrees);
+ }
+
+ @Override
+ ToStringHelper addToStringAttributes(final ToStringHelper helper) {
+ return helper.add("dataTrees", dataTrees);
+ }
+ }
+
+ public static final class Rpc extends DOMOperationInstance<QName> {
+ Rpc(final QName type) {
+ super(type);
+ }
+
+ @Override
+ public int hashCode() {
+ return getType().hashCode();
+ }
+
+ @Override
+ public boolean equals(final @Nullable Object obj) {
+ return this == obj || obj instanceof Rpc && getType().equals(((Rpc) obj).getType());
+ }
+ }
+
+ private final T type;
+
+ DOMOperationInstance(final T type) {
+ this.type = requireNonNull(type);
+ }
+
+ public static Action actionOf(final SchemaPath type, final Set<DOMDataTreeIdentifier> dataTrees) {
+ return new Action(type, dataTrees);
+ }
+
+ public static Action actionOf(final SchemaPath type, final DOMDataTreeIdentifier... dataTrees) {
+ return actionOf(type, ImmutableSet.copyOf(dataTrees));
+ }
+
+ public static Action actionOf(final SchemaPath type, final LogicalDatastoreType datastore,
+ final YangInstanceIdentifier path) {
+ return actionOf(type, ImmutableSet.of(new DOMDataTreeIdentifier(datastore, path)));
+ }
+
+ public static Rpc rpcOf(final QName type) {
+ return new Rpc(type);
+ }
+
+ /**
+ * Return the operation type.
+ *
+ * @return operation type.
+ */
+ public final T getType() {
+ return type;
+ }
+
+ @Override
+ public abstract int hashCode();
+
+ @Override
+ public abstract boolean equals(@Nullable Object obj);
+
+ @Override
+ public final String toString() {
+ return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
+ }
+
+ ToStringHelper addToStringAttributes(final ToStringHelper helper) {
+ return helper.add("type", type);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.mdsal.dom.api;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Exception indicating that no implementation of the requested operation is available.
+ */
+@Beta
+@NonNullByDefault
+public final class DOMOperationNotAvailableException extends DOMOperationException {
+ private static final long serialVersionUID = 1L;
+
+ public DOMOperationNotAvailableException(final String format, final Object... args) {
+ super(String.format(format, args));
+ }
+
+ public DOMOperationNotAvailableException(final Throwable cause, final String format, final Object... args) {
+ super(String.format(format, args), requireNonNull(cause));
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 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.mdsal.dom.api;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableSet;
+import java.util.Set;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+
+/**
+ * A {@link DOMService} which allows registration of operation implementations with a conceptual
+ * router. The client counterpart of this service is {@link DOMOperationService}.
+ */
+@Beta
+@NonNullByDefault
+public interface DOMOperationProviderService
+ extends DOMExtensibleService<DOMOperationProviderService, DOMOperationProviderServiceExtension> {
+ /**
+ * Register an {@link DOMOperationImplementation.Action} object with this service.
+ *
+ * @param implementation action implementation, must not be null
+ * @param instances Set of supported operation identifiers. Must not be null, empty, or contain a null element.
+ * @return A {@link ObjectRegistration} object, guaranteed to be non-null.
+ * @throws NullPointerException if implementation or types is null
+ * @throws IllegalArgumentException if {@code instances} is empty
+ */
+ <T extends DOMOperationImplementation.Action> ObjectRegistration<T> registerActionImplementation(T implementation,
+ Set<DOMOperationInstance.Action> instances);
+
+ default <T extends DOMOperationImplementation.Action> ObjectRegistration<T> registerActionImplementation(
+ final T implementation, final DOMOperationInstance.Action... instances) {
+ return registerActionImplementation(implementation, ImmutableSet.copyOf(instances));
+ }
+
+ /**
+ * Register an {@link DOMOperationImplementation.Rpc} object with this service.
+ *
+ * @param implementation RPC implementation, must not be null
+ * @param instances Set of supported operation identifiers. Must not be null, empty, or contain a null element.
+ * @return A {@link ObjectRegistration} object, guaranteed to be non-null.
+ * @throws NullPointerException if implementation or types is null
+ * @throws IllegalArgumentException if {@code instances} is empty
+ */
+ <T extends DOMOperationImplementation.Rpc> ObjectRegistration<T> registerRpcImplementation(T implementation,
+ Set<DOMOperationInstance.Rpc> instances);
+
+ default <T extends DOMOperationImplementation.Rpc> ObjectRegistration<T> registerRpcImplementation(
+ final T implementation, final DOMOperationInstance.Rpc... instances) {
+ return registerRpcImplementation(implementation, ImmutableSet.copyOf(instances));
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.mdsal.dom.api;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Marker interface for extensions of {@link DOMOperationProviderService}.
+ *
+ * @author Robert Varga
+ */
+@Beta
+@NonNullByDefault
+public interface DOMOperationProviderServiceExtension
+ extends DOMServiceExtension<DOMOperationProviderService, DOMOperationProviderServiceExtension> {
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.mdsal.dom.api;
+
+import com.google.common.annotations.Beta;
+import java.util.Collection;
+import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+/**
+ * Interface defining a result of an operation invocation.
+ *
+ * @author Robert Varga
+ */
+@Beta
+@NonNullByDefault
+public interface DOMOperationResult {
+ /**
+ * Returns a set of errors and warnings which occurred during processing the call.
+ *
+ * @return a Collection of {@link RpcError}, guaranteed to be non-null. In case no errors are reported, an empty
+ * collection is returned.
+ */
+ Collection<RpcError> getErrors();
+
+ /**
+ * Returns the value result of the call.
+ *
+ * @return Invocation result, absent if the operation has not produced a result. This might be the case if the
+ * operation does not produce a result, or if it failed.
+ */
+ Optional<NormalizedNode<?, ?>> getOutput();
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.mdsal.dom.api;
+
+import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
+
+import com.google.common.annotations.Beta;
+import com.google.common.util.concurrent.FluentFuture;
+import com.google.common.util.concurrent.SettableFuture;
+import java.util.concurrent.Executor;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.StoreTreeNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+
+/**
+ * A {@link DOMService} which allows clients to invoke Actions and RPCs. The conceptual model of this service is that
+ * of a dynamic router, where the set of available Operation services can change dynamically. The service allows users
+ * to add a listener to track the process of Actions and RPCs becoming available.
+ *
+ * @author Robert Varga
+ */
+@Beta
+@NonNullByDefault
+public interface DOMOperationService extends DOMExtensibleService<DOMOperationService, DOMOperationServiceExtension> {
+ /**
+ * Initiate invocation of an RPC. This method is guaranteed to not block on any external resources.
+ *
+ * @param type QName of the RPC to be invoked
+ * @param input Input arguments
+ * @param callback Callback to invoke with the invocation result
+ * @param callbackExecutor Executor to use for executing the callback
+ * @throws NullPointerException if any of the arguments is null
+ */
+ void invokeRpc(QName type, NormalizedNode<?, ?> input, DOMOperationCallback callback,
+ Executor callbackExecutor);
+
+ /**
+ * Initiate invocation of an RPC. This method is guaranteed to not block on any external resources.
+ *
+ * @param type QName of the RPC to be invoked
+ * @param input Input arguments
+ * @return A FluentFuture which completes with the result of invocation
+ * @throws NullPointerException if any of the arguments is null
+ */
+ default FluentFuture<DOMOperationResult> invokeRpc(final QName type, final NormalizedNode<?, ?> input) {
+ final SettableFuture<DOMOperationResult> future = SettableFuture.create();
+ invokeRpc(type, input, DOMOperationCallback.completingFuture(future), directExecutor());
+ return future;
+ }
+
+ /**
+ * Initiate invocation of an Action. This method is guaranteed to not block on any external resources.
+ *
+ * @param type SchemaPath of the action to be invoked. This path refers to an effective action instantiated on top
+ * of the conceptual {@link StoreTreeNode}.
+ * @param path {@link DOMDataTreeIdentifier} of parent data node which action attached to.
+ * @param input Input argument
+ * @param callback Callback to invoke with the invocation result
+ * @param callbackExecutor Executor to use for executing the callback
+ * @throws NullPointerException if any of the arguments is null
+ */
+ void invokeAction(SchemaPath type, DOMDataTreeIdentifier path,
+ NormalizedNode<?, ?> input, DOMOperationCallback callback, Executor callbackExecutor);
+
+ /**
+ * Initiate invocation of an Action. This method is guaranteed to not block on any external resources.
+ *
+ * @param type SchemaPath of the action to be invoked. This path refers to an effective action instantiated on top
+ * of the conceptual {@link StoreTreeNode}.
+ * @param path {@link DOMDataTreeIdentifier} of parent data node which action attached to.
+ * @param input Input argument
+ * @return A FluentFuture which completes with the result of invocation
+ * @throws NullPointerException if any of the arguments is null
+ */
+ default FluentFuture<DOMOperationResult> invokeAction(final SchemaPath type, final DOMDataTreeIdentifier path,
+ final NormalizedNode<?, ?> input) {
+ final SettableFuture<DOMOperationResult> future = SettableFuture.create();
+ invokeAction(type, path, input, DOMOperationCallback.completingFuture(future), directExecutor());
+ return future;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 Pantheon Technologies, s.r.o. 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.mdsal.dom.api;
+
+import com.google.common.annotations.Beta;
+import org.eclipse.jdt.annotation.NonNullByDefault;
+
+/**
+ * Marker interface for extensions of {@link DOMOperationService}.
+ *
+ * @author Robert Varga
+ */
+@Beta
+@NonNullByDefault
+public interface DOMOperationServiceExtension
+ extends DOMServiceExtension<DOMOperationService, DOMOperationServiceExtension> {
+
+}
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
/**
- * Identifier of a RPC context. This is an extension of the YANG RPC, which
- * always has global context. It allows an RPC to have a instance identifier
- * attached, so that there can be multiple implementations bound to different
- * contexts concurrently.
+ * Identifier of a RPC context. This is an extension of the YANG RPC, which always has global context. It allows an RPC
+ * to have a instance identifier attached, so that there can be multiple implementations bound to different contexts
+ * concurrently.
*/
public abstract class DOMRpcIdentifier {
private static final class Global extends DOMRpcIdentifier {
@Nullable final YangInstanceIdentifier contextReference) {
if (contextReference == null || contextReference.isEmpty()) {
return new Global(type);
- } else {
- return new Local(type, contextReference);
}
+
+ return new Local(type, contextReference);
}
/**
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
/**
- * A {@link DOMService} which allows clients to invoke RPCs. The conceptual model of this
- * service is that of a dynamic router, where the set of available RPC services can change
- * dynamically. The service allows users to add a listener to track the process of
- * RPCs becoming available.
+ * A {@link DOMService} which allows clients to invoke RPCs. The conceptual model of this service is that of a dynamic
+ * router, where the set of available RPC services can change dynamically. The service allows users to add a listener
+ * to track the process of RPCs becoming available.
*/
+// FIXME: once we have a DOMOperationService implementation, deprecate this interface
public interface DOMRpcService extends DOMService {
/**
* Initiate invocation of an RPC. This method is guaranteed to not block on any external