package org.opendaylight.mdsal.dom.broker;
import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@GuardedBy("this")
private final DOMDataTreePrefixTable<DOMDataTreeProducer> producers = DOMDataTreePrefixTable.create();
-
void removeShard(final ShardRegistration<?> reg) {
final DOMDataTreeIdentifier prefix = reg.getPrefix();
final ShardRegistration<?> parentReg;
}
@Override
- public <T extends DOMDataTreeShard> ListenerRegistration<T> registerDataTreeShard(final DOMDataTreeIdentifier prefix, final T shard) throws DOMDataTreeShardingConflictException {
+ public <T extends DOMDataTreeShard> ListenerRegistration<T> registerDataTreeShard(
+ final DOMDataTreeIdentifier prefix, final T shard, final DOMDataTreeProducer producer)
+ throws DOMDataTreeShardingConflictException {
+
+ final DOMDataTreeIdentifier firstSubtree = Iterables.getOnlyElement(((
+ ShardedDOMDataTreeProducer) producer).getSubtrees());
+ Preconditions.checkArgument(firstSubtree != null, "Producer that is used to verify namespace claim can"
+ + " only claim a single namespace");
+ Preconditions.checkArgument(prefix.equals(firstSubtree), "Trying to register shard to a different namespace"
+ + " than the producer has claimed");
+
final ShardRegistration<T> reg;
final ShardRegistration<?> parentReg;
shards.store(prefix, reg);
- // FIXME: update any producers/registrations
+ ((ShardedDOMDataTreeProducer) producer).subshardAdded(Collections.singletonMap(prefix, shard));
}
// Notify the parent shard
@GuardedBy("this")
private DOMDataTreeProducer findProducer(final DOMDataTreeIdentifier subtree) {
- DOMDataTreePrefixTableEntry<DOMDataTreeProducer> producerEntry = producers.lookup(subtree);
+ final DOMDataTreePrefixTableEntry<DOMDataTreeProducer> producerEntry = producers.lookup(subtree);
if (producerEntry != null) {
return producerEntry.getValue();
}
}
@GuardedBy("this")
- private DOMDataTreeProducer createProducer(final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap) {
+ private DOMDataTreeProducer createProducer(final Collection<DOMDataTreeIdentifier> subtrees,
+ final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap) {
// Record the producer's attachment points
- final DOMDataTreeProducer ret = ShardedDOMDataTreeProducer.create(this, shardMap);
- for (final DOMDataTreeIdentifier s : shardMap.keySet()) {
- producers.store(s, ret);
+ final DOMDataTreeProducer ret = ShardedDOMDataTreeProducer.create(this, subtrees, shardMap);
+ for (final DOMDataTreeIdentifier subtree : subtrees) {
+ producers.store(subtree, ret);
}
return ret;
Preconditions.checkArgument(!subtrees.isEmpty(), "Subtrees may not be empty");
final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap = new HashMap<>();
- for (final DOMDataTreeIdentifier s : subtrees) {
+ for (final DOMDataTreeIdentifier subtree : subtrees) {
// Attempting to create a disconnected producer -- all subtrees have to be unclaimed
- final DOMDataTreeProducer producer = findProducer(s);
- Preconditions.checkArgument(producer == null, "Subtree %s is attached to producer %s", s, producer);
+ final DOMDataTreeProducer producer = findProducer(subtree);
+ Preconditions.checkArgument(producer == null, "Subtree %s is attached to producer %s", subtree, producer);
- shardMap.put(s, shards.lookup(s).getValue().getInstance());
+ final DOMDataTreePrefixTableEntry<ShardRegistration<?>> possibleShardReg = shards.lookup(subtree);
+ if (possibleShardReg != null && possibleShardReg.getValue() != null) {
+ shardMap.put(subtree, possibleShardReg.getValue().getInstance());
+ }
}
- return createProducer(shardMap);
+ return createProducer(subtrees, shardMap);
}
- synchronized DOMDataTreeProducer createProducer(final ShardedDOMDataTreeProducer parent, final Collection<DOMDataTreeIdentifier> subtrees) {
+ synchronized DOMDataTreeProducer createProducer(final ShardedDOMDataTreeProducer parent,
+ final Collection<DOMDataTreeIdentifier> subtrees) {
Preconditions.checkNotNull(parent);
final Map<DOMDataTreeIdentifier, DOMDataTreeShard> shardMap = new HashMap<>();
shardMap.put(s, shards.lookup(s).getValue().getInstance());
}
- return createProducer(shardMap);
+ return createProducer(subtrees, shardMap);
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
@Override
public synchronized <T extends DOMDataTreeListener> ListenerRegistration<T> registerListener(final T listener,
final Collection<DOMDataTreeIdentifier> subtrees, final boolean allowRxMerges,
ShardedDOMDataTreeListenerContext.create(listener, subtrees, allowRxMerges);
try {
// FIXME: Add attachment of producers
- for (DOMDataTreeProducer producer : producers) {
+ for (final DOMDataTreeProducer producer : producers) {
Preconditions.checkArgument(producer instanceof ShardedDOMDataTreeProducer);
- ShardedDOMDataTreeProducer castedProducer = ((ShardedDOMDataTreeProducer) producer);
+ final ShardedDOMDataTreeProducer castedProducer = ((ShardedDOMDataTreeProducer) producer);
simpleLoopCheck(subtrees, castedProducer.getSubtrees());
// FIXME: We should also unbound listeners
castedProducer.boundToListener(listenerContext);
}
- for (DOMDataTreeIdentifier subtree : subtrees) {
- DOMDataTreeShard shard = shards.lookup(subtree).getValue().getInstance();
+ for (final DOMDataTreeIdentifier subtree : subtrees) {
+ final DOMDataTreeShard shard = shards.lookup(subtree).getValue().getInstance();
// FIXME: What should we do if listener is wildcard? And shards are on per
// node basis?
Preconditions.checkArgument(shard instanceof DOMStoreTreeChangePublisher,
listenerContext.register(subtree, (DOMStoreTreeChangePublisher) shard);
}
- } catch (Exception e) {
+ } catch (final Exception e) {
listenerContext.close();
throw e;
}
};
}
- private static void simpleLoopCheck(Collection<DOMDataTreeIdentifier> listen, Set<DOMDataTreeIdentifier> writes)
- throws DOMDataTreeLoopException {
- for(DOMDataTreeIdentifier listenPath : listen) {
- for (DOMDataTreeIdentifier writePath : writes) {
+ private static void simpleLoopCheck(final Collection<DOMDataTreeIdentifier> listen,
+ final Set<DOMDataTreeIdentifier> writes) throws DOMDataTreeLoopException {
+ for (final DOMDataTreeIdentifier listenPath : listen) {
+ for (final DOMDataTreeIdentifier writePath : writes) {
if (listenPath.contains(writePath)) {
throw new DOMDataTreeLoopException(String.format(
"Listener must not listen on parent (%s), and also writes child (%s)", listenPath,
}
}
- void removeListener(ShardedDOMDataTreeListenerContext<?> listener) {
+ void removeListener(final ShardedDOMDataTreeListenerContext<?> listener) {
// FIXME: detach producers
listener.close();
}