Search in sources :

Example 21 with ServerConfigurationPayload

use of org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload in project controller by opendaylight.

the class ClusterAdminRpcServiceTest method testFlipMemberVotingStatesWithVotingMembersDown.

@Test
public void testFlipMemberVotingStatesWithVotingMembersDown() throws Exception {
    String name = "testFlipMemberVotingStatesWithVotingMembersDown";
    // Members 4, 5, and 6 are initially non-voting and simulated as down by not starting them up.
    ServerConfigurationPayload persistedServerConfig = new ServerConfigurationPayload(Arrays.asList(new ServerInfo("member-1", true), new ServerInfo("member-2", true), new ServerInfo("member-3", true), new ServerInfo("member-4", false), new ServerInfo("member-5", false), new ServerInfo("member-6", false)));
    setupPersistedServerConfigPayload(persistedServerConfig, "member-1", name, "cars", "people");
    setupPersistedServerConfigPayload(persistedServerConfig, "member-2", name, "cars", "people");
    setupPersistedServerConfigPayload(persistedServerConfig, "member-3", name, "cars", "people");
    String moduleShardsConfig = "module-shards-member1-and-2-and-3.conf";
    final MemberNode leaderNode1 = MemberNode.builder(memberNodes).akkaConfig("Member1").testName(name).moduleShardsConfig(moduleShardsConfig).datastoreContextBuilder(DatastoreContext.newBuilder().shardHeartbeatIntervalInMillis(300).shardElectionTimeoutFactor(1)).build();
    final MemberNode replicaNode2 = MemberNode.builder(memberNodes).akkaConfig("Member2").testName(name).moduleShardsConfig(moduleShardsConfig).build();
    final MemberNode replicaNode3 = MemberNode.builder(memberNodes).akkaConfig("Member3").testName(name).moduleShardsConfig(moduleShardsConfig).build();
    leaderNode1.configDataStore().waitTillReady();
    leaderNode1.operDataStore().waitTillReady();
    verifyVotingStates(leaderNode1.configDataStore(), "cars", new SimpleEntry<>("member-1", TRUE), new SimpleEntry<>("member-2", TRUE), new SimpleEntry<>("member-3", TRUE), new SimpleEntry<>("member-4", FALSE), new SimpleEntry<>("member-5", FALSE), new SimpleEntry<>("member-6", FALSE));
    ClusterAdminRpcService service1 = new ClusterAdminRpcService(leaderNode1.configDataStore(), leaderNode1.operDataStore(), null);
    RpcResult<FlipMemberVotingStatesForAllShardsOutput> rpcResult = service1.flipMemberVotingStatesForAllShards().get(10, TimeUnit.SECONDS);
    FlipMemberVotingStatesForAllShardsOutput result = verifySuccessfulRpcResult(rpcResult);
    verifyShardResults(result.getShardResult(), successShardResult("cars", DataStoreType.Config), successShardResult("people", DataStoreType.Config), successShardResult("cars", DataStoreType.Operational), successShardResult("people", DataStoreType.Operational));
    // Members 2 and 3 are now non-voting but should get replicated with the new new server config.
    verifyVotingStates(new AbstractDataStore[] { leaderNode1.configDataStore(), leaderNode1.operDataStore(), replicaNode2.configDataStore(), replicaNode2.operDataStore(), replicaNode3.configDataStore(), replicaNode3.operDataStore() }, new String[] { "cars", "people" }, new SimpleEntry<>("member-1", FALSE), new SimpleEntry<>("member-2", FALSE), new SimpleEntry<>("member-3", FALSE), new SimpleEntry<>("member-4", TRUE), new SimpleEntry<>("member-5", TRUE), new SimpleEntry<>("member-6", TRUE));
    // The leader (member 1) was changed to non-voting but it shouldn't be able to step down as leader yet
    // b/c it can't get a majority consensus with all voting members down. So verify it remains the leader.
    verifyRaftState(leaderNode1.configDataStore(), "cars", raftState -> {
        assertNotNull("Expected non-null leader Id", raftState.getLeader());
        assertTrue("Expected leader member-1", raftState.getLeader().contains("member-1"));
    });
}
Also used : MemberNode(org.opendaylight.controller.cluster.datastore.MemberNode) ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) ServerInfo(org.opendaylight.controller.cluster.raft.persisted.ServerInfo) FlipMemberVotingStatesForAllShardsOutput(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.FlipMemberVotingStatesForAllShardsOutput) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) Test(org.junit.Test)

Example 22 with ServerConfigurationPayload

use of org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload in project controller by opendaylight.

the class ClusterAdminRpcServiceTest method setupPersistedServerConfigPayload.

private static void setupPersistedServerConfigPayload(ServerConfigurationPayload serverConfig, String member, String datastoreTypeSuffix, String... shards) {
    String[] datastoreTypes = { "config_", "oper_" };
    for (String type : datastoreTypes) {
        for (String shard : shards) {
            List<ServerInfo> newServerInfo = new ArrayList<>(serverConfig.getServerConfig().size());
            for (ServerInfo info : serverConfig.getServerConfig()) {
                newServerInfo.add(new ServerInfo(ShardIdentifier.create(shard, MemberName.forName(info.getId()), type + datastoreTypeSuffix).toString(), info.isVoting()));
            }
            String shardID = ShardIdentifier.create(shard, MemberName.forName(member), type + datastoreTypeSuffix).toString();
            InMemoryJournal.addEntry(shardID, 1, new UpdateElectionTerm(1, null));
            InMemoryJournal.addEntry(shardID, 2, new SimpleReplicatedLogEntry(0, 1, new ServerConfigurationPayload(newServerInfo)));
        }
    }
}
Also used : ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) ServerInfo(org.opendaylight.controller.cluster.raft.persisted.ServerInfo) ArrayList(java.util.ArrayList) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) UpdateElectionTerm(org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm)

Example 23 with ServerConfigurationPayload

use of org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload in project controller by opendaylight.

the class ClusterAdminRpcServiceTest method testFlipMemberVotingStatesWithNoInitialLeader.

@Test
public void testFlipMemberVotingStatesWithNoInitialLeader() throws Exception {
    String name = "testFlipMemberVotingStatesWithNoInitialLeader";
    // Members 1, 2, and 3 are initially started up as non-voting. Members 4, 5, and 6 are initially
    // non-voting and simulated as down by not starting them up.
    ServerConfigurationPayload persistedServerConfig = new ServerConfigurationPayload(Arrays.asList(new ServerInfo("member-1", false), new ServerInfo("member-2", false), new ServerInfo("member-3", false), new ServerInfo("member-4", true), new ServerInfo("member-5", true), new ServerInfo("member-6", true)));
    setupPersistedServerConfigPayload(persistedServerConfig, "member-1", name, "cars", "people");
    setupPersistedServerConfigPayload(persistedServerConfig, "member-2", name, "cars", "people");
    setupPersistedServerConfigPayload(persistedServerConfig, "member-3", name, "cars", "people");
    String moduleShardsConfig = "module-shards-member1-and-2-and-3.conf";
    final MemberNode replicaNode1 = MemberNode.builder(memberNodes).akkaConfig("Member1").testName(name).moduleShardsConfig(moduleShardsConfig).datastoreContextBuilder(DatastoreContext.newBuilder().shardHeartbeatIntervalInMillis(300).shardElectionTimeoutFactor(1)).build();
    final MemberNode replicaNode2 = MemberNode.builder(memberNodes).akkaConfig("Member2").testName(name).moduleShardsConfig(moduleShardsConfig).build();
    final MemberNode replicaNode3 = MemberNode.builder(memberNodes).akkaConfig("Member3").testName(name).moduleShardsConfig(moduleShardsConfig).build();
    // Initially there won't be a leader b/c all the up nodes are non-voting.
    replicaNode1.waitForMembersUp("member-2", "member-3");
    verifyVotingStates(replicaNode1.configDataStore(), "cars", new SimpleEntry<>("member-1", FALSE), new SimpleEntry<>("member-2", FALSE), new SimpleEntry<>("member-3", FALSE), new SimpleEntry<>("member-4", TRUE), new SimpleEntry<>("member-5", TRUE), new SimpleEntry<>("member-6", TRUE));
    verifyRaftState(replicaNode1.configDataStore(), "cars", raftState -> assertEquals("Expected raft state", RaftState.Follower.toString(), raftState.getRaftState()));
    ClusterAdminRpcService service1 = new ClusterAdminRpcService(replicaNode1.configDataStore(), replicaNode1.operDataStore(), null);
    RpcResult<FlipMemberVotingStatesForAllShardsOutput> rpcResult = service1.flipMemberVotingStatesForAllShards().get(10, TimeUnit.SECONDS);
    FlipMemberVotingStatesForAllShardsOutput result = verifySuccessfulRpcResult(rpcResult);
    verifyShardResults(result.getShardResult(), successShardResult("cars", DataStoreType.Config), successShardResult("people", DataStoreType.Config), successShardResult("cars", DataStoreType.Operational), successShardResult("people", DataStoreType.Operational));
    verifyVotingStates(new AbstractDataStore[] { replicaNode1.configDataStore(), replicaNode1.operDataStore(), replicaNode2.configDataStore(), replicaNode2.operDataStore(), replicaNode3.configDataStore(), replicaNode3.operDataStore() }, new String[] { "cars", "people" }, new SimpleEntry<>("member-1", TRUE), new SimpleEntry<>("member-2", TRUE), new SimpleEntry<>("member-3", TRUE), new SimpleEntry<>("member-4", FALSE), new SimpleEntry<>("member-5", FALSE), new SimpleEntry<>("member-6", FALSE));
    // Since member 1 was changed to voting and there was no leader, it should've started and election
    // and become leader
    verifyRaftState(replicaNode1.configDataStore(), "cars", raftState -> {
        assertNotNull("Expected non-null leader Id", raftState.getLeader());
        assertTrue("Expected leader member-1. Actual: " + raftState.getLeader(), raftState.getLeader().contains("member-1"));
    });
    verifyRaftState(replicaNode1.operDataStore(), "cars", raftState -> {
        assertNotNull("Expected non-null leader Id", raftState.getLeader());
        assertTrue("Expected leader member-1. Actual: " + raftState.getLeader(), raftState.getLeader().contains("member-1"));
    });
}
Also used : MemberNode(org.opendaylight.controller.cluster.datastore.MemberNode) ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) ServerInfo(org.opendaylight.controller.cluster.raft.persisted.ServerInfo) FlipMemberVotingStatesForAllShardsOutput(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.FlipMemberVotingStatesForAllShardsOutput) CoreMatchers.containsString(org.hamcrest.CoreMatchers.containsString) Test(org.junit.Test)

Example 24 with ServerConfigurationPayload

use of org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload in project controller by opendaylight.

the class RaftActor method handleApplyState.

private void handleApplyState(final ApplyState applyState) {
    long startTime = System.nanoTime();
    Payload payload = applyState.getReplicatedLogEntry().getData();
    if (LOG.isDebugEnabled()) {
        LOG.debug("{}: Applying state for log index {} data {}", persistenceId(), applyState.getReplicatedLogEntry().getIndex(), payload);
    }
    if (!(payload instanceof NoopPayload) && !(payload instanceof ServerConfigurationPayload)) {
        applyState(applyState.getClientActor(), applyState.getIdentifier(), payload);
    }
    long elapsedTime = System.nanoTime() - startTime;
    if (elapsedTime >= APPLY_STATE_DELAY_THRESHOLD_IN_NANOS) {
        LOG.debug("ApplyState took more time than expected. Elapsed Time = {} ms ApplyState = {}", TimeUnit.NANOSECONDS.toMillis(elapsedTime), applyState);
    }
    // Send the ApplyState message back to self to handle further processing asynchronously.
    self().tell(applyState, self());
}
Also used : ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) NoopPayload(org.opendaylight.controller.cluster.raft.persisted.NoopPayload) ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) NoopPayload(org.opendaylight.controller.cluster.raft.persisted.NoopPayload) Payload(org.opendaylight.controller.cluster.raft.protobuff.client.messages.Payload)

Example 25 with ServerConfigurationPayload

use of org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload in project controller by opendaylight.

the class RaftActorContextImpl method getPeerServerInfo.

@Override
public ServerConfigurationPayload getPeerServerInfo(final boolean includeSelf) {
    if (!isDynamicServerConfigurationInUse()) {
        return null;
    }
    Collection<PeerInfo> peers = getPeers();
    List<ServerInfo> newConfig = new ArrayList<>(peers.size() + 1);
    for (PeerInfo peer : peers) {
        newConfig.add(new ServerInfo(peer.getId(), peer.isVoting()));
    }
    if (includeSelf) {
        newConfig.add(new ServerInfo(getId(), votingMember));
    }
    return new ServerConfigurationPayload(newConfig);
}
Also used : ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) ServerInfo(org.opendaylight.controller.cluster.raft.persisted.ServerInfo) ArrayList(java.util.ArrayList)

Aggregations

ServerConfigurationPayload (org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload)25 ServerInfo (org.opendaylight.controller.cluster.raft.persisted.ServerInfo)22 Test (org.junit.Test)18 SimpleReplicatedLogEntry (org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry)15 UpdateElectionTerm (org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm)8 ActorRef (akka.actor.ActorRef)6 ArrayList (java.util.ArrayList)6 CoreMatchers.containsString (org.hamcrest.CoreMatchers.containsString)5 ApplySnapshot (org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot)5 InstallSnapshot (org.opendaylight.controller.cluster.raft.messages.InstallSnapshot)5 FiniteDuration (scala.concurrent.duration.FiniteDuration)5 TestActorRef (akka.testkit.TestActorRef)4 List (java.util.List)4 TimeUnit (java.util.concurrent.TimeUnit)4 ApplyState (org.opendaylight.controller.cluster.raft.base.messages.ApplyState)4 ChangeServersVotingStatus (org.opendaylight.controller.cluster.raft.messages.ChangeServersVotingStatus)4 Optional (com.google.common.base.Optional)3 Stopwatch (com.google.common.base.Stopwatch)3 ImmutableMap (com.google.common.collect.ImmutableMap)3 Sets (com.google.common.collect.Sets)3