X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fsharding%2FDistributedShardedDOMDataTree.java;h=35f5e998825951829be49b5e57e36a0ce3615cd4;hp=564fb978bee42cc41c4f87c2fa8f03a94fb0c57d;hb=9e6714ce7693d8e3c00adf72dafce78041d3a7cc;hpb=d65678cef128d33202318409ec52146722ae5318 diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/sharding/DistributedShardedDOMDataTree.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/sharding/DistributedShardedDOMDataTree.java index 564fb978be..35f5e99882 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/sharding/DistributedShardedDOMDataTree.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/sharding/DistributedShardedDOMDataTree.java @@ -161,7 +161,7 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat createPrefixConfigShard(distributedOperDatastore); } - private void createPrefixConfigShard(final AbstractDataStore dataStore) { + private static void createPrefixConfigShard(final AbstractDataStore dataStore) { Configuration configuration = dataStore.getActorContext().getConfiguration(); Collection memberNames = configuration.getUniqueMemberNamesForAllShards(); CreateShard createShardMessage = @@ -307,7 +307,7 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat LOG.debug("{} - Received success from remote nodes, creating producer:{}", distributedConfigDatastore.getActorContext().getClusterWrapper().getCurrentMemberName(), subtrees); return new ProxyProducer(producer, subtrees, shardedDataTreeActor, - distributedConfigDatastore.getActorContext()); + distributedConfigDatastore.getActorContext(), shards); } else if (response instanceof Exception) { closeProducer(producer); throw Throwables.propagate((Exception) response); @@ -451,12 +451,12 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat Futures.addCallback(future, new FutureCallback() { @Override - public void onSuccess(@Nullable Void result) { + public void onSuccess(@Nullable final Void result) { LOG.debug("{} - Succesfuly removed shard for {}", memberName, prefix); } @Override - public void onFailure(Throwable throwable) { + public void onFailure(final Throwable throwable) { LOG.error("Removal of shard {} from configuration failed.", prefix, throwable); } }); @@ -642,14 +642,21 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat @GuardedBy("shardAccessMap") private final Map shardAccessMap = new HashMap<>(); + // We don't have to guard access to shardTable in ProxyProducer. + // ShardTable's entries relevant to this ProxyProducer shouldn't + // change during producer's lifetime. + private final DOMDataTreePrefixTable> shardTable; + ProxyProducer(final DOMDataTreeProducer delegate, final Collection subtrees, final ActorRef shardDataTreeActor, - final ActorContext actorContext) { + final ActorContext actorContext, + final DOMDataTreePrefixTable> shardLayout) { this.delegate = Preconditions.checkNotNull(delegate); this.subtrees = Preconditions.checkNotNull(subtrees); this.shardDataTreeActor = Preconditions.checkNotNull(shardDataTreeActor); this.actorContext = Preconditions.checkNotNull(actorContext); + this.shardTable = Preconditions.checkNotNull(shardLayout); } @Nonnull @@ -670,6 +677,7 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat @SuppressWarnings("checkstyle:IllegalCatch") public void close() throws DOMDataTreeProducerException { delegate.close(); + synchronized (shardAccessMap) { shardAccessMap.values().forEach(CDSShardAccessImpl::close); } @@ -690,19 +698,27 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat @Nonnull @Override public CDSShardAccess getShardAccess(@Nonnull final DOMDataTreeIdentifier subtree) { + Preconditions.checkArgument( + subtrees.stream().anyMatch(dataTreeIdentifier -> dataTreeIdentifier.contains(subtree)), + "Subtree {} is not controlled by this producer {}", subtree, this); + + final DOMDataTreePrefixTableEntry> lookup = + shardTable.lookup(subtree); + Preconditions.checkState(lookup != null, "Subtree {} is not contained in any registered shard."); + + final DOMDataTreeIdentifier lookupId = lookup.getValue().getPrefix(); + synchronized (shardAccessMap) { - Preconditions.checkArgument(subtrees.contains(subtree), - "Subtree {} is not controlled by this producer {}", subtree, this); - if (shardAccessMap.get(subtree) != null) { - return shardAccessMap.get(subtree); + if (shardAccessMap.get(lookupId) != null) { + return shardAccessMap.get(lookupId); } // TODO Maybe we can have static factory method and return the same instance // for same subtrees. But maybe it is not needed since there can be only one // producer attached to some subtree at a time. And also how we can close ShardAccess // then - final CDSShardAccessImpl shardAccess = new CDSShardAccessImpl(subtree, actorContext); - shardAccessMap.put(subtree, shardAccess); + final CDSShardAccessImpl shardAccess = new CDSShardAccessImpl(lookupId, actorContext); + shardAccessMap.put(lookupId, shardAccess); return shardAccess; } }