From 43fb391bf873b252383a8d736b2651b04da8d40d Mon Sep 17 00:00:00 2001 From: Tom Pantelis Date: Fri, 10 Mar 2017 18:03:11 -0500 Subject: [PATCH] Bug 7814: Fix InvalidActorNameException When a read tx actor is created in the Shard, the actor name is generated as eg "shard-member-1:datastore-operational@0:19" where 0 is the instance's static generation id and 19 is the tx id. If the tx was created from a chain, the chain's history id is appended. So every part of the name is constant for the controller instance except the tx id, which is generated via a counter in AbstractTransactionContextFactory, and the history id which is also generated via a counter. The counters do make the full tx id unique in the cluster. However if multiple shards are involved in a single front-end transaction, they all have the same tx id and thus the actor names generated by each shard would be the same. It seems that's what occurred in Bug 7814. Therefore I changed the actor name to include the shard name. Change-Id: Iacb11bb401bd6bded38847690f8009c115ee0637 Signed-off-by: Tom Pantelis --- .../controller/cluster/datastore/Shard.java | 4 ++-- .../ShardTransactionActorFactory.java | 24 +++++++++++-------- .../cluster/datastore/ShardTest.java | 10 ++++---- 3 files changed, 22 insertions(+), 16 deletions(-) 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 423323187f..7ca79fc234 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 @@ -209,8 +209,8 @@ public class Shard extends RaftActor { getRaftActorContext().getConfigParams().getIsolatedCheckIntervalInMillis()); transactionActorFactory = new ShardTransactionActorFactory(store, datastoreContext, - new Dispatchers(context().system().dispatchers()).getDispatcherPath( - Dispatchers.DispatcherType.Transaction), self(), getContext(), shardMBean); + new Dispatchers(context().system().dispatchers()).getDispatcherPath(Dispatchers.DispatcherType.Transaction), + self(), getContext(), shardMBean, builder.getId().getShardName()); snapshotCohort = ShardSnapshotCohort.create(getContext(), builder.getId().getMemberName(), store, LOG, this.name); diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardTransactionActorFactory.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardTransactionActorFactory.java index 0ba36640a8..8e9c762bf1 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardTransactionActorFactory.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/ShardTransactionActorFactory.java @@ -29,26 +29,30 @@ class ShardTransactionActorFactory { private final ShardStats shardMBean; private final UntypedActorContext actorContext; private final ActorRef shardActor; + private final String shardName; ShardTransactionActorFactory(ShardDataTree dataTree, DatastoreContext datastoreContext, - String txnDispatcherPath, ActorRef shardActor, UntypedActorContext actorContext, ShardStats shardMBean) { + String txnDispatcherPath, ActorRef shardActor, UntypedActorContext actorContext, ShardStats shardMBean, + String shardName) { this.dataTree = Preconditions.checkNotNull(dataTree); - this.datastoreContext = datastoreContext; - this.txnDispatcherPath = txnDispatcherPath; - this.shardMBean = shardMBean; - this.actorContext = actorContext; - this.shardActor = shardActor; + this.datastoreContext = Preconditions.checkNotNull(datastoreContext); + this.txnDispatcherPath = Preconditions.checkNotNull(txnDispatcherPath); + this.shardMBean = Preconditions.checkNotNull(shardMBean); + this.actorContext = Preconditions.checkNotNull(actorContext); + this.shardActor = Preconditions.checkNotNull(shardActor); + this.shardName = Preconditions.checkNotNull(shardName); } - private static String actorNameFor(final TransactionIdentifier txId) { + private String actorNameFor(final TransactionIdentifier txId) { final LocalHistoryIdentifier historyId = txId.getHistoryId(); final ClientIdentifier clientId = historyId.getClientId(); final FrontendIdentifier frontendId = clientId.getFrontendId(); final StringBuilder sb = new StringBuilder("shard-"); - sb.append(frontendId.getMemberName().getName()).append(':'); - sb.append(frontendId.getClientType().getName()).append('@'); - sb.append(clientId.getGeneration()).append(':'); + sb.append(shardName).append('-') + .append(frontendId.getMemberName().getName()).append(':') + .append(frontendId.getClientType().getName()).append('@') + .append(clientId.getGeneration()).append(':'); if (historyId.getHistoryId() != 0) { sb.append(historyId.getHistoryId()).append('-'); } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTest.java index d484f99696..45239ac63f 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/ShardTest.java @@ -373,8 +373,9 @@ public class ShardTest extends AbstractShardTest { CreateTransactionReply.class); final String path = reply.getTransactionPath().toString(); - assertTrue("Unexpected transaction path " + path, path - .startsWith("akka://test/user/testCreateTransaction/shard-member-1:ShardTransactionTest@0:")); + assertTrue("Unexpected transaction path " + path, path.startsWith(String.format( + "akka://test/user/testCreateTransaction/shard-%s-%s:ShardTransactionTest@0:", + shardID.getShardName(), shardID.getMemberName().getName()))); } }; } @@ -394,8 +395,9 @@ public class ShardTest extends AbstractShardTest { CreateTransactionReply.class); final String path = reply.getTransactionPath().toString(); - assertTrue("Unexpected transaction path " + path, path.startsWith( - "akka://test/user/testCreateTransactionOnChain/shard-member-1:ShardTransactionTest@0:")); + assertTrue("Unexpected transaction path " + path, path.startsWith(String.format( + "akka://test/user/testCreateTransactionOnChain/shard-%s-%s:ShardTransactionTest@0:", + shardID.getShardName(), shardID.getMemberName().getName()))); } }; } -- 2.36.6