X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fsharding%2FDistributedShardedDOMDataTree.java;h=564fb978bee42cc41c4f87c2fa8f03a94fb0c57d;hb=81f7896feb2812430ea138d67e68e00d205974b6;hp=6e53a2791234977ce4e8362fbc07f01d79d88af5;hpb=ef3b9a8300db1c791f2c4088d39152ccf9f5b97c;p=controller.git 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 6e53a27912..564fb978be 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * Copyright (c) 2016, 2017 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, @@ -32,7 +32,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.EnumMap; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.CompletionStage; @@ -46,7 +48,7 @@ import org.opendaylight.controller.cluster.ActorSystemProvider; import org.opendaylight.controller.cluster.access.concepts.MemberName; import org.opendaylight.controller.cluster.databroker.actors.dds.DataStoreClient; import org.opendaylight.controller.cluster.databroker.actors.dds.SimpleDataStoreClientActor; -import org.opendaylight.controller.cluster.datastore.DistributedDataStore; +import org.opendaylight.controller.cluster.datastore.AbstractDataStore; import org.opendaylight.controller.cluster.datastore.Shard; import org.opendaylight.controller.cluster.datastore.config.Configuration; import org.opendaylight.controller.cluster.datastore.config.ModuleShardConfiguration; @@ -54,6 +56,8 @@ import org.opendaylight.controller.cluster.datastore.messages.CreateShard; import org.opendaylight.controller.cluster.datastore.shardstrategy.ModuleShardStrategy; import org.opendaylight.controller.cluster.datastore.utils.ActorContext; import org.opendaylight.controller.cluster.datastore.utils.ClusterUtils; +import org.opendaylight.controller.cluster.dom.api.CDSDataTreeProducer; +import org.opendaylight.controller.cluster.dom.api.CDSShardAccess; import org.opendaylight.controller.cluster.sharding.ShardedDataTreeActor.ShardedDataTreeActorCreator; import org.opendaylight.controller.cluster.sharding.messages.InitConfigListener; import org.opendaylight.controller.cluster.sharding.messages.LookupPrefixShard; @@ -108,8 +112,8 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat private final ShardedDOMDataTree shardedDOMDataTree; private final ActorSystem actorSystem; - private final DistributedDataStore distributedOperDatastore; - private final DistributedDataStore distributedConfigDatastore; + private final AbstractDataStore distributedOperDatastore; + private final AbstractDataStore distributedConfigDatastore; private final ActorRef shardedDataTreeActor; private final MemberName memberName; @@ -130,8 +134,8 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat private final PrefixedShardConfigUpdateHandler updateHandler; public DistributedShardedDOMDataTree(final ActorSystemProvider actorSystemProvider, - final DistributedDataStore distributedOperDatastore, - final DistributedDataStore distributedConfigDatastore) { + final AbstractDataStore distributedOperDatastore, + final AbstractDataStore distributedConfigDatastore) { this.actorSystem = Preconditions.checkNotNull(actorSystemProvider).getActorSystem(); this.distributedOperDatastore = Preconditions.checkNotNull(distributedOperDatastore); this.distributedConfigDatastore = Preconditions.checkNotNull(distributedConfigDatastore); @@ -157,7 +161,7 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat createPrefixConfigShard(distributedOperDatastore); } - private void createPrefixConfigShard(final DistributedDataStore dataStore) { + private void createPrefixConfigShard(final AbstractDataStore dataStore) { Configuration configuration = dataStore.getActorContext().getConfiguration(); Collection memberNames = configuration.getUniqueMemberNamesForAllShards(); CreateShard createShardMessage = @@ -184,8 +188,11 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat * Finally, we need to be sure that default shards for both operational and * configuration data stores are up and running and we have distributed * shards frontend created for them. + * + *

+ * This is intended to be invoked by blueprint as initialization method. */ - void init() { + public void init() { // create our writers to the configuration try { LOG.debug("{} - starting config shard lookup.", @@ -391,11 +398,11 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat private void createShardFrontend(final DOMDataTreeIdentifier prefix) { LOG.debug("Member {}: Creating CDS shard for prefix: {}", memberName, prefix); final String shardName = ClusterUtils.getCleanShardName(prefix.getRootIdentifier()); - final DistributedDataStore distributedDataStore = + final AbstractDataStore distributedDataStore = prefix.getDatastoreType().equals(org.opendaylight.mdsal.common.api.LogicalDatastoreType.CONFIGURATION) ? distributedConfigDatastore : distributedOperDatastore; - try (final DOMDataTreeProducer producer = localCreateProducer(Collections.singletonList(prefix))) { + try (DOMDataTreeProducer producer = localCreateProducer(Collections.singletonList(prefix))) { final Entry entry = createDatastoreClient(shardName, distributedDataStore.getActorContext()); @@ -457,8 +464,9 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat DOMDataTreePrefixTableEntry> lookupShardFrontend( final DOMDataTreeIdentifier prefix) { - return shards.lookup(prefix); - + synchronized (shards) { + return shards.lookup(prefix); + } } DOMDataTreeProducer localCreateProducer(final Collection prefix) { @@ -608,13 +616,13 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat final Future closeFuture = ask.transform( new Mapper() { @Override - public Void apply(Object parameter) { + public Void apply(final Object parameter) { return null; } }, new Mapper() { @Override - public Throwable apply(Throwable throwable) { + public Throwable apply(final Throwable throwable) { return throwable; } }, actorSystem.dispatcher()); @@ -623,12 +631,16 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat } } - private static final class ProxyProducer extends ForwardingObject implements DOMDataTreeProducer { + // TODO what about producers created by this producer? + // They should also be CDSProducers + private static final class ProxyProducer extends ForwardingObject implements CDSDataTreeProducer { private final DOMDataTreeProducer delegate; private final Collection subtrees; private final ActorRef shardDataTreeActor; private final ActorContext actorContext; + @GuardedBy("shardAccessMap") + private final Map shardAccessMap = new HashMap<>(); ProxyProducer(final DOMDataTreeProducer delegate, final Collection subtrees, @@ -655,12 +667,16 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat } @Override + @SuppressWarnings("checkstyle:IllegalCatch") public void close() throws DOMDataTreeProducerException { delegate.close(); + synchronized (shardAccessMap) { + shardAccessMap.values().forEach(CDSShardAccessImpl::close); + } final Object o = actorContext.executeOperation(shardDataTreeActor, new ProducerRemoved(subtrees)); if (o instanceof DOMDataTreeProducerException) { - throw ((DOMDataTreeProducerException) o); + throw (DOMDataTreeProducerException) o; } else if (o instanceof Throwable) { throw new DOMDataTreeProducerException("Unable to close producer", (Throwable) o); } @@ -670,5 +686,25 @@ public class DistributedShardedDOMDataTree implements DOMDataTreeService, DOMDat protected DOMDataTreeProducer delegate() { return delegate; } + + @Nonnull + @Override + public CDSShardAccess getShardAccess(@Nonnull final DOMDataTreeIdentifier subtree) { + 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); + } + + // 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); + return shardAccess; + } + } } }