import java.lang.reflect.Proxy;
import java.util.Map.Entry;
import java.util.Optional;
+import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
class RpcServiceAdapter implements InvocationHandler {
private final ImmutableMap<Method, RpcInvocationStrategy> rpcNames;
final DOMRpcService domService) {
this.type = requireNonNull(type);
this.adapterContext = requireNonNull(adapterContext);
- this.delegate = requireNonNull(domService);
+ delegate = requireNonNull(domService);
final ImmutableBiMap<Method, RpcDefinition> methods = adapterContext.currentSerializer()
.getRpcMethodToSchema(type);
}
private RpcInvocationStrategy createStrategy(final Method method, final RpcDefinition schema) {
+ final QName rpcType = schema.getQName();
final RpcRoutingStrategy strategy = RpcRoutingStrategy.from(schema);
- if (strategy.isContextBasedRouted()) {
- return new RoutedStrategy(schema.getPath(), method, strategy.getLeaf());
- }
- return new NonRoutedStrategy(schema.getPath());
+ return strategy.isContextBasedRouted() ? new RoutedStrategy(rpcType, method, strategy.getLeaf())
+ : new NonRoutedStrategy(rpcType);
}
RpcService getProxy() {
@Override
@SuppressWarnings("checkstyle:hiddenField")
- public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
-
+ public Object invoke(final Object proxy, final Method method, final Object[] args) {
final RpcInvocationStrategy rpc = rpcNames.get(method);
if (rpc != null) {
- if (method.getParameterCount() == 0) {
- return rpc.invokeEmpty();
- }
if (args.length != 1) {
throw new IllegalArgumentException("Input must be provided.");
}
- return rpc.invoke((DataObject) args[0]);
+ return rpc.invoke((DataObject) requireNonNull(args[0]));
}
switch (method.getName()) {
}
private abstract class RpcInvocationStrategy {
- private final SchemaPath rpcName;
+ private final @NonNull NodeIdentifier inputIdentifier;
+ private final @NonNull Absolute outputPath;
- RpcInvocationStrategy(final SchemaPath path) {
- rpcName = path;
+ RpcInvocationStrategy(final QName rpcName) {
+ final var namespace = rpcName.getModule();
+ outputPath = Absolute.of(rpcName, YangConstants.operationOutputQName(namespace).intern()).intern();
+ inputIdentifier = NodeIdentifier.create(YangConstants.operationInputQName(namespace.intern()));
}
final ListenableFuture<RpcResult<?>> invoke(final DataObject input) {
- return invoke0(rpcName, serialize(input));
+ return invoke0(serialize(input));
}
abstract ContainerNode serialize(DataObject input);
- final ListenableFuture<RpcResult<?>> invokeEmpty() {
- return invoke0(rpcName, null);
- }
-
- final SchemaPath getRpcName() {
- return rpcName;
+ final @NonNull NodeIdentifier inputIdentifier() {
+ return inputIdentifier;
}
- ListenableFuture<RpcResult<?>> invoke0(final SchemaPath schemaPath, final ContainerNode input) {
- final ListenableFuture<DOMRpcResult> result = delegate.invokeRpc(schemaPath, input);
+ private ListenableFuture<RpcResult<?>> invoke0(final ContainerNode input) {
+ final ListenableFuture<? extends DOMRpcResult> result =
+ delegate.invokeRpc(outputPath.firstNodeIdentifier(), input);
if (ENABLE_CODEC_SHORTCUT && result instanceof BindingRpcFutureAware) {
return ((BindingRpcFutureAware) result).getBindingFuture();
}
- return transformFuture(schemaPath, result, adapterContext.currentSerializer());
+ return transformFuture(result, adapterContext.currentSerializer());
}
- private ListenableFuture<RpcResult<?>> transformFuture(final SchemaPath rpc,
- final ListenableFuture<DOMRpcResult> domFuture, final BindingNormalizedNodeSerializer resultCodec) {
+ private ListenableFuture<RpcResult<?>> transformFuture(final ListenableFuture<? extends DOMRpcResult> domFuture,
+ final BindingNormalizedNodeSerializer resultCodec) {
return Futures.transform(domFuture, input -> {
- final NormalizedNode<?, ?> domData = input.getResult();
+ final NormalizedNode domData = input.getResult();
final DataObject bindingResult;
if (domData != null) {
- final SchemaPath rpcOutput = rpc.createChild(YangConstants.operationOutputQName(
- rpc.getLastComponent().getModule()));
- bindingResult = resultCodec.fromNormalizedNodeRpcData(rpcOutput, (ContainerNode) domData);
+ bindingResult = resultCodec.fromNormalizedNodeRpcData(outputPath, (ContainerNode) domData);
} else {
bindingResult = null;
}
}
private final class NonRoutedStrategy extends RpcInvocationStrategy {
- NonRoutedStrategy(final SchemaPath path) {
- super(path);
+ NonRoutedStrategy(final QName rpcName) {
+ super(rpcName);
}
@Override
ContainerNode serialize(final DataObject input) {
- return LazySerializedContainerNode.create(getRpcName(), input, adapterContext.currentSerializer());
+ return LazySerializedContainerNode.create(inputIdentifier(), input, adapterContext.currentSerializer());
}
}
private final ContextReferenceExtractor refExtractor;
private final NodeIdentifier contextName;
- RoutedStrategy(final SchemaPath path, final Method rpcMethod, final QName leafName) {
- super(path);
+ RoutedStrategy(final QName rpcName, final Method rpcMethod, final QName leafName) {
+ super(rpcName);
final Optional<Class<? extends DataContainer>> maybeInputType =
BindingReflections.resolveRpcInputClass(rpcMethod);
checkState(maybeInputType.isPresent(), "RPC method %s has no input", rpcMethod.getName());
final Class<? extends DataContainer> inputType = maybeInputType.get();
refExtractor = ContextReferenceExtractor.from(inputType);
- this.contextName = new NodeIdentifier(leafName);
+ contextName = new NodeIdentifier(leafName);
}
@Override
if (bindingII != null) {
final YangInstanceIdentifier yangII = serializer.toCachedYangInstanceIdentifier(bindingII);
final LeafNode<?> contextRef = ImmutableNodes.leafNode(contextName, yangII);
- return LazySerializedContainerNode.withContextRef(getRpcName(), input, contextRef, serializer);
+ return LazySerializedContainerNode.withContextRef(inputIdentifier(), input, contextRef, serializer);
}
- return LazySerializedContainerNode.create(getRpcName(), input, serializer);
+ return LazySerializedContainerNode.create(inputIdentifier(), input, serializer);
}
}