package org.opendaylight.mdsal.binding.javav2.api;
import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableSet;
import java.util.Set;
import org.opendaylight.mdsal.binding.javav2.spec.base.Action;
import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
-import org.opendaylight.mdsal.binding.javav2.spec.base.KeyedInstanceIdentifier;
-import org.opendaylight.mdsal.binding.javav2.spec.base.ListAction;
import org.opendaylight.mdsal.binding.javav2.spec.base.Rpc;
import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
-import org.opendaylight.yangtools.concepts.Identifier;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
import org.opendaylight.yangtools.concepts.ObjectRegistration;
/**
T implementation, Set<InstanceIdentifier<?>> paths);
/**
- * Returns class representing registration of Action.
- * @param type Action binding generated interface
- * @param parent parent node for Action connected to
- * @param implementation Action binding implementation
+ * Returns class representing registration of Action/ListAction.
+ * @param type Action/ListAction binding generated interface
+ * @param implementation Action/ListAction binding implementation
+ * @param datastore {@link LogicalDatastoreType} on which the implementation operates
+ * @param validNodes Set of nodes this implementation is constrained to, empty if this implementation can handle
+ * any target node.
* @param <S> service class type
* @param <P> parent type
* @param <T> service implementation type
*/
<S extends Action<? extends TreeNode, ?, ?, ?>, T extends S, P extends TreeNode> ObjectRegistration<T>
registerActionImplementation(
- Class<S> type, InstanceIdentifier<P> parent, T implementation);
+ Class<S> type, T implementation, LogicalDatastoreType datastore, Set<DataTreeIdentifier<P>> validNodes);
- /**
- * Returns class representing registration of ListAction.
- * @param type ListAction binding generated interface
- * @param parent parent node for ListAction connected to
- * @param implementation ListAction binding implementation
- * @param <S> service class type
- * @param <P> parent type
- * @param <K> key type
- * @param <T> service implementation type
- * @return returns class representing a ListAction registration
- */
- <S extends ListAction<? extends TreeNode, ?, ?, ?>, T extends S, P extends TreeNode, K extends Identifier>
- ObjectRegistration<T> registerListActionImplementation(Class<S> type, KeyedInstanceIdentifier<P, K> parent,
- T implementation);
+ default <S extends Action<? extends TreeNode, ?, ?, ?>, T extends S> ObjectRegistration<T>
+ registerActionImplementation(Class<S> type, T implementation, LogicalDatastoreType datastore) {
+ return registerActionImplementation(type, implementation, datastore, ImmutableSet.of());
+ }
+
+ default <S extends Action<? extends TreeNode, ?, ?, ?>, T extends S> ObjectRegistration<T>
+ registerActionImplementation(Class<S> type, T implementation) {
+ return registerActionImplementation(type, implementation, LogicalDatastoreType.OPERATIONAL, ImmutableSet.of());
+ }
}
+++ /dev/null
-/*
- * Copyright (c) 2017 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.binding.javav2.dom.adapter.impl.operation;
-
-import com.google.common.annotations.Beta;
-import com.google.common.base.Preconditions;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.util.concurrent.FluentFuture;
-import com.google.common.util.concurrent.JdkFutureAdapters;
-import com.google.common.util.concurrent.ListenableFuture;
-import java.lang.reflect.Method;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.ExecutionException;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.operation.invoker.OperationServiceInvoker;
-import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
-import org.opendaylight.mdsal.binding.javav2.dom.codec.serialized.LazySerializedContainerNode;
-import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
-import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
-import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
-import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
-import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
-import org.opendaylight.mdsal.dom.api.DOMRpcResult;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.RpcResult;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
-
-/**
- * Operation implementation adapter.
- */
-@Beta
-public class BindingDOMOperationImplementationAdapter implements DOMRpcImplementation {
-
- private static final Cache<Class<? extends Operation>, OperationServiceInvoker> SERVICE_INVOKERS =
- CacheBuilder.newBuilder().weakKeys().build();
- // Default implementations are 0, we need to perform some translation, hence we have a slightly higher
- // cost
- private static final int COST = 1;
-
- private final BindingNormalizedNodeCodecRegistry codec;
- private final OperationServiceInvoker invoker;
- private final Operation delegate;
- private final QName inputQname;
-
- <T extends Operation> BindingDOMOperationImplementationAdapter(final BindingNormalizedNodeCodecRegistry codec,
- final Class<T> type, final Map<SchemaPath, Method> localNameToMethod, final T delegate) {
- try {
- this.invoker = SERVICE_INVOKERS.get(type, () -> {
- final Map<QName, Method> map = new HashMap<>();
- for (final Entry<SchemaPath, Method> e : localNameToMethod.entrySet()) {
- map.put(e.getKey().getLastComponent(), e.getValue());
- }
-
- return OperationServiceInvoker.from(map);
- });
- } catch (final ExecutionException e) {
- throw new IllegalArgumentException("Failed to create invokers for type " + type, e);
- }
-
- this.codec = Preconditions.checkNotNull(codec);
- this.delegate = Preconditions.checkNotNull(delegate);
- inputQname = QName.create(BindingReflections.getQNameModule(type), "input").intern();
- }
-
- @SuppressWarnings("deprecation")
- @Nonnull
- @Override
- public FluentFuture<DOMRpcResult> invokeRpc(@Nonnull final DOMRpcIdentifier rpc,
- @Nullable final NormalizedNode<?, ?> input) {
-
- final SchemaPath schemaPath = rpc.getType();
- final TreeNode bindingInput = input != null ? deserialize(rpc.getType(), input) : null;
- final ListenableFuture<RpcResult<?>> bindingResult = invoke(schemaPath, bindingInput);
- return transformResult(bindingResult);
- }
-
- @Override
- public long invocationCost() {
- return COST;
- }
-
- private TreeNode deserialize(final SchemaPath rpcPath, final NormalizedNode<?, ?> input) {
- if (input instanceof LazySerializedContainerNode) {
- return ((LazySerializedContainerNode) input).bindingData();
- }
- final SchemaPath inputSchemaPath = rpcPath.createChild(inputQname);
- return codec.fromNormalizedNodeOperationData(inputSchemaPath, (ContainerNode) input);
- }
-
- private ListenableFuture<RpcResult<?>> invoke(final SchemaPath schemaPath, final TreeNode input) {
- return JdkFutureAdapters.listenInPoolThread(invoker.invoke(delegate, schemaPath.getLastComponent(), input));
- }
-
- private FluentFuture<DOMRpcResult> transformResult(final ListenableFuture<RpcResult<?>> bindingResult) {
- return LazyDOMOperationResultFuture.create(codec, bindingResult);
- }
-}
package org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.operation;
import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
-import java.lang.reflect.Method;
+import com.google.common.util.concurrent.FluentFuture;
+import com.google.common.util.concurrent.SettableFuture;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
-import java.util.Map;
import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.mdsal.binding.javav2.api.DataTreeIdentifier;
import org.opendaylight.mdsal.binding.javav2.api.RpcActionProviderService;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.operation.BindingDOMOperationProviderServiceAdapter.AbstractImplAdapter.ActionAdapter;
+import org.opendaylight.mdsal.binding.javav2.dom.adapter.impl.operation.BindingDOMOperationProviderServiceAdapter.AbstractImplAdapter.RpcAdapter;
import org.opendaylight.mdsal.binding.javav2.dom.adapter.registration.BindingDOMOperationAdapterRegistration;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingToNormalizedNodeCodec;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.serialized.LazySerializedContainerNode;
+import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
import org.opendaylight.mdsal.binding.javav2.spec.base.Action;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Input;
import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
-import org.opendaylight.mdsal.binding.javav2.spec.base.KeyedInstanceIdentifier;
-import org.opendaylight.mdsal.binding.javav2.spec.base.ListAction;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Output;
import org.opendaylight.mdsal.binding.javav2.spec.base.Rpc;
+import org.opendaylight.mdsal.binding.javav2.spec.base.RpcCallback;
import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMActionImplementation;
+import org.opendaylight.mdsal.dom.api.DOMActionInstance;
+import org.opendaylight.mdsal.dom.api.DOMActionProviderService;
+import org.opendaylight.mdsal.dom.api.DOMActionResult;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
+import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementationRegistration;
import org.opendaylight.mdsal.dom.api.DOMRpcProviderService;
-import org.opendaylight.yangtools.concepts.Identifier;
+import org.opendaylight.mdsal.dom.api.DOMRpcResult;
import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
//FIXME missing support of Action operation (dependence on support of Yang 1.1 in DOM part of MD-SAL)
private static final Set<YangInstanceIdentifier> GLOBAL = ImmutableSet.of(YangInstanceIdentifier.builder().build());
private final BindingToNormalizedNodeCodec codec;
private final DOMRpcProviderService domRpcRegistry;
+ private final DOMActionProviderService domActionRegistry;
public BindingDOMOperationProviderServiceAdapter(final DOMRpcProviderService domRpcRegistry,
- final BindingToNormalizedNodeCodec codec) {
+ final DOMActionProviderService domActionRegistry, final BindingToNormalizedNodeCodec codec) {
this.codec = codec;
this.domRpcRegistry = domRpcRegistry;
+ this.domActionRegistry = domActionRegistry;
}
@Override
private <S extends Rpc<?, ?>, T extends S> ObjectRegistration<T> register(final Class<S> type,
final T implementation, final Collection<YangInstanceIdentifier> rpcContextPaths) {
- final Map<SchemaPath, Method> rpcs = codec.getRPCMethodToSchemaPath(type).inverse();
-
- final BindingDOMOperationImplementationAdapter adapter =
- new BindingDOMOperationImplementationAdapter(codec.getCodecRegistry(), type, rpcs, implementation);
- final Set<DOMRpcIdentifier> domRpcs = createDomRpcIdentifiers(rpcs.keySet(), rpcContextPaths);
- final DOMRpcImplementationRegistration<?> domReg = domRpcRegistry.registerRpcImplementation(adapter, domRpcs);
+ final SchemaPath path = codec.getRpcPath(type);
+ final Set<DOMRpcIdentifier> domRpcs = createDomRpcIdentifiers(path, rpcContextPaths);
+ final DOMRpcImplementationRegistration<?> domReg = domRpcRegistry.registerRpcImplementation(
+ new RpcAdapter(codec.getCodecRegistry(), type, implementation), domRpcs);
return new BindingDOMOperationAdapterRegistration<>(implementation, domReg);
}
- private static Set<DOMRpcIdentifier> createDomRpcIdentifiers(final Set<SchemaPath> rpcs,
+ private static Set<DOMRpcIdentifier> createDomRpcIdentifiers(final SchemaPath rpc,
final Collection<YangInstanceIdentifier> paths) {
final Set<DOMRpcIdentifier> ret = new HashSet<>();
for (final YangInstanceIdentifier path : paths) {
- for (final SchemaPath rpc : rpcs) {
- ret.add(DOMRpcIdentifier.create(rpc, path));
- }
+ ret.add(DOMRpcIdentifier.create(rpc, path));
}
return ret;
}
@Override
public <S extends Action<? extends TreeNode, ?, ?, ?>, T extends S, P extends TreeNode> ObjectRegistration<T>
- registerActionImplementation(final Class<S> type, final InstanceIdentifier<P> parent,
- final T implementation) {
- // TODO implement after improve DOM part of MD-SAL for support of Yang 1.1
- throw new UnsupportedOperationException();
+ registerActionImplementation(final Class<S> type, final T implementation,
+ final LogicalDatastoreType datastore, final Set<DataTreeIdentifier<P>> validNodes) {
+ final SchemaPath path = codec.getActionPath(type);
+ final ObjectRegistration<ActionAdapter> domReg = domActionRegistry.registerActionImplementation(
+ new ActionAdapter(codec.getCodecRegistry(), type, implementation),
+ DOMActionInstance.of(path, codec.toDOMDataTreeIdentifiers(validNodes)));
+ return new BindingDOMOperationAdapterRegistration<>(implementation, domReg);
}
- @Override
- public <S extends ListAction<? extends TreeNode, ?, ?, ?>, T extends S, P extends TreeNode, K extends Identifier>
- ObjectRegistration<T> registerListActionImplementation(final Class<S> type,
- final KeyedInstanceIdentifier<P, K> parent, final T implementation) {
- // TODO implement after improve DOM part of MD-SAL for support of Yang 1.1
- throw new UnsupportedOperationException();
+ public abstract static class AbstractImplAdapter<D> {
+ protected final BindingNormalizedNodeCodecRegistry codec;
+ protected final D delegate;
+ private final QName inputQname;
+
+ AbstractImplAdapter(final BindingNormalizedNodeCodecRegistry codec, final Class<? extends Operation> clazz,
+ final D delegate) {
+ this.codec = Preconditions.checkNotNull(codec);
+ this.delegate = Preconditions.checkNotNull(delegate);
+ inputQname = QName.create(BindingReflections.getQNameModule(clazz), "input").intern();
+ }
+
+ TreeNode deserialize(final SchemaPath path, final NormalizedNode<?, ?> input) {
+ if (input instanceof LazySerializedContainerNode) {
+ return ((LazySerializedContainerNode) input).bindingData();
+ }
+ final SchemaPath inputSchemaPath = path.createChild(inputQname);
+ return codec.fromNormalizedNodeOperationData(inputSchemaPath, (ContainerNode) input);
+ }
+
+ public static final class RpcAdapter extends AbstractImplAdapter<Rpc> implements DOMRpcImplementation {
+
+ RpcAdapter(BindingNormalizedNodeCodecRegistry codec, Class<? extends Operation> clazz,
+ Rpc<?, ?> delegate) {
+ super(codec, clazz, delegate);
+ }
+
+ @SuppressWarnings("checkstyle:illegalCatch, unchecked")
+ @Nonnull
+ @Override
+ public FluentFuture<DOMRpcResult> invokeRpc(@Nonnull final DOMRpcIdentifier rpc,
+ @Nullable final NormalizedNode<?, ?> input) {
+ final TreeNode bindingInput = input != null ? deserialize(rpc.getType(), input) : null;
+ final SettableFuture<RpcResult<?>> bindingResult = SettableFuture.create();
+ CompletableFuture.runAsync(() -> delegate.invoke((Input<?>) bindingInput,
+ new RpcCallback<Output<?>>() {
+ public void onSuccess(Output<?> output) {
+ bindingResult.set(RpcResultBuilder.success(output).build());
+ }
+
+ public void onFailure(Throwable error) {
+ bindingResult.set(RpcResultBuilder.failed().withError(ErrorType.APPLICATION,
+ error.getMessage()).build());
+ }
+ })
+ );
+ return LazyDOMRpcResultFuture.create(codec,bindingResult);
+ }
+ }
+
+ public static final class ActionAdapter extends AbstractImplAdapter<Action>
+ implements DOMActionImplementation {
+
+ ActionAdapter(BindingNormalizedNodeCodecRegistry codec, Class<? extends Operation> clazz,
+ Action<?, ?, ?, ?> delegate) {
+ super(codec, clazz, delegate);
+ }
+
+ @SuppressWarnings("checkstyle:illegalCatch, unchecked")
+ @Nonnull
+ public FluentFuture<? extends DOMActionResult> invokeAction(SchemaPath type, DOMDataTreeIdentifier path,
+ ContainerNode input) {
+ final TreeNode bindingInput = input != null ? deserialize(type, input) : null;
+ final SettableFuture<RpcResult<?>> bindingResult = SettableFuture.create();
+ CompletableFuture.runAsync(() -> delegate.invoke((Input<?>) bindingInput,
+ codec.fromYangInstanceIdentifier(path.getRootIdentifier()),
+ new RpcCallback<Output<?>>() {
+ public void onSuccess(Output<?> output) {
+ bindingResult.set(RpcResultBuilder.success(output).build());
+ }
+
+ public void onFailure(Throwable error) {
+ bindingResult.set(RpcResultBuilder.failed().withError(ErrorType.APPLICATION,
+ error.getMessage()).build());
+ }
+ })
+ );
+ return LazyDOMActionResultFuture.create(codec, bindingResult);
+ }
+ }
}
}
--- /dev/null
+/*
+ * Copyright (c) 2017 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.binding.javav2.dom.adapter.impl.operation;
+
+import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.AbstractFuture;
+import com.google.common.util.concurrent.FluentFuture;
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import javax.annotation.Nonnull;
+import org.opendaylight.mdsal.binding.javav2.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
+import org.opendaylight.mdsal.dom.api.DOMActionException;
+import org.opendaylight.mdsal.dom.api.DOMActionNotAvailableException;
+import org.opendaylight.mdsal.dom.api.DOMActionResult;
+import org.opendaylight.mdsal.dom.spi.SimpleDOMActionResult;
+import org.opendaylight.yangtools.util.concurrent.ExceptionMapper;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+
+/**
+ * DOM operation result from Binding.
+ */
+@Beta
+final class LazyDOMActionResultFuture extends AbstractFuture<DOMActionResult> {
+ private static final ExceptionMapper<DOMActionException> DOM_ACTION_EX_MAPPER =
+ new ExceptionMapper<DOMActionException>("action", DOMActionException.class) {
+ @Override
+ protected DOMActionException newWithCause(String message, Throwable cause) {
+ return cause instanceof DOMActionException ? (DOMActionException)cause
+ : new DOMActionNotAvailableException("Action failed", cause);
+ }
+ };
+
+ private final ListenableFuture<RpcResult<?>> bindingFuture;
+ private final BindingNormalizedNodeCodecRegistry codec;
+ private volatile DOMActionResult result;
+
+ private LazyDOMActionResultFuture(final ListenableFuture<RpcResult<?>> delegate,
+ final BindingNormalizedNodeCodecRegistry codec) {
+ this.bindingFuture = Preconditions.checkNotNull(delegate, "delegate");
+ this.codec = Preconditions.checkNotNull(codec, "codec");
+ }
+
+ static FluentFuture<DOMActionResult> create(final BindingNormalizedNodeCodecRegistry codec,
+ final ListenableFuture<RpcResult<?>> bindingResult) {
+ return new LazyDOMActionResultFuture(bindingResult, codec);
+ }
+
+ ListenableFuture<RpcResult<?>> getBindingFuture() {
+ return bindingFuture;
+ }
+
+ @Override
+ public boolean cancel(final boolean mayInterruptIfRunning) {
+ return bindingFuture.cancel(mayInterruptIfRunning);
+ }
+
+ @Override
+ public void addListener(@Nonnull final Runnable listener, @Nonnull final Executor executor) {
+ bindingFuture.addListener(listener, executor);
+ }
+
+ @Override
+ public DOMActionResult get() throws InterruptedException, ExecutionException {
+ if (result != null) {
+ return result;
+ }
+
+ try {
+ return transformIfNecessary(bindingFuture.get());
+ } catch (ExecutionException e) {
+ throw new ExecutionException(e.getMessage(), DOM_ACTION_EX_MAPPER.apply(e));
+ }
+ }
+
+ @Override
+ public DOMActionResult get(@Nonnull final long timeout, final TimeUnit unit)
+ throws InterruptedException, ExecutionException, TimeoutException {
+ if (result != null) {
+ return result;
+ }
+
+ try {
+ return transformIfNecessary(bindingFuture.get(timeout, unit));
+ } catch (ExecutionException e) {
+ throw new ExecutionException(e.getMessage(), DOM_ACTION_EX_MAPPER.apply(e));
+ }
+ }
+
+ @Override
+ public boolean isCancelled() {
+ return bindingFuture.isCancelled();
+ }
+
+ @Override
+ public boolean isDone() {
+ return bindingFuture.isDone();
+ }
+
+ private synchronized DOMActionResult transformIfNecessary(final RpcResult<?> input) {
+ if (result == null) {
+ result = transform(input);
+ }
+ return result;
+ }
+
+ private DOMActionResult transform(final RpcResult<?> input) {
+ if (input.isSuccessful()) {
+ final Object inputData = input.getResult();
+ if (inputData instanceof DataContainer) {
+ return new SimpleDOMActionResult(codec.toNormalizedNodeOperationData((TreeNode) inputData),
+ ImmutableList.of());
+ } else {
+ return new SimpleDOMActionResult(ImmutableList.of());
+ }
+ }
+ return new SimpleDOMActionResult(input.getErrors());
+ }
+
+}
* DOM operation result from Binding.
*/
@Beta
-final class LazyDOMOperationResultFuture extends AbstractFuture<DOMRpcResult> {
+final class LazyDOMRpcResultFuture extends AbstractFuture<DOMRpcResult> {
private static final ExceptionMapper<DOMRpcException> DOM_RPC_EX_MAPPER =
new ExceptionMapper<DOMRpcException>("rpc", DOMRpcException.class) {
@Override
private final BindingNormalizedNodeCodecRegistry codec;
private volatile DOMRpcResult result;
- private LazyDOMOperationResultFuture(final ListenableFuture<RpcResult<?>> delegate,
- final BindingNormalizedNodeCodecRegistry codec) {
+ private LazyDOMRpcResultFuture(final ListenableFuture<RpcResult<?>> delegate,
+ final BindingNormalizedNodeCodecRegistry codec) {
this.bindingFuture = Preconditions.checkNotNull(delegate, "delegate");
this.codec = Preconditions.checkNotNull(codec, "codec");
}
static FluentFuture<DOMRpcResult> create(final BindingNormalizedNodeCodecRegistry codec,
final ListenableFuture<RpcResult<?>> bindingResult) {
- return new LazyDOMOperationResultFuture(bindingResult, codec);
+ return new LazyDOMRpcResultFuture(bindingResult, codec);
}
ListenableFuture<RpcResult<?>> getBindingFuture() {
private ListenableFuture<RpcResult<?>> invoke0(final SchemaPath schemaPath, final NormalizedNode<?, ?> input) {
final ListenableFuture<DOMRpcResult> listenInPoolThread =
JdkFutureAdapters.listenInPoolThread(delegate.invokeRpc(schemaPath, input));
- if (listenInPoolThread instanceof LazyDOMOperationResultFuture) {
- return ((LazyDOMOperationResultFuture) listenInPoolThread).getBindingFuture();
+ if (listenInPoolThread instanceof LazyDOMRpcResultFuture) {
+ return ((LazyDOMRpcResultFuture) listenInPoolThread).getBindingFuture();
}
return transformFuture(schemaPath, listenInPoolThread, codec.getCodecFactory());
import com.google.common.annotations.Beta;
import org.opendaylight.mdsal.binding.javav2.spec.base.Operation;
-import org.opendaylight.mdsal.dom.api.DOMRpcImplementationRegistration;
import org.opendaylight.yangtools.concepts.AbstractObjectRegistration;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
/**
* Registration of Binding - DOM Operation adapter.
@Beta
public class BindingDOMOperationAdapterRegistration<T extends Operation> extends AbstractObjectRegistration<T> {
- private final DOMRpcImplementationRegistration<?> reg;
+ private final ObjectRegistration<?> reg;
- // FIXME : DOM part doesn't work with Yang 1.1 - Action registration isn't implemented yet.
- public BindingDOMOperationAdapterRegistration(final T instance, final DOMRpcImplementationRegistration<?> reg) {
+ public BindingDOMOperationAdapterRegistration(final T instance, final ObjectRegistration<?> reg) {
super(instance);
this.reg = reg;
}
import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
import org.opendaylight.mdsal.binding.javav2.spec.runtime.YangModuleInfo;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMActionProviderService;
import org.opendaylight.mdsal.dom.api.DOMDataBroker;
import org.opendaylight.mdsal.dom.api.DOMMountPointService;
import org.opendaylight.mdsal.dom.api.DOMNotificationPublishService;
checkState(executor != null, "Executor needs to be set");
baConsumerRpc = new BindingDOMOperationServiceAdapter(getDomRpcInvoker(), codec);
- baProviderRpc = new BindingDOMOperationProviderServiceAdapter(getDomRpcRegistry(), codec);
+ baProviderRpc = new BindingDOMOperationProviderServiceAdapter(getDomRpcRegistry(), getDomActionRegistry(),
+ codec);
final MountPointService mountService = new BindingDOMMountPointServiceAdapter(biMountImpl, codec);
}
return domRouter.getRpcProviderService();
}
+ public DOMActionProviderService getDomActionRegistry() {
+ return domRouter.getActionProviderService();
+ }
+
public DOMRpcService getDomRpcInvoker() {
return domRouter.getRpcService();
}
*/
package org.opendaylight.mdsal.binding.javav2.dom.codec.impl;
+import static com.google.common.base.Preconditions.checkArgument;
+
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
import com.google.common.cache.CacheBuilder;
import org.opendaylight.mdsal.binding.javav2.generator.impl.GeneratedClassLoadingStrategy;
import org.opendaylight.mdsal.binding.javav2.runtime.context.BindingRuntimeContext;
import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Action;
import org.opendaylight.mdsal.binding.javav2.spec.base.InstanceIdentifier;
import org.opendaylight.mdsal.binding.javav2.spec.base.Notification;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Rpc;
import org.opendaylight.mdsal.binding.javav2.spec.base.TreeArgument;
import org.opendaylight.mdsal.binding.javav2.spec.base.TreeNode;
import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
* - RPC as binding object
* @return map of method with path of specific RPC
*/
+ @Deprecated
public ImmutableBiMap<Method, SchemaPath> getRPCMethodToSchemaPath(final Class<?> key) {
final Module module = getModuleBlocking(key);
final ImmutableBiMap.Builder<Method, SchemaPath> ret = ImmutableBiMap.builder();
}
/**
- * Resolve method with path of specific Action as binding object.
+ * Get Action schema path.
*
- * @param key
- * - action as binding object
- * @return map of method with path of specific action
+ * @param type
+ * - Action implementation class type
+ * @return schema path of Action
*/
- public ImmutableBiMap<Method, SchemaPath> getActionMethodToSchemaPath(final Class<?> key) {
- final Module module = getModuleBlocking(key);
-
- final ImmutableBiMap.Builder<Method, SchemaPath> ret = ImmutableBiMap.builder();
- try {
- for (final ActionDefinition actionDefinition : runtimeContext.getSchemaContext().getActions()) {
- final QName qName = actionDefinition.getQName();
- if (qName.getModule().equals(module.getQNameModule())) {
- final Method method = runtimeContext.findOperationMethod(key, actionDefinition);
- ret.put(method, actionDefinition.getPath());
- }
- }
- } catch (final NoSuchMethodException e) {
- throw new IllegalStateException("Action defined in model does not have representation in generated class.",
- e);
- }
- return ret.build();
+ public SchemaPath getActionPath(final Class<? extends Action<?, ?, ?, ?>> type) {
+ final ActionDefinition schema = runtimeContext.getActionDefinition(type);
+ checkArgument(schema != null, "Failed to find schema for %s", type);
+ return schema.getPath();
}
+ /**
+ * Get RPC schema path.
+ *
+ * @param type
+ * - RPC implementation class type
+ * @return schema path of RPC
+ */
+ public SchemaPath getRpcPath(final Class<? extends Rpc<?, ?>> type) {
+ final RpcDefinition schema = runtimeContext.getRpcDefinition(type);
+ checkArgument(schema != null, "Failed to find schema for %s", type);
+ return schema.getPath();
+ }
/**
* Resolve method with definition of specific RPC as binding object.
final BindingTreeCodec currentCodecTree = codecRegistry.getCodecContext();
final InstanceIdentifier<?> bindingPath = codecRegistry.fromYangInstanceIdentifier(domIdentifier);
- Preconditions.checkArgument(bindingPath != null);
+ checkArgument(bindingPath != null);
/**
* If we are able to deserialize YANG instance identifier, getSubtreeCodec must return non-null value.
*/
return ret;
}
+ //FIXME: avoid the duplication of the function above.
+ public <P extends TreeNode> Set<DOMDataTreeIdentifier>
+ toDOMDataTreeIdentifiers(final Set<DataTreeIdentifier<P>> subtrees) {
+ final Set<DOMDataTreeIdentifier> ret = new HashSet<>(subtrees.size());
+
+ for (final DataTreeIdentifier<?> subtree : subtrees) {
+ ret.add(toDOMDataTreeIdentifier(subtree));
+ }
+ return ret;
+ }
+
/**
* Create new DOM data tree identifier from Binding data tree identifier.
*
import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus;
import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
private final List<GeneratedTypeBuilder> augmentations = new ArrayList<>();
private final Multimap<Type,AugmentationSchemaNode> typeToAugmentations = HashMultimap.create();
private final BiMap<SchemaPath,Type> targetToAugmentation = HashBiMap.create();
- private final Map<Type,Object> typeToSchema = new HashMap<>();
+ private final Map<Type,WithStatus> typeToSchema = new HashMap<>();
private final Multimap<Type, Type> choiceToCases = HashMultimap.create();
private final BiMap<Type, CaseSchemaNode> caseTypeToSchema = HashBiMap.create();
private final Map<SchemaPath, Type> innerTypes = new HashMap<>();
*
* @return Mapping from type to corresponding schema
*/
- public Map<Type, Object> getTypeToSchema() {
+ public Map<Type, WithStatus> getTypeToSchema() {
return Collections.unmodifiableMap(this.typeToSchema);
}
import org.opendaylight.mdsal.binding.javav2.model.api.type.builder.GeneratedTypeBuilder;
import org.opendaylight.mdsal.binding.javav2.runtime.context.util.BindingSchemaContextUtils;
import org.opendaylight.mdsal.binding.javav2.runtime.reflection.BindingReflections;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Action;
+import org.opendaylight.mdsal.binding.javav2.spec.base.Rpc;
import org.opendaylight.mdsal.binding.javav2.spec.structural.Augmentation;
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.OperationDefinition;
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
private final Multimap<Type, AugmentationSchemaNode> augmentationToSchemas = HashMultimap.create();
private final BiMap<SchemaPath,Type> targetToAugmentation = HashBiMap.create();
- private final BiMap<Type, Object> typeToDefiningSchema = HashBiMap.create();
+ private final BiMap<Type, WithStatus> typeToDefiningSchema = HashBiMap.create();
private final Multimap<Type, Type> choiceToCases = HashMultimap.create();
private final Map<QName, Type> identities = new HashMap<>();
return (DataSchemaNode) this.typeToDefiningSchema.get(referencedType(cls));
}
+ public RpcDefinition getRpcDefinition(final Class<? extends Rpc<?, ?>> cls) {
+ return (RpcDefinition) typeToDefiningSchema.get(referencedType(cls));
+ }
+
+ public ActionDefinition getActionDefinition(final Class<? extends Action<?, ?, ?, ?>> cls) {
+ return (ActionDefinition) typeToDefiningSchema.get(referencedType(cls));
+ }
+
/**
* Returns defining {@link AugmentationSchemaNode} of target for supplied class.
*
checkArgument(cls != null);
final String packageName = getModelRootPackageName(cls.getPackage());
final String potentialClassName = getModuleInfoClassName(packageName);
- return ClassLoaderUtils.withClassLoader(cls.getClassLoader(), (Callable<YangModuleInfo>) () -> {
+ return ClassLoaderUtils.callWithClassLoader(cls.getClassLoader(), () -> {
final Class<?> moduleInfoClass = Thread.currentThread().getContextClassLoader().loadClass(potentialClassName);
return (YangModuleInfo) moduleInfoClass.getMethod("getInstance").invoke(null);
});