Search in sources :

Example 6 with AddServer

use of org.opendaylight.controller.cluster.raft.messages.AddServer in project controller by opendaylight.

the class RaftActorServerConfigurationSupportTest method testAddServerWithExistingServer.

@Test
public void testAddServerWithExistingServer() {
    LOG.info("testAddServerWithExistingServer starting");
    RaftActorContext initialActorContext = new MockRaftActorContext();
    TestActorRef<MockLeaderRaftActor> leaderActor = actorFactory.createTestActor(MockLeaderRaftActor.props(ImmutableMap.of(FOLLOWER_ID, followerActor.path().toString()), initialActorContext).withDispatcher(Dispatchers.DefaultDispatcherId()), actorFactory.generateActorId(LEADER_ID));
    leaderActor.tell(new AddServer(FOLLOWER_ID, followerActor.path().toString(), true), testKit.getRef());
    AddServerReply addServerReply = testKit.expectMsgClass(testKit.duration("5 seconds"), AddServerReply.class);
    assertEquals("getStatus", ServerChangeStatus.ALREADY_EXISTS, addServerReply.getStatus());
    LOG.info("testAddServerWithExistingServer ending");
}
Also used : AddServerReply(org.opendaylight.controller.cluster.raft.messages.AddServerReply) AddServer(org.opendaylight.controller.cluster.raft.messages.AddServer) Test(org.junit.Test)

Example 7 with AddServer

use of org.opendaylight.controller.cluster.raft.messages.AddServer in project controller by opendaylight.

the class RaftActorServerConfigurationSupportTest method testAddServerWithNoExistingFollower.

@Test
public void testAddServerWithNoExistingFollower() throws Exception {
    LOG.info("testAddServerWithNoExistingFollower starting");
    setupNewFollower();
    RaftActorContext initialActorContext = new MockRaftActorContext();
    initialActorContext.setCommitIndex(1);
    initialActorContext.setLastApplied(1);
    initialActorContext.setReplicatedLog(new MockRaftActorContext.MockReplicatedLogBuilder().createEntries(0, 2, 1).build());
    TestActorRef<MockLeaderRaftActor> leaderActor = actorFactory.createTestActor(MockLeaderRaftActor.props(ImmutableMap.<String, String>of(), initialActorContext).withDispatcher(Dispatchers.DefaultDispatcherId()), actorFactory.generateActorId(LEADER_ID));
    MockLeaderRaftActor leaderRaftActor = leaderActor.underlyingActor();
    final RaftActorContext leaderActorContext = leaderRaftActor.getRaftActorContext();
    final ActorRef leaderCollectorActor = newLeaderCollectorActor(leaderRaftActor);
    leaderActor.tell(new AddServer(NEW_SERVER_ID, newFollowerRaftActor.path().toString(), true), testKit.getRef());
    // Leader should install snapshot - capture and verify ApplySnapshot contents
    ApplySnapshot applySnapshot = expectFirstMatching(newFollowerCollectorActor, ApplySnapshot.class);
    List<Object> snapshotState = MockRaftActor.fromState(applySnapshot.getSnapshot().getState());
    assertEquals("Snapshot state", snapshotState, leaderRaftActor.getState());
    AddServerReply addServerReply = testKit.expectMsgClass(testKit.duration("5 seconds"), AddServerReply.class);
    assertEquals("getStatus", ServerChangeStatus.OK, addServerReply.getStatus());
    assertEquals("getLeaderHint", LEADER_ID, addServerReply.getLeaderHint().get());
    // Verify ServerConfigurationPayload entry in leader's log
    expectFirstMatching(leaderCollectorActor, ApplyState.class);
    assertEquals("Leader journal last index", 2, leaderActorContext.getReplicatedLog().lastIndex());
    assertEquals("Leader commit index", 2, leaderActorContext.getCommitIndex());
    assertEquals("Leader last applied index", 2, leaderActorContext.getLastApplied());
    verifyServerConfigurationPayloadEntry(leaderActorContext.getReplicatedLog(), votingServer(LEADER_ID), votingServer(NEW_SERVER_ID));
    // Verify ServerConfigurationPayload entry in the new follower
    expectFirstMatching(newFollowerCollectorActor, ApplyState.class);
    assertEquals("New follower journal last index", 2, newFollowerActorContext.getReplicatedLog().lastIndex());
    verifyServerConfigurationPayloadEntry(newFollowerActorContext.getReplicatedLog(), votingServer(LEADER_ID), votingServer(NEW_SERVER_ID));
    // Verify new server config was applied in the new follower
    assertEquals("New follower peers", Sets.newHashSet(LEADER_ID), newFollowerActorContext.getPeerIds());
    LOG.info("testAddServerWithNoExistingFollower ending");
}
Also used : ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) ApplySnapshot(org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot) AddServerReply(org.opendaylight.controller.cluster.raft.messages.AddServerReply) AddServer(org.opendaylight.controller.cluster.raft.messages.AddServer) Test(org.junit.Test)

Example 8 with AddServer

use of org.opendaylight.controller.cluster.raft.messages.AddServer in project controller by opendaylight.

the class RaftActorServerConfigurationSupportTest method testAddServerWithOperationInProgress.

@Test
public void testAddServerWithOperationInProgress() throws Exception {
    LOG.info("testAddServerWithOperationInProgress starting");
    setupNewFollower();
    RaftActorContext initialActorContext = new MockRaftActorContext();
    TestActorRef<MockLeaderRaftActor> leaderActor = actorFactory.createTestActor(MockLeaderRaftActor.props(ImmutableMap.<String, String>of(), initialActorContext).withDispatcher(Dispatchers.DefaultDispatcherId()), actorFactory.generateActorId(LEADER_ID));
    MockLeaderRaftActor leaderRaftActor = leaderActor.underlyingActor();
    final RaftActorContext leaderActorContext = leaderRaftActor.getRaftActorContext();
    final ActorRef leaderCollectorActor = newLeaderCollectorActor(leaderRaftActor);
    RaftActorContext follower2ActorContext = newFollowerContext(NEW_SERVER_ID2, followerActor);
    Follower newFollower2 = new Follower(follower2ActorContext);
    followerActor.underlyingActor().setBehavior(newFollower2);
    MockNewFollowerRaftActor newFollowerRaftActorInstance = newFollowerRaftActor.underlyingActor();
    newFollowerRaftActorInstance.setDropMessageOfType(InstallSnapshot.class);
    leaderActor.tell(new AddServer(NEW_SERVER_ID, newFollowerRaftActor.path().toString(), true), testKit.getRef());
    // Wait for leader's install snapshot and capture it
    InstallSnapshot installSnapshot = expectFirstMatching(newFollowerCollectorActor, InstallSnapshot.class);
    // Send a second AddServer - should get queued
    TestKit testKit2 = new TestKit(getSystem());
    leaderActor.tell(new AddServer(NEW_SERVER_ID2, followerActor.path().toString(), false), testKit2.getRef());
    // Continue the first AddServer
    newFollowerRaftActorInstance.setDropMessageOfType(null);
    newFollowerRaftActor.tell(installSnapshot, leaderActor);
    // Verify both complete successfully
    AddServerReply addServerReply = testKit.expectMsgClass(testKit.duration("5 seconds"), AddServerReply.class);
    assertEquals("getStatus", ServerChangeStatus.OK, addServerReply.getStatus());
    addServerReply = testKit2.expectMsgClass(testKit2.duration("5 seconds"), AddServerReply.class);
    assertEquals("getStatus", ServerChangeStatus.OK, addServerReply.getStatus());
    // Verify ServerConfigurationPayload entries in leader's log
    expectMatching(leaderCollectorActor, ApplyState.class, 2);
    assertEquals("Leader journal last index", 1, leaderActorContext.getReplicatedLog().lastIndex());
    assertEquals("Leader commit index", 1, leaderActorContext.getCommitIndex());
    assertEquals("Leader last applied index", 1, leaderActorContext.getLastApplied());
    verifyServerConfigurationPayloadEntry(leaderActorContext.getReplicatedLog(), votingServer(LEADER_ID), votingServer(NEW_SERVER_ID), nonVotingServer(NEW_SERVER_ID2));
    // Verify ServerConfigurationPayload entry in the new follower
    expectMatching(newFollowerCollectorActor, ApplyState.class, 2);
    assertEquals("New follower peers", Sets.newHashSet(LEADER_ID, NEW_SERVER_ID2), newFollowerActorContext.getPeerIds());
    LOG.info("testAddServerWithOperationInProgress ending");
}
Also used : ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) Follower(org.opendaylight.controller.cluster.raft.behaviors.Follower) TestKit(akka.testkit.javadsl.TestKit) AddServerReply(org.opendaylight.controller.cluster.raft.messages.AddServerReply) AddServer(org.opendaylight.controller.cluster.raft.messages.AddServer) InstallSnapshot(org.opendaylight.controller.cluster.raft.messages.InstallSnapshot) Test(org.junit.Test)

Example 9 with AddServer

use of org.opendaylight.controller.cluster.raft.messages.AddServer in project controller by opendaylight.

the class ShardManagerTest method testAddShardReplica.

@Test
public void testAddShardReplica() throws Exception {
    LOG.info("testAddShardReplica starting");
    MockConfiguration mockConfig = new MockConfiguration(ImmutableMap.<String, List<String>>builder().put("default", Arrays.asList("member-1", "member-2")).put("astronauts", Arrays.asList("member-2")).build());
    final String shardManagerID = ShardManagerIdentifier.builder().type(shardMrgIDSuffix).build().toString();
    datastoreContextBuilder.shardManagerPersistenceId(shardManagerID);
    // Create an ActorSystem ShardManager actor for member-1.
    final ActorSystem system1 = newActorSystem("Member1");
    Cluster.get(system1).join(AddressFromURIString.parse("akka://cluster-test@127.0.0.1:2558"));
    ActorRef mockDefaultShardActor = newMockShardActor(system1, Shard.DEFAULT_NAME, "member-1");
    final TestActorRef<TestShardManager> newReplicaShardManager = TestActorRef.create(system1, newTestShardMgrBuilder(mockConfig).shardActor(mockDefaultShardActor).cluster(new ClusterWrapperImpl(system1)).props().withDispatcher(Dispatchers.DefaultDispatcherId()), shardManagerID);
    // Create an ActorSystem ShardManager actor for member-2.
    final ActorSystem system2 = newActorSystem("Member2");
    Cluster.get(system2).join(AddressFromURIString.parse("akka://cluster-test@127.0.0.1:2558"));
    String memberId2 = "member-2-shard-astronauts-" + shardMrgIDSuffix;
    String name = ShardIdentifier.create("astronauts", MEMBER_2, "config").toString();
    final TestActorRef<MockRespondActor> mockShardLeaderActor = TestActorRef.create(system2, Props.create(MockRespondActor.class, AddServer.class, new AddServerReply(ServerChangeStatus.OK, memberId2)).withDispatcher(Dispatchers.DefaultDispatcherId()), name);
    final TestActorRef<TestShardManager> leaderShardManager = TestActorRef.create(system2, newTestShardMgrBuilder(mockConfig).shardActor(mockShardLeaderActor).cluster(new ClusterWrapperImpl(system2)).props().withDispatcher(Dispatchers.DefaultDispatcherId()), shardManagerID);
    new TestKit(system1) {

        {
            newReplicaShardManager.tell(new UpdateSchemaContext(TestModel.createTestContext()), getRef());
            leaderShardManager.tell(new UpdateSchemaContext(TestModel.createTestContext()), getRef());
            leaderShardManager.tell(new ActorInitialized(), mockShardLeaderActor);
            short leaderVersion = DataStoreVersions.CURRENT_VERSION - 1;
            leaderShardManager.tell(new ShardLeaderStateChanged(memberId2, memberId2, mock(DataTree.class), leaderVersion), mockShardLeaderActor);
            leaderShardManager.tell(new RoleChangeNotification(memberId2, RaftState.Candidate.name(), RaftState.Leader.name()), mockShardLeaderActor);
            newReplicaShardManager.underlyingActor().waitForMemberUp();
            leaderShardManager.underlyingActor().waitForMemberUp();
            // Have a dummy snapshot to be overwritten by the new data
            // persisted.
            String[] restoredShards = { "default", "people" };
            ShardManagerSnapshot snapshot = new ShardManagerSnapshot(Arrays.asList(restoredShards), Collections.emptyMap());
            InMemorySnapshotStore.addSnapshot(shardManagerID, snapshot);
            Uninterruptibles.sleepUninterruptibly(2, TimeUnit.MILLISECONDS);
            InMemorySnapshotStore.addSnapshotSavedLatch(shardManagerID);
            InMemorySnapshotStore.addSnapshotDeletedLatch(shardManagerID);
            // construct a mock response message
            newReplicaShardManager.tell(new AddShardReplica("astronauts"), getRef());
            AddServer addServerMsg = MessageCollectorActor.expectFirstMatching(mockShardLeaderActor, AddServer.class);
            String addServerId = "member-1-shard-astronauts-" + shardMrgIDSuffix;
            assertEquals("AddServer serverId", addServerId, addServerMsg.getNewServerId());
            expectMsgClass(duration("5 seconds"), Status.Success.class);
            InMemorySnapshotStore.waitForSavedSnapshot(shardManagerID, ShardManagerSnapshot.class);
            InMemorySnapshotStore.waitForDeletedSnapshot(shardManagerID);
            List<ShardManagerSnapshot> persistedSnapshots = InMemorySnapshotStore.getSnapshots(shardManagerID, ShardManagerSnapshot.class);
            assertEquals("Number of snapshots persisted", 1, persistedSnapshots.size());
            ShardManagerSnapshot shardManagerSnapshot = persistedSnapshots.get(0);
            assertEquals("Persisted local shards", Sets.newHashSet("default", "astronauts"), Sets.newHashSet(shardManagerSnapshot.getShardList()));
        }
    };
    LOG.info("testAddShardReplica ending");
}
Also used : ActorSystem(akka.actor.ActorSystem) FollowerInitialSyncUpStatus(org.opendaylight.controller.cluster.raft.base.messages.FollowerInitialSyncUpStatus) ChangeShardMembersVotingStatus(org.opendaylight.controller.cluster.datastore.messages.ChangeShardMembersVotingStatus) Status(akka.actor.Status) ServerChangeStatus(org.opendaylight.controller.cluster.raft.messages.ServerChangeStatus) ChangeServersVotingStatus(org.opendaylight.controller.cluster.raft.messages.ChangeServersVotingStatus) ClusterWrapperImpl(org.opendaylight.controller.cluster.datastore.ClusterWrapperImpl) UpdateSchemaContext(org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext) ShardLeaderStateChanged(org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateChanged) ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) RoleChangeNotification(org.opendaylight.controller.cluster.notifications.RoleChangeNotification) AddressFromURIString(akka.actor.AddressFromURIString) TestKit(akka.testkit.javadsl.TestKit) AddServer(org.opendaylight.controller.cluster.raft.messages.AddServer) ShardManagerSnapshot(org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot) MockConfiguration(org.opendaylight.controller.cluster.datastore.utils.MockConfiguration) List(java.util.List) ActorInitialized(org.opendaylight.controller.cluster.datastore.messages.ActorInitialized) AddShardReplica(org.opendaylight.controller.cluster.datastore.messages.AddShardReplica) AddServerReply(org.opendaylight.controller.cluster.raft.messages.AddServerReply) Test(org.junit.Test) AbstractShardManagerTest(org.opendaylight.controller.cluster.datastore.AbstractShardManagerTest)

Example 10 with AddServer

use of org.opendaylight.controller.cluster.raft.messages.AddServer in project controller by opendaylight.

the class ShardManagerTest method testAddShardReplicaWithPreExistingReplicaInRemoteShardLeader.

@Test
public void testAddShardReplicaWithPreExistingReplicaInRemoteShardLeader() throws Exception {
    LOG.info("testAddShardReplicaWithPreExistingReplicaInRemoteShardLeader starting");
    new TestKit(getSystem()) {

        {
            TestActorRef<TestShardManager> shardManager = actorFactory.createTestActor(newPropsShardMgrWithMockShardActor(), shardMgrID);
            shardManager.tell(new UpdateSchemaContext(TestModel.createTestContext()), getRef());
            shardManager.tell(new ActorInitialized(), mockShardActor);
            String leaderId = "leader-member-shard-default-" + shardMrgIDSuffix;
            AddServerReply addServerReply = new AddServerReply(ServerChangeStatus.ALREADY_EXISTS, null);
            ActorRef leaderShardActor = shardManager.underlyingActor().getContext().actorOf(Props.create(MockRespondActor.class, AddServer.class, addServerReply), leaderId);
            MockClusterWrapper.sendMemberUp(shardManager, "leader-member", leaderShardActor.path().toString());
            String newReplicaId = "member-1-shard-default-" + shardMrgIDSuffix;
            shardManager.tell(new RoleChangeNotification(newReplicaId, RaftState.Candidate.name(), RaftState.Follower.name()), mockShardActor);
            shardManager.tell(new ShardLeaderStateChanged(newReplicaId, leaderId, DataStoreVersions.CURRENT_VERSION), mockShardActor);
            shardManager.tell(new AddShardReplica(Shard.DEFAULT_NAME), getRef());
            MessageCollectorActor.expectFirstMatching(leaderShardActor, AddServer.class);
            Failure resp = expectMsgClass(duration("5 seconds"), Failure.class);
            assertEquals("Failure cause", AlreadyExistsException.class, resp.cause().getClass());
            shardManager.tell(new FindLocalShard(Shard.DEFAULT_NAME, false), getRef());
            expectMsgClass(duration("5 seconds"), LocalShardFound.class);
            // Send message again to verify previous in progress state is
            // cleared
            shardManager.tell(new AddShardReplica(Shard.DEFAULT_NAME), getRef());
            resp = expectMsgClass(duration("5 seconds"), Failure.class);
            assertEquals("Failure cause", AlreadyExistsException.class, resp.cause().getClass());
            // Send message again with an AddServer timeout to verify the
            // pre-existing shard actor isn't terminated.
            shardManager.tell(newDatastoreContextFactory(datastoreContextBuilder.shardLeaderElectionTimeout(100, TimeUnit.MILLISECONDS).build()), getRef());
            leaderShardActor.tell(MockRespondActor.CLEAR_RESPONSE, ActorRef.noSender());
            shardManager.tell(new AddShardReplica(Shard.DEFAULT_NAME), getRef());
            expectMsgClass(duration("5 seconds"), Failure.class);
            shardManager.tell(new FindLocalShard(Shard.DEFAULT_NAME, false), getRef());
            expectMsgClass(duration("5 seconds"), LocalShardFound.class);
        }
    };
    LOG.info("testAddShardReplicaWithPreExistingReplicaInRemoteShardLeader ending");
}
Also used : UpdateSchemaContext(org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext) ShardLeaderStateChanged(org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateChanged) ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) RoleChangeNotification(org.opendaylight.controller.cluster.notifications.RoleChangeNotification) FindLocalShard(org.opendaylight.controller.cluster.datastore.messages.FindLocalShard) TestKit(akka.testkit.javadsl.TestKit) AddressFromURIString(akka.actor.AddressFromURIString) AddServer(org.opendaylight.controller.cluster.raft.messages.AddServer) ActorInitialized(org.opendaylight.controller.cluster.datastore.messages.ActorInitialized) AddShardReplica(org.opendaylight.controller.cluster.datastore.messages.AddShardReplica) AddServerReply(org.opendaylight.controller.cluster.raft.messages.AddServerReply) Failure(akka.actor.Status.Failure) Test(org.junit.Test) AbstractShardManagerTest(org.opendaylight.controller.cluster.datastore.AbstractShardManagerTest)

Aggregations

AddServer (org.opendaylight.controller.cluster.raft.messages.AddServer)17 Test (org.junit.Test)16 AddServerReply (org.opendaylight.controller.cluster.raft.messages.AddServerReply)15 ActorRef (akka.actor.ActorRef)12 TestActorRef (akka.testkit.TestActorRef)12 Follower (org.opendaylight.controller.cluster.raft.behaviors.Follower)5 TestKit (akka.testkit.javadsl.TestKit)4 AddressFromURIString (akka.actor.AddressFromURIString)3 AbstractShardManagerTest (org.opendaylight.controller.cluster.datastore.AbstractShardManagerTest)3 AddShardReplica (org.opendaylight.controller.cluster.datastore.messages.AddShardReplica)3 UpdateSchemaContext (org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext)3 InitiateCaptureSnapshot (org.opendaylight.controller.cluster.raft.base.messages.InitiateCaptureSnapshot)3 Failure (akka.actor.Status.Failure)2 ActorInitialized (org.opendaylight.controller.cluster.datastore.messages.ActorInitialized)2 FindLocalShard (org.opendaylight.controller.cluster.datastore.messages.FindLocalShard)2 ShardLeaderStateChanged (org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateChanged)2 MockConfiguration (org.opendaylight.controller.cluster.datastore.utils.MockConfiguration)2 RoleChangeNotification (org.opendaylight.controller.cluster.notifications.RoleChangeNotification)2 ApplySnapshot (org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot)2 UnInitializedFollowerSnapshotReply (org.opendaylight.controller.cluster.raft.messages.UnInitializedFollowerSnapshotReply)2