1 package org.opendaylight.controller.cluster.example;
3 import akka.actor.ActorRef;
4 import akka.actor.ActorSystem;
5 import com.google.common.base.Optional;
6 import org.opendaylight.controller.cluster.example.messages.PrintRole;
7 import org.opendaylight.controller.cluster.example.messages.PrintState;
8 import org.opendaylight.controller.cluster.raft.ConfigParams;
10 import java.io.BufferedReader;
11 import java.io.InputStreamReader;
12 import java.util.HashMap;
14 import java.util.concurrent.ConcurrentHashMap;
17 * This is a test driver for testing akka-raft implementation
18 * Its uses ExampleActors and threads to push content(key-vals) to these actors
19 * Each ExampleActor can have one or more ClientActors. Each ClientActor spawns
20 * a thread and starts push logs to the actor its assigned to.
22 public class TestDriver {
24 private static final ActorSystem actorSystem = ActorSystem.create();
25 private static Map<String, String> allPeers = new HashMap<>();
26 private static Map<String, ActorRef> clientActorRefs = new HashMap<String, ActorRef>();
27 private static Map<String, ActorRef> actorRefs = new HashMap<String, ActorRef>();
28 private static LogGenerator logGenerator = new LogGenerator();
29 private int nameCounter = 0;
30 private static ConfigParams configParams = new ExampleConfigParamsImpl();
33 * Create nodes, add clients and start logging.
38 * reinstateNode:{nodeName}
40 * addClientsToNode:{nodeName, num}
43 * startLoggingForClient:{nodeName}
44 * stopLoggingForClient:{nodeName}
48 * Note: when run on IDE and on debug log level, the debug logs in
49 * AbstractUptypedActor and AbstractUptypedPersistentActor would need to be commented out.
50 * Also RaftActor handleCommand(), debug log which prints for every command other than AE/AER
55 public static void main(String[] args) throws Exception {
56 TestDriver td = new TestDriver();
58 System.out.println("Enter command (type bye to exit):");
61 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
63 String command = br.readLine();
64 if (command.startsWith("bye")) {
67 } else if (command.startsWith("createNodes")) {
68 String[] arr = command.split(":");
69 int n = Integer.parseInt(arr[1]);
72 } else if (command.startsWith("addClients")) {
73 String[] arr = command.split(":");
74 int n = Integer.parseInt(arr[1]);
77 } else if (command.startsWith("addClientsToNode")) {
78 String[] arr = command.split(":");
79 String nodeName = arr[1];
80 int n = Integer.parseInt(arr[1]);
81 td.addClientsToNode(nodeName, n);
83 } else if (command.startsWith("stopNode")) {
84 String[] arr = command.split(":");
87 } else if (command.startsWith("reinstateNode")) {
88 String[] arr = command.split(":");
89 td.reinstateNode(arr[1]);
91 } else if (command.startsWith("startLogging")) {
94 } else if (command.startsWith("startLoggingForClient")) {
95 String[] arr = command.split(":");
96 td.startLoggingForClient(clientActorRefs.get(arr[1]));
98 } else if (command.startsWith("stopLogging")) {
101 } else if (command.startsWith("stopLoggingForClient")) {
102 String[] arr = command.split(":");
103 td.stopLoggingForClient(clientActorRefs.get(arr[1]));
105 } else if (command.startsWith("printState")) {
107 } else if (command.startsWith("printNodes")) {
110 System.out.println("Invalid command:" + command);
116 public static ActorRef createExampleActor(String name) {
117 return actorSystem.actorOf(ExampleActor.props(name, withoutPeer(name),
118 Optional.of(configParams)), name);
121 public void createNodes(int num) {
122 for (int i=0; i < num; i++) {
123 nameCounter = nameCounter + 1;
124 allPeers.put("example-"+nameCounter, "akka://default/user/example-"+nameCounter);
127 for (String s : allPeers.keySet()) {
128 ActorRef exampleActor = createExampleActor(s);
129 actorRefs.put(s, exampleActor);
130 System.out.println("Created node:"+s);
135 // add num clients to all nodes in the system
136 public void addClients(int num) {
137 for(Map.Entry<String,ActorRef> actorRefEntry : actorRefs.entrySet()) {
138 for (int i=0; i < num; i++) {
139 String clientName = "client-" + i + "-" + actorRefEntry.getKey();
140 ActorRef clientActor = actorSystem.actorOf(
141 ClientActor.props(actorRefEntry.getValue()), clientName);
142 clientActorRefs.put(clientName, clientActor);
143 System.out.println("Created client-node:" + clientName);
148 // add num clients to a node
149 public void addClientsToNode(String actorName, int num) {
150 ActorRef actorRef = actorRefs.get(actorName);
151 for (int i=0; i < num; i++) {
152 String clientName = "client-" + i + "-" + actorName;
153 clientActorRefs.put(clientName,
154 actorSystem.actorOf(ClientActor.props(actorRef), clientName));
155 System.out.println("Added client-node:" + clientName);
159 public void stopNode(String actorName) {
160 ActorRef actorRef = actorRefs.get(actorName);
162 for (Map.Entry<String,ActorRef> entry : clientActorRefs.entrySet()) {
163 if (entry.getKey().endsWith(actorName)) {
164 actorSystem.stop(entry.getValue());
168 actorSystem.stop(actorRef);
169 actorRefs.remove(actorName);
170 allPeers.remove(actorName);
173 public void reinstateNode(String actorName) {
174 String address = "akka://default/user/"+actorName;
175 allPeers.put(actorName, address);
177 ActorRef exampleActor = createExampleActor(actorName);
178 actorRefs.put(actorName, exampleActor);
180 addClientsToNode(actorName, 1);
183 public void startAllLogging() {
184 if(!clientActorRefs.isEmpty()) {
185 for(Map.Entry<String,ActorRef> client : clientActorRefs.entrySet()) {
186 logGenerator.startLoggingForClient(client.getValue());
187 System.out.println("Started logging for client:"+client.getKey());
190 System.out.println("There are no clients for any nodes. First create clients using commands- addClients:<num> or addClientsToNode:<nodename>:<num>");
195 public void startLoggingForClient(ActorRef client) {
196 logGenerator.startLoggingForClient(client);
199 public void stopAllLogging() {
200 for(Map.Entry<String,ActorRef> client : clientActorRefs.entrySet()) {
201 logGenerator.stopLoggingForClient(client.getValue());
205 public void stopLoggingForClient(ActorRef client) {
206 logGenerator.stopLoggingForClient(client);
209 public void printState() {
210 for (ActorRef ref : actorRefs.values()) {
211 ref.tell(new PrintState(), null);
215 public void printNodes() {
216 for (ActorRef ref : actorRefs.values()) {
217 ref.tell(new PrintRole(), null);
221 public ActorRef getLeader() {
226 private static Map<String, String> withoutPeer(String peerId) {
227 Map<String, String> without = new ConcurrentHashMap<>(allPeers);
228 without.remove(peerId);