*/
package org.opendaylight.mdsal.binding.dom.adapter;
-import com.google.common.base.Preconditions;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.Objects.requireNonNull;
+import static org.opendaylight.mdsal.binding.dom.adapter.StaticConfiguration.ENABLE_CODEC_SHORTCUT;
+
+import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import java.lang.reflect.Proxy;
import java.util.Map.Entry;
import java.util.Optional;
-import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
+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.mdsal.dom.api.DOMRpcService;
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;
private final Class<? extends RpcService> type;
- private final BindingToNormalizedNodeCodec codec;
+ private final AdapterContext adapterContext;
private final DOMRpcService delegate;
private final RpcService proxy;
- RpcServiceAdapter(final Class<? extends RpcService> type, final BindingToNormalizedNodeCodec codec,
+ RpcServiceAdapter(final Class<? extends RpcService> type, final AdapterContext adapterContext,
final DOMRpcService domService) {
- this.type = Preconditions.checkNotNull(type);
- this.codec = Preconditions.checkNotNull(codec);
- this.delegate = Preconditions.checkNotNull(domService);
- final ImmutableMap.Builder<Method, RpcInvocationStrategy> rpcBuilder = ImmutableMap.builder();
- for (final Entry<Method, RpcDefinition> rpc : codec.getRpcMethodToSchema(type).entrySet()) {
+ this.type = requireNonNull(type);
+ this.adapterContext = requireNonNull(adapterContext);
+ this.delegate = requireNonNull(domService);
+
+ final ImmutableBiMap<Method, RpcDefinition> methods = adapterContext.currentSerializer()
+ .getRpcMethodToSchema(type);
+ final Builder<Method, RpcInvocationStrategy> rpcBuilder = ImmutableMap.builderWithExpectedSize(methods.size());
+ for (final Entry<Method, RpcDefinition> rpc : methods.entrySet()) {
rpcBuilder.put(rpc.getKey(), createStrategy(rpc.getKey(), rpc.getValue()));
}
rpcNames = rpcBuilder.build();
}
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 @NonNull Absolute outputPath;
- private final SchemaPath rpcName;
-
- protected RpcInvocationStrategy(final SchemaPath path) {
- rpcName = path;
+ RpcInvocationStrategy(final QName rpcName) {
+ this.outputPath = Absolute.of(rpcName, YangConstants.operationOutputQName(rpcName.getModule()).intern())
+ .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 QName getRpcName() {
+ return outputPath.firstNodeIdentifier();
}
- final SchemaPath getRpcName() {
- return rpcName;
- }
-
- ListenableFuture<RpcResult<?>> invoke0(final SchemaPath schemaPath, final ContainerNode input) {
- final ListenableFuture<DOMRpcResult> result = delegate.invokeRpc(schemaPath, input);
- if (result instanceof BindingRpcFutureAware) {
+ 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, codec.getCodecFactory());
+ return transformFuture(result, adapterContext.currentSerializer());
}
- private ListenableFuture<RpcResult<?>> transformFuture(final SchemaPath rpc,
- final ListenableFuture<DOMRpcResult> domFuture, final BindingNormalizedNodeCodecRegistry 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 {
-
- protected NonRoutedStrategy(final SchemaPath path) {
- super(path);
+ NonRoutedStrategy(final QName rpcName) {
+ super(rpcName);
}
@Override
ContainerNode serialize(final DataObject input) {
- return LazySerializedContainerNode.create(getRpcName(), input, codec.getCodecRegistry());
+ return LazySerializedContainerNode.create(getRpcName(), input, adapterContext.currentSerializer());
}
-
}
private final class RoutedStrategy extends RpcInvocationStrategy {
-
private final ContextReferenceExtractor refExtractor;
private final NodeIdentifier contextName;
- protected 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);
- Preconditions.checkState(maybeInputType.isPresent(), "RPC method %s has no input", rpcMethod.getName());
+ 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);
@Override
ContainerNode serialize(final DataObject input) {
final InstanceIdentifier<?> bindingII = refExtractor.extract(input);
+ final CurrentAdapterSerializer serializer = adapterContext.currentSerializer();
+
if (bindingII != null) {
- final YangInstanceIdentifier yangII = codec.toYangInstanceIdentifierCached(bindingII);
+ final YangInstanceIdentifier yangII = serializer.toCachedYangInstanceIdentifier(bindingII);
final LeafNode<?> contextRef = ImmutableNodes.leafNode(contextName, yangII);
- return LazySerializedContainerNode.withContextRef(getRpcName(), input, contextRef,
- codec.getCodecRegistry());
+ return LazySerializedContainerNode.withContextRef(getRpcName(), input, contextRef, serializer);
}
- return LazySerializedContainerNode.create(getRpcName(), input, codec.getCodecRegistry());
+ return LazySerializedContainerNode.create(getRpcName(), input, serializer);
}
}