From: Tom Pantelis Date: Fri, 7 Aug 2015 20:20:48 +0000 (-0400) Subject: Bug 4105: Add EntityOwnershipShard X-Git-Tag: release/beryllium~315 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=0b9b1dcba996fd76e0e1bde731692570747f5efd Bug 4105: Add EntityOwnershipShard Added the EntityOwnershipShard and modified DistributedEntityOwnershipService to create it. Change-Id: Id173b148797e90ff5d38d7f7cde177d303943181 Signed-off-by: Tom Pantelis --- diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStore.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStore.java index f655186920..96f5ce816b 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStore.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/DistributedDataStore.java @@ -202,8 +202,7 @@ public class DistributedDataStore implements DOMStore, SchemaContextListener, DistributedDataStoreFactory.destroyInstance(this); } - @VisibleForTesting - ActorContext getActorContext() { + public ActorContext getActorContext() { return actorContext; } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java index dd1c0ad6ff..7b34f5df60 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/Shard.java @@ -162,14 +162,8 @@ public class Shard extends RaftActor { datastoreContext.getShardTransactionCommitTimeoutInSeconds(), TimeUnit.SECONDS) / 2; } - public static Props props(final ShardIdentifier name, - final Map peerAddresses, - final DatastoreContext datastoreContext, final SchemaContext schemaContext) { - Preconditions.checkNotNull(name, "name should not be null"); - Preconditions.checkNotNull(peerAddresses, "peerAddresses should not be null"); - Preconditions.checkNotNull(datastoreContext, "dataStoreContext should not be null"); - Preconditions.checkNotNull(schemaContext, "schemaContext should not be null"); - + public static Props props(final ShardIdentifier name, final Map peerAddresses, + final DatastoreContext datastoreContext, final SchemaContext schemaContext) { return Props.create(new ShardCreator(name, peerAddresses, datastoreContext, schemaContext)); } @@ -291,7 +285,7 @@ public class Shard extends RaftActor { leaderPayloadVersion); } - private void onDatastoreContext(DatastoreContext context) { + protected void onDatastoreContext(DatastoreContext context) { datastoreContext = context; commitCoordinator.setQueueCapacity(datastoreContext.getShardTransactionCommitQueueCapacity()); @@ -690,22 +684,29 @@ public class Shard extends RaftActor { return commitCoordinator; } + protected abstract static class AbstractShardCreator implements Creator { + private static final long serialVersionUID = 1L; - private static class ShardCreator implements Creator { + protected final ShardIdentifier name; + protected final Map peerAddresses; + protected final DatastoreContext datastoreContext; + protected final SchemaContext schemaContext; - private static final long serialVersionUID = 1L; + protected AbstractShardCreator(final ShardIdentifier name, final Map peerAddresses, + final DatastoreContext datastoreContext, final SchemaContext schemaContext) { + this.name = Preconditions.checkNotNull(name, "name should not be null"); + this.peerAddresses = Preconditions.checkNotNull(peerAddresses, "peerAddresses should not be null"); + this.datastoreContext = Preconditions.checkNotNull(datastoreContext, "dataStoreContext should not be null"); + this.schemaContext = Preconditions.checkNotNull(schemaContext, "schemaContext should not be null"); + } + } - final ShardIdentifier name; - final Map peerAddresses; - final DatastoreContext datastoreContext; - final SchemaContext schemaContext; + private static class ShardCreator extends AbstractShardCreator { + private static final long serialVersionUID = 1L; ShardCreator(final ShardIdentifier name, final Map peerAddresses, final DatastoreContext datastoreContext, final SchemaContext schemaContext) { - this.name = name; - this.peerAddresses = peerAddresses; - this.datastoreContext = datastoreContext; - this.schemaContext = schemaContext; + super(name, peerAddresses, datastoreContext, schemaContext); } @Override diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/DistributedEntityOwnershipService.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/DistributedEntityOwnershipService.java index a4025c55af..ca315435cf 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/DistributedEntityOwnershipService.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/DistributedEntityOwnershipService.java @@ -7,7 +7,12 @@ */ package org.opendaylight.controller.cluster.datastore.entityownership; +import akka.actor.ActorRef; +import akka.dispatch.OnComplete; +import akka.util.Timeout; +import java.util.concurrent.TimeUnit; import org.opendaylight.controller.cluster.datastore.DistributedDataStore; +import org.opendaylight.controller.cluster.datastore.messages.CreateShard; import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException; import org.opendaylight.controller.md.sal.common.api.clustering.Entity; import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipCandidate; @@ -17,6 +22,7 @@ import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipL import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import scala.concurrent.Future; /** * The distributed implementation of the EntityOwnershipService. @@ -25,6 +31,8 @@ import org.slf4j.LoggerFactory; */ public class DistributedEntityOwnershipService implements EntityOwnershipService, AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(DistributedEntityOwnershipService.class); + static final String ENTITY_OWNERSHIP_SHARD_NAME = "entity-ownership"; + private static final Timeout MESSAGE_TIMEOUT = new Timeout(1, TimeUnit.MINUTES); private final DistributedDataStore datastore; @@ -33,7 +41,25 @@ public class DistributedEntityOwnershipService implements EntityOwnershipService } public void start() { - LOG.info("DistributedEntityOwnershipService starting"); + ActorRef shardManagerActor = datastore.getActorContext().getShardManager(); + + CreateShard createShard = new CreateShard(ENTITY_OWNERSHIP_SHARD_NAME, + datastore.getActorContext().getConfiguration().getUniqueMemberNamesForAllShards(), + new EntityOwnershipShardPropsCreator(), null); + + Future createFuture = datastore.getActorContext().executeOperationAsync(shardManagerActor, + createShard, MESSAGE_TIMEOUT); + + createFuture.onComplete(new OnComplete() { + @Override + public void onComplete(Throwable failure, Object response) { + if(failure != null) { + LOG.error("Failed to create {} shard", ENTITY_OWNERSHIP_SHARD_NAME); + } else { + LOG.info("Successfully created {} shard", ENTITY_OWNERSHIP_SHARD_NAME); + } + } + }, datastore.getActorContext().getClientDispatcher()); } @Override diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/EntityOwnershipShard.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/EntityOwnershipShard.java new file mode 100644 index 0000000000..2fabf0a878 --- /dev/null +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/EntityOwnershipShard.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2015 Brocade Communications 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, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.cluster.datastore.entityownership; + +import akka.actor.Props; +import java.util.Map; +import org.opendaylight.controller.cluster.datastore.DatastoreContext; +import org.opendaylight.controller.cluster.datastore.Shard; +import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +/** + * Special Shard for EntityOwnership. + * + * @author Thomas Pantelis + */ +public class EntityOwnershipShard extends Shard { + + private static DatastoreContext noPersistenceDatastoreContext(DatastoreContext datastoreContext) { + return DatastoreContext.newBuilderFrom(datastoreContext).persistent(false).build(); + } + + protected EntityOwnershipShard(ShardIdentifier name, Map peerAddresses, + DatastoreContext datastoreContext, SchemaContext schemaContext) { + super(name, peerAddresses, noPersistenceDatastoreContext(datastoreContext), schemaContext); + } + + @Override + protected void onDatastoreContext(DatastoreContext context) { + super.onDatastoreContext(noPersistenceDatastoreContext(context)); + } + + public static Props props(final ShardIdentifier name, final Map peerAddresses, + final DatastoreContext datastoreContext, final SchemaContext schemaContext) { + return Props.create(new Creator(name, peerAddresses, datastoreContext, schemaContext)); + } + + private static class Creator extends AbstractShardCreator { + private static final long serialVersionUID = 1L; + + Creator(final ShardIdentifier name, final Map peerAddresses, + final DatastoreContext datastoreContext, final SchemaContext schemaContext) { + super(name, peerAddresses, datastoreContext, schemaContext); + } + + @Override + public Shard create() throws Exception { + return new EntityOwnershipShard(name, peerAddresses, datastoreContext, schemaContext); + } + } +} diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/EntityOwnershipShardPropsCreator.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/EntityOwnershipShardPropsCreator.java new file mode 100644 index 0000000000..2335d2948b --- /dev/null +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/entityownership/EntityOwnershipShardPropsCreator.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2015 Brocade Communications 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, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.cluster.datastore.entityownership; + +import akka.actor.Props; +import java.util.Map; +import org.opendaylight.controller.cluster.datastore.DatastoreContext; +import org.opendaylight.controller.cluster.datastore.ShardPropsCreator; +import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +/** + * Implementation of ShardPropsCreator that creates a Props instance for the EntityOwnershipShard class. + * + * @author Thomas Pantelis + */ +public class EntityOwnershipShardPropsCreator implements ShardPropsCreator { + + @Override + public Props newProps(ShardIdentifier shardId, Map peerAddresses, + DatastoreContext datastoreContext, SchemaContext schemaContext) { + return EntityOwnershipShard.props(shardId, peerAddresses, datastoreContext, schemaContext); + } +} diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/entityownership/DistributedEntityOwnershipServiceTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/entityownership/DistributedEntityOwnershipServiceTest.java new file mode 100644 index 0000000000..b7f75c98f3 --- /dev/null +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/entityownership/DistributedEntityOwnershipServiceTest.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2015 Brocade Communications 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, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.cluster.datastore.entityownership; + +import static org.junit.Assert.assertNotNull; +import akka.actor.ActorRef; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; +import org.junit.Before; +import org.junit.Test; +import org.opendaylight.controller.cluster.datastore.AbstractActorTest; +import org.opendaylight.controller.cluster.datastore.DatastoreContext; +import org.opendaylight.controller.cluster.datastore.DistributedDataStore; +import org.opendaylight.controller.cluster.datastore.utils.MockClusterWrapper; +import org.opendaylight.controller.cluster.datastore.utils.MockConfiguration; +import org.opendaylight.controller.md.cluster.datastore.model.TestModel; +import scala.concurrent.Await; +import scala.concurrent.Future; +import scala.concurrent.duration.Duration; + +/** + * Unit tests for DistributedEntityOwnershipService. + * + * @author Thomas Pantelis + */ +public class DistributedEntityOwnershipServiceTest extends AbstractActorTest { + private static int ID_COUNTER = 1; + + private final String dataStoreType = "config" + ID_COUNTER++; + private DistributedEntityOwnershipService service; + private DistributedDataStore dataStore; + + @Before + public void setUp() throws Exception { + DatastoreContext datastoreContext = DatastoreContext.newBuilder().dataStoreType(dataStoreType). + shardInitializationTimeout(10, TimeUnit.SECONDS).build(); + dataStore = new DistributedDataStore(getSystem(), new MockClusterWrapper(), + new MockConfiguration(Collections.>emptyMap()), datastoreContext ); + + dataStore.onGlobalContextUpdated(TestModel.createTestContext()); + + service = new DistributedEntityOwnershipService(dataStore); + } + + @Test + public void testEntityOwnershipShardCreated() throws Exception { + service.start(); + + Future future = dataStore.getActorContext().findLocalShardAsync( + DistributedEntityOwnershipService.ENTITY_OWNERSHIP_SHARD_NAME); + ActorRef shardActor = Await.result(future, Duration.create(10, TimeUnit.SECONDS)); + assertNotNull(DistributedEntityOwnershipService.ENTITY_OWNERSHIP_SHARD_NAME + " not found", shardActor); + } + + @Test + public void testRegisterCandidate() { + } + + @Test + public void testRegisterListener() { + } +}