import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.Maps;
-import com.google.common.util.concurrent.FluentFuture;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import org.opendaylight.mdsal.dom.api.DOMRpcAvailabilityListener;
+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.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
abstract class AbstractDOMRpcRoutingTableEntry {
private final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> implementations;
- private final SchemaPath schemaPath;
+ private final DOMRpcIdentifier rpcId;
- AbstractDOMRpcRoutingTableEntry(final SchemaPath schemaPath, final Map<YangInstanceIdentifier,
+ AbstractDOMRpcRoutingTableEntry(final DOMRpcIdentifier rpcId, final Map<YangInstanceIdentifier,
List<DOMRpcImplementation>> implementations) {
- this.schemaPath = Preconditions.checkNotNull(schemaPath);
+ this.rpcId = Preconditions.checkNotNull(rpcId);
this.implementations = Preconditions.checkNotNull(implementations);
}
final SchemaPath getSchemaPath() {
- return schemaPath;
+ return rpcId.getType();
+ }
+
+ final DOMRpcIdentifier getRpcId() {
+ return rpcId;
}
final List<DOMRpcImplementation> getImplementations(final YangInstanceIdentifier context) {
return v.isEmpty() ? null : newInstance(v);
}
- protected abstract FluentFuture<DOMRpcResult> invokeRpc(NormalizedNode<?, ?> input);
-
protected abstract AbstractDOMRpcRoutingTableEntry newInstance(
Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls);
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.opendaylight.yangtools.util.concurrent.FluentFutures;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public final class DOMRpcRouter extends AbstractRegistration implements SchemaContextListener {
private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder().setNameFormat(
new DOMRpcImplementationNotAvailableException("No implementation of RPC %s available", type));
}
- return entry.invokeRpc(input);
+ return RpcInvocation.invoke(entry, input);
}
@Override
};
}
}
+
+ static final class RpcInvocation {
+ private static final Logger LOG = LoggerFactory.getLogger(RpcInvocation.class);
+
+ static FluentFuture<DOMRpcResult> invoke(final AbstractDOMRpcRoutingTableEntry entry,
+ final NormalizedNode<?, ?> input) {
+ if (entry instanceof UnknownDOMRpcRoutingTableEntry) {
+ return FluentFutures.immediateFailedFluentFuture(
+ new DOMRpcImplementationNotAvailableException("SchemaPath %s is not resolved to an RPC",
+ entry.getSchemaPath()));
+ } else if (entry instanceof RoutedDOMRpcRoutingTableEntry) {
+ return invokeRoutedRpc((RoutedDOMRpcRoutingTableEntry) entry, input);
+ } else if (entry instanceof GlobalDOMRpcRoutingTableEntry) {
+ return invokeGlobalRpc((GlobalDOMRpcRoutingTableEntry) entry, input);
+ }
+
+ return FluentFutures.immediateFailedFluentFuture(
+ new DOMRpcImplementationNotAvailableException("Unsupported RPC entry."));
+ }
+
+ private static FluentFuture<DOMRpcResult> invokeRoutedRpc(final RoutedDOMRpcRoutingTableEntry entry,
+ final NormalizedNode<?, ?> input) {
+ final Optional<NormalizedNode<?, ?>> maybeKey = NormalizedNodes.findNode(input,
+ entry.getRpcId().getContextReference());
+
+ // Routing key is present, attempt to deliver as a routed RPC
+ if (maybeKey.isPresent()) {
+ final NormalizedNode<?, ?> key = maybeKey.get();
+ final Object value = key.getValue();
+ if (value instanceof YangInstanceIdentifier) {
+ final YangInstanceIdentifier iid = (YangInstanceIdentifier) value;
+
+ // Find a DOMRpcImplementation for a specific iid
+ final List<DOMRpcImplementation> specificImpls = entry.getImplementations(iid);
+ if (specificImpls != null) {
+ return specificImpls.get(0)
+ .invokeRpc(DOMRpcIdentifier.create(entry.getSchemaPath(), iid), input);
+ }
+
+ LOG.debug("No implementation for context {} found will now look for wildcard id", iid);
+
+ // Find a DOMRpcImplementation for a wild card. Usually remote-rpc-connector would register an
+ // implementation this way
+ final List<DOMRpcImplementation> mayBeRemoteImpls =
+ entry.getImplementations(YangInstanceIdentifier.EMPTY);
+
+ if (mayBeRemoteImpls != null) {
+ return mayBeRemoteImpls.get(0)
+ .invokeRpc(DOMRpcIdentifier.create(entry.getSchemaPath(), iid), input);
+ }
+
+ } else {
+ LOG.warn("Ignoring wrong context value {}", value);
+ }
+ }
+
+ final List<DOMRpcImplementation> impls = entry.getImplementations(null);
+ if (impls != null) {
+ return impls.get(0).invokeRpc(entry.getRpcId(), input);
+ }
+
+ return FluentFutures.immediateFailedFluentFuture(
+ new DOMRpcImplementationNotAvailableException("No implementation of RPC %s available",
+ entry.getSchemaPath()));
+ }
+
+ private static FluentFuture<DOMRpcResult> invokeGlobalRpc(final GlobalDOMRpcRoutingTableEntry entry,
+ final NormalizedNode<?, ?> input) {
+ return entry.getImplementations(YangInstanceIdentifier.EMPTY).get(0).invokeRpc(entry.getRpcId(), input);
+ }
+ }
}
*/
package org.opendaylight.mdsal.dom.broker;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.FluentFuture;
import java.util.List;
import java.util.Map;
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.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
final class GlobalDOMRpcRoutingTableEntry extends AbstractDOMRpcRoutingTableEntry {
- private final DOMRpcIdentifier rpcId;
private GlobalDOMRpcRoutingTableEntry(final DOMRpcIdentifier rpcId, final Map<YangInstanceIdentifier,
List<DOMRpcImplementation>> impls) {
- super(rpcId.getType(), impls);
- this.rpcId = Preconditions.checkNotNull(rpcId);
+ super(rpcId, impls);
}
// We do not need the RpcDefinition, but this makes sure we do not
// forward something we don't know to be an RPC.
GlobalDOMRpcRoutingTableEntry(final RpcDefinition def, final Map<YangInstanceIdentifier,
List<DOMRpcImplementation>> impls) {
- super(def.getPath(), impls);
- this.rpcId = DOMRpcIdentifier.create(def.getPath());
- }
-
- @Override
- protected FluentFuture<DOMRpcResult> invokeRpc(final NormalizedNode<?, ?> input) {
- return getImplementations(YangInstanceIdentifier.EMPTY).get(0).invokeRpc(rpcId, input);
+ super(DOMRpcIdentifier.create(def.getPath()), impls);
}
@Override
protected GlobalDOMRpcRoutingTableEntry newInstance(final Map<YangInstanceIdentifier,
List<DOMRpcImplementation>> impls) {
- return new GlobalDOMRpcRoutingTableEntry(rpcId, impls);
+ return new GlobalDOMRpcRoutingTableEntry(getRpcId(), impls);
}
}
*/
package org.opendaylight.mdsal.dom.broker;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.FluentFuture;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
-import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
-import org.opendaylight.mdsal.dom.api.DOMRpcResult;
-import org.opendaylight.yangtools.util.concurrent.FluentFutures;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
final class RoutedDOMRpcRoutingTableEntry extends AbstractDOMRpcRoutingTableEntry {
- private static final Logger LOG = LoggerFactory.getLogger(RoutedDOMRpcRoutingTableEntry.class);
- private final DOMRpcIdentifier globalRpcId;
- private final YangInstanceIdentifier keyId;
- private RoutedDOMRpcRoutingTableEntry(final DOMRpcIdentifier globalRpcId,
- final YangInstanceIdentifier keyId,
+ private RoutedDOMRpcRoutingTableEntry(final DOMRpcIdentifier routedRpcId,
final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls) {
- super(globalRpcId.getType(), impls);
- this.keyId = Preconditions.checkNotNull(keyId);
- this.globalRpcId = Preconditions.checkNotNull(globalRpcId);
+ super(routedRpcId, impls);
}
RoutedDOMRpcRoutingTableEntry(final RpcDefinition def, final YangInstanceIdentifier keyId,
final Map<YangInstanceIdentifier, List<DOMRpcImplementation>> impls) {
- super(def.getPath(), impls);
- this.keyId = Preconditions.checkNotNull(keyId);
- this.globalRpcId = DOMRpcIdentifier.create(def.getPath());
- }
-
- @Override
- protected FluentFuture<DOMRpcResult> invokeRpc(final NormalizedNode<?, ?> input) {
- final Optional<NormalizedNode<?, ?>> maybeKey = NormalizedNodes.findNode(input, keyId);
-
- // Routing key is present, attempt to deliver as a routed RPC
- if (maybeKey.isPresent()) {
- final NormalizedNode<?, ?> key = maybeKey.get();
- final Object value = key.getValue();
- if (value instanceof YangInstanceIdentifier) {
- final YangInstanceIdentifier iid = (YangInstanceIdentifier) value;
-
- // Find a DOMRpcImplementation for a specific iid
- final List<DOMRpcImplementation> specificImpls = getImplementations(iid);
- if (specificImpls != null) {
- return specificImpls.get(0).invokeRpc(DOMRpcIdentifier.create(getSchemaPath(), iid), input);
- }
-
- LOG.debug("No implementation for context {} found will now look for wildcard id", iid);
-
- // Find a DOMRpcImplementation for a wild card. Usually remote-rpc-connector would register an
- // implementation this way
- final List<DOMRpcImplementation> mayBeRemoteImpls = getImplementations(YangInstanceIdentifier.EMPTY);
-
- if (mayBeRemoteImpls != null) {
- return mayBeRemoteImpls.get(0).invokeRpc(DOMRpcIdentifier.create(getSchemaPath(), iid), input);
- }
-
- } else {
- LOG.warn("Ignoring wrong context value {}", value);
- }
- }
-
- final List<DOMRpcImplementation> impls = getImplementations(null);
- if (impls != null) {
- return impls.get(0).invokeRpc(globalRpcId, input);
- }
-
- return FluentFutures.immediateFailedFluentFuture(
- new DOMRpcImplementationNotAvailableException("No implementation of RPC %s available", getSchemaPath()));
+ super(DOMRpcIdentifier.create(def.getPath(), keyId), impls);
}
@Override
protected RoutedDOMRpcRoutingTableEntry newInstance(final Map<YangInstanceIdentifier,
List<DOMRpcImplementation>> impls) {
- return new RoutedDOMRpcRoutingTableEntry(globalRpcId, keyId, impls);
+ return new RoutedDOMRpcRoutingTableEntry(getRpcId(), impls);
}
}
import com.google.common.util.concurrent.FluentFuture;
import java.util.List;
import java.util.Map;
+import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
import org.opendaylight.mdsal.dom.api.DOMRpcResult;
import org.opendaylight.yangtools.util.concurrent.FluentFutures;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
final class UnknownDOMRpcRoutingTableEntry extends AbstractDOMRpcRoutingTableEntry {
UnknownDOMRpcRoutingTableEntry(final SchemaPath schemaPath, final Map<YangInstanceIdentifier,
List<DOMRpcImplementation>> impls) {
- super(schemaPath, impls);
+ super(DOMRpcIdentifier.create(schemaPath), impls);
unknownRpc = FluentFutures.immediateFailedFluentFuture(
new DOMRpcImplementationNotAvailableException("SchemaPath %s is not resolved to an RPC", schemaPath));
}
- @Override
- protected FluentFuture<DOMRpcResult> invokeRpc(final NormalizedNode<?, ?> input) {
- return unknownRpc;
- }
-
@Override
protected UnknownDOMRpcRoutingTableEntry newInstance(final Map<YangInstanceIdentifier,
List<DOMRpcImplementation>> impls) {
import org.junit.Test;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
+import org.opendaylight.mdsal.dom.broker.DOMRpcRouter.RpcInvocation;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
rpcImplementation));
try {
- globalDOMRpcRoutingTableEntry.newInstance(rpcImplementations)
- .invokeRpc(TEST_CONTAINER).get(5, TimeUnit.SECONDS);
+ RpcInvocation.invoke(globalDOMRpcRoutingTableEntry.newInstance(rpcImplementations),
+ TEST_CONTAINER).get(5, TimeUnit.SECONDS);
fail("Expected DOMRpcImplementationNotAvailableException");
} catch (ExecutionException e) {
assertTrue(e.getCause() instanceof DOMRpcImplementationNotAvailableException);
import java.util.concurrent.TimeoutException;
import org.junit.Test;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementationNotAvailableException;
+import org.opendaylight.mdsal.dom.broker.DOMRpcRouter.RpcInvocation;
import org.opendaylight.mdsal.dom.broker.util.TestModel;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
assertNotNull(routedDOMRpcRoutingTableEntry.newInstance(new HashMap<>()));
try {
- routedDOMRpcRoutingTableEntry.invokeRpc(TEST_CHILD).get();
+ RpcInvocation.invoke(routedDOMRpcRoutingTableEntry, TEST_CHILD).get();
fail("Expected DOMRpcImplementationNotAvailableException");
} catch (ExecutionException e) {
assertTrue(e.getCause() instanceof DOMRpcImplementationNotAvailableException);
import java.util.Map;
import org.junit.Test;
import org.opendaylight.mdsal.dom.api.DOMRpcImplementation;
+import org.opendaylight.mdsal.dom.broker.DOMRpcRouter.RpcInvocation;
import org.opendaylight.mdsal.dom.broker.util.TestModel;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
assertNotNull(test);
assertNotNull(test.newInstance(emptyImpls));
- assertNotNull(test.invokeRpc(TEST_CONTAINER));
+ assertNotNull(RpcInvocation.invoke(test, TEST_CONTAINER));
assertNotNull(test.getImplementations());
assertEquals(test.getImplementations(YangInstanceIdentifier.EMPTY), TEST_LIST);
assertTrue(test.containsContext(YangInstanceIdentifier.EMPTY));