import java.util.AbstractMap.SimpleEntry;
import java.util.Collections;
import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import org.opendaylight.controller.cluster.datastore.messages.CloseTransactionChain;
import org.opendaylight.controller.cluster.datastore.utils.ActorContext;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreReadWriteTransaction;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreTransactionChain;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import scala.concurrent.Future;
import scala.concurrent.Promise;
* TransactionChainProxy acts as a proxy for a DOMStoreTransactionChain created on a remote shard
*/
public class TransactionChainProxy implements DOMStoreTransactionChain {
+
+ private static final Logger LOG = LoggerFactory.getLogger(TransactionChainProxy.class);
+
private interface State {
boolean isReady();
private final ActorContext actorContext;
private final String transactionChainId;
private volatile State state = IDLE_STATE;
+ private static final AtomicInteger counter = new AtomicInteger(0);
public TransactionChainProxy(ActorContext actorContext) {
this.actorContext = actorContext;
- transactionChainId = actorContext.getCurrentMemberName() + "-" + System.currentTimeMillis();
+ transactionChainId = actorContext.getCurrentMemberName() + "-transaction-chain-" + counter.incrementAndGet();
+ }
+
+ public String getTransactionChainId() {
+ return transactionChainId;
}
@Override
@Override
protected void onTransactionReady(List<Future<ActorSelection>> readyFutures) {
+ LOG.debug("onTransactionReady {} pending readyFutures size {} chain {}", getIdentifier(), readyFutures.size(), TransactionChainProxy.this.transactionChainId);
state.setReadyFutures(getIdentifier(), readyFutures);
}
phantomReferenceCache.put(cleanup, cleanup);
}
- LOG.debug("Created txn {} of type {}", identifier, transactionType);
+ LOG.debug("Created txn {} of type {} on chain {}", identifier, transactionType, transactionChainId);
}
@VisibleForTesting
for(TransactionFutureCallback txFutureCallback : txFutureCallbackMap.values()) {
- LOG.debug("Tx {} Readying transaction for shard {}", identifier,
- txFutureCallback.getShardName());
+ LOG.debug("Tx {} Readying transaction for shard {} chain {}", identifier,
+ txFutureCallback.getShardName(), transactionChainId);
TransactionContext transactionContext = txFutureCallback.getTransactionContext();
if(transactionContext != null) {
package org.opendaylight.controller.cluster.datastore;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.opendaylight.controller.sal.core.spi.data.DOMStoreWriteTransaction;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
public class TransactionChainProxyTest {
ActorContext actorContext = mock(ActorContext.class);
SchemaContext schemaContext = mock(SchemaContext.class);
verify(context, times(1)).broadcast(anyObject());
}
+
+ @Test
+ public void testTransactionChainsHaveUniqueId(){
+ TransactionChainProxy one = new TransactionChainProxy(mock(ActorContext.class));
+ TransactionChainProxy two = new TransactionChainProxy(mock(ActorContext.class));
+
+ Assert.assertNotEquals(one.getTransactionChainId(), two.getTransactionChainId());
+ }
}