ab980f77835d038b8d127fce286343416be58bc0
[controller.git] / opendaylight / md-sal / sal-akka-raft-example / src / main / java / org / opendaylight / controller / cluster / example / TestDriver.java
1 /*
2  * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.cluster.example;
10
11 import akka.actor.ActorRef;
12 import akka.actor.ActorSystem;
13 import com.google.common.base.Optional;
14 import com.google.common.collect.Lists;
15 import com.typesafe.config.ConfigFactory;
16 import java.io.BufferedReader;
17 import java.io.InputStreamReader;
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.concurrent.ConcurrentHashMap;
22 import org.opendaylight.controller.cluster.example.messages.PrintRole;
23 import org.opendaylight.controller.cluster.example.messages.PrintState;
24 import org.opendaylight.controller.cluster.raft.ConfigParams;
25
26 /**
27  * This is a test driver for testing akka-raft implementation
28  * Its uses ExampleActors and threads to push content(key-vals) to these actors
29  * Each ExampleActor can have one or more ClientActors. Each ClientActor spawns
30  * a thread and starts push logs to the actor its assigned to.
31  */
32 @SuppressWarnings("checkstyle:RegexpSingleLineJava")
33 public class TestDriver {
34     private static Map<String, String> allPeers = new HashMap<>();
35     private static Map<String, ActorRef> clientActorRefs  = new HashMap<>();
36     private static Map<String, ActorRef> actorRefs = new HashMap<>();
37     private static LogGenerator logGenerator = new LogGenerator();
38     private int nameCounter = 0;
39     private static ConfigParams configParams = new ExampleConfigParamsImpl();
40
41     private static ActorSystem actorSystem;
42     private static ActorSystem listenerActorSystem;
43
44     /**
45      * Create nodes, add clients and start logging.
46      * Commands
47      *  bye
48      *  createNodes:{num}
49      *  stopNode:{nodeName}
50      *  reinstateNode:{nodeName}
51      *  addClients:{num}
52      *  addClientsToNode:{nodeName, num}
53      *  startLogging
54      *  stopLogging
55      *  startLoggingForClient:{nodeName}
56      *  stopLoggingForClient:{nodeName}
57      *  printNodes
58      *  printState
59      *
60      * <p>
61      *  Note: when run on IDE and on debug log level, the debug logs in
62      *  AbstractUptypedActor and AbstractUptypedPersistentActor would need to be commented out.
63      *  Also RaftActor handleCommand(), debug log which prints for every command other than AE/AER
64      */
65     public static void main(String[] args) throws Exception {
66
67         actorSystem = ActorSystem.create("raft-test", ConfigFactory
68             .load().getConfig("raft-test"));
69
70         listenerActorSystem = ActorSystem.create("raft-test-listener", ConfigFactory
71             .load().getConfig("raft-test-listener"));
72
73         TestDriver td = new TestDriver();
74
75         System.out.println("Enter command (type bye to exit):");
76
77
78         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
79         while (true) {
80             String command = br.readLine();
81             if (command.startsWith("bye")) {
82                 System.exit(0);
83
84             } else if (command.startsWith("createNodes")) {
85                 String[] arr = command.split(":");
86                 int num = Integer.parseInt(arr[1]);
87                 td.createNodes(num);
88
89             } else if (command.startsWith("addClients")) {
90                 String[] arr = command.split(":");
91                 int num = Integer.parseInt(arr[1]);
92                 td.addClients(num);
93
94             } else if (command.startsWith("addClientsToNode")) {
95                 String[] arr = command.split(":");
96                 String nodeName = arr[1];
97                 int num = Integer.parseInt(arr[1]);
98                 td.addClientsToNode(nodeName, num);
99
100             } else if (command.startsWith("stopNode")) {
101                 String[] arr = command.split(":");
102                 td.stopNode(arr[1]);
103
104             } else if (command.startsWith("reinstateNode")) {
105                 String[] arr = command.split(":");
106                 td.reinstateNode(arr[1]);
107
108             } else if (command.startsWith("startLogging")) {
109                 td.startAllLogging();
110
111             } else if (command.startsWith("startLoggingForClient")) {
112                 String[] arr = command.split(":");
113                 td.startLoggingForClient(clientActorRefs.get(arr[1]));
114
115             } else if (command.startsWith("stopLogging")) {
116                 td.stopAllLogging();
117
118             } else if (command.startsWith("stopLoggingForClient")) {
119                 String[] arr = command.split(":");
120                 td.stopLoggingForClient(clientActorRefs.get(arr[1]));
121
122             } else if (command.startsWith("printState")) {
123                 td.printState();
124             } else if (command.startsWith("printNodes")) {
125                 td.printNodes();
126             } else {
127                 System.out.println("Invalid command:" + command);
128             }
129
130         }
131     }
132
133     // create the listener using a separate actor system for each example actor
134     private static void createClusterRoleChangeListener(List<String> memberIds) {
135         System.out.println("memberIds=" + memberIds);
136         for (String memberId : memberIds) {
137             ActorRef listenerActor = listenerActorSystem.actorOf(
138                 ExampleRoleChangeListener.getProps(memberId), memberId + "-role-change-listener");
139             System.out.println("Role Change Listener created:" + listenerActor.path().toString());
140         }
141     }
142
143     public static ActorRef createExampleActor(String name) {
144         return actorSystem.actorOf(ExampleActor.props(name, withoutPeer(name),
145             Optional.of(configParams)), name);
146     }
147
148     public void createNodes(int num) {
149         for (int i = 0; i < num; i++)  {
150             nameCounter = nameCounter + 1;
151             allPeers.put("example-" + nameCounter, "akka://raft-test/user/example-" + nameCounter);
152         }
153
154         for (String s : allPeers.keySet())  {
155             ActorRef exampleActor = createExampleActor(s);
156             actorRefs.put(s, exampleActor);
157             System.out.println("Created node:" + s);
158         }
159
160         createClusterRoleChangeListener(Lists.newArrayList(allPeers.keySet()));
161     }
162
163     // add num clients to all nodes in the system
164     public void addClients(int num) {
165         for (Map.Entry<String, ActorRef> actorRefEntry : actorRefs.entrySet()) {
166             for (int i = 0; i < num; i++) {
167                 String clientName = "client-" + i + "-" + actorRefEntry.getKey();
168                 ActorRef clientActor = actorSystem.actorOf(
169                     ClientActor.props(actorRefEntry.getValue()), clientName);
170                 clientActorRefs.put(clientName, clientActor);
171                 System.out.println("Created client-node:" + clientName);
172             }
173         }
174     }
175
176     // add num clients to a node
177     public void addClientsToNode(String actorName, int num) {
178         ActorRef actorRef = actorRefs.get(actorName);
179         for (int i = 0; i < num; i++) {
180             String clientName = "client-" + i + "-" + actorName;
181             clientActorRefs.put(clientName,
182                 actorSystem.actorOf(ClientActor.props(actorRef), clientName));
183             System.out.println("Added client-node:" + clientName);
184         }
185     }
186
187     public void stopNode(String actorName) {
188         ActorRef actorRef = actorRefs.get(actorName);
189
190         for (Map.Entry<String,ActorRef> entry : clientActorRefs.entrySet()) {
191             if (entry.getKey().endsWith(actorName)) {
192                 actorSystem.stop(entry.getValue());
193             }
194         }
195
196         actorSystem.stop(actorRef);
197         actorRefs.remove(actorName);
198         allPeers.remove(actorName);
199     }
200
201     public void reinstateNode(String actorName) {
202         String address = "akka://default/user/" + actorName;
203         allPeers.put(actorName, address);
204
205         ActorRef exampleActor = createExampleActor(actorName);
206         actorRefs.put(actorName, exampleActor);
207
208         addClientsToNode(actorName, 1);
209     }
210
211     public void startAllLogging() {
212         if (!clientActorRefs.isEmpty()) {
213             for (Map.Entry<String, ActorRef> client : clientActorRefs.entrySet()) {
214                 logGenerator.startLoggingForClient(client.getValue());
215                 System.out.println("Started logging for client:" + client.getKey());
216             }
217         } else {
218             System.out.println(
219                     "There are no clients for any nodes. First create clients using commands- addClients:<num> or "
220                     + "addClientsToNode:<nodename>:<num>");
221         }
222     }
223
224     public void startLoggingForClient(ActorRef client) {
225         logGenerator.startLoggingForClient(client);
226     }
227
228     public void stopAllLogging() {
229         for (Map.Entry<String, ActorRef> client : clientActorRefs.entrySet()) {
230             logGenerator.stopLoggingForClient(client.getValue());
231         }
232     }
233
234     public void stopLoggingForClient(ActorRef client) {
235         logGenerator.stopLoggingForClient(client);
236     }
237
238     public void printState() {
239         for (ActorRef ref : actorRefs.values()) {
240             ref.tell(new PrintState(), null);
241         }
242     }
243
244     public void printNodes() {
245         for (ActorRef ref : actorRefs.values()) {
246             ref.tell(new PrintRole(), null);
247         }
248     }
249
250     public ActorRef getLeader() {
251         return null;
252     }
253
254
255     private static Map<String, String> withoutPeer(String peerId) {
256         Map<String, String> without = new ConcurrentHashMap<>(allPeers);
257         without.remove(peerId);
258
259         return without;
260     }
261 }
262