1 package org.ultramonkey.l7.controller;
3 import java.io.BufferedReader;
4 import java.io.InputStream;
5 import java.io.InputStreamReader;
7 import java.util.regex.*;
9 import org.apache.log4j.Logger;
10 import org.ultramonkey.l7.model.LogCategorySet;
15 * class ClusterController
18 * Copyright(c) NTT COMWARE 2008
23 public class ClusterController {
26 * TODO This class is only for Heartbeat cluster now. We have to be
27 * refactoring for any cluster software using JNDI later.
30 private Logger ioCommandLogger = Logger.getLogger(LogCategorySet.GUI_IO_COMMAND);
32 protected static ClusterData data = null;
34 private static final String CRM_MON = "/usr/sbin/crm_mon";
36 private static final String CRM_STANDBY = "/usr/sbin/crm_standby";
38 private static final int CHECK_TIMEOUT = 10;
40 private static String HB_LOG = "/var/log/ha-log";
48 * @return cluster data
50 public ClusterData getData() {
51 // --- debug log (in method) ---
52 if (ioCommandLogger.isDebugEnabled()) {
53 ioCommandLogger.debug("11558 ClusterController::getData() in");
55 // --- debug log (in method) ---
58 String command = CRM_MON + " -1";
59 String result = runProcess(command);
61 ClusterData data = new ClusterData();
62 data.self_status = ClusterStatus.SINGLE;
63 data.logFileName = HB_LOG;
66 InetAddress local = InetAddress.getLocalHost();
67 String host = local.getHostName();
68 data.self_ip = local.getHostAddress();
71 Pattern p = Pattern.compile("^Node: ([^ ]+)[^:]+: (\\w+)$",
73 Matcher m = p.matcher(result);
75 if (host.equals(m.group(1))) {
76 data.self_hostname = m.group(1);
77 data.self_ip = local.getHostAddress();
78 if ("OFFLINE".equals(m.group(2)))
79 data.self_status = ClusterStatus.OUT_OF_SERVICE;
80 else if ("online".equals(m.group(2)))
81 data.self_status = ClusterStatus.STANDBY;
82 else if ("standby".equals(m.group(2)))
83 data.self_status = ClusterStatus.OUT_OF_SERVICE;
85 data.self_status = ClusterStatus.SINGLE;
87 data.other_hostname = m.group(1);
89 data.other_ip = InetAddress.getByName(m.group(1))
91 } catch (UnknownHostException e) {
92 ioCommandLogger.info("21100 name resolution failed: " + m.group(1));
95 if ("OFFLINE".equals(m.group(2)))
96 data.other_status = ClusterStatus.OUT_OF_SERVICE;
97 else if ("online".equals(m.group(2)))
98 data.other_status = ClusterStatus.STANDBY;
99 else if ("standby".equals(m.group(2)))
100 data.other_status = ClusterStatus.OUT_OF_SERVICE;
102 data.other_status = ClusterStatus.SINGLE;
105 p = Pattern.compile("Started ([-\\.\\w]+)$", Pattern.MULTILINE);
106 m = p.matcher(result);
108 if (m.group(1).equals(data.self_hostname)
109 && data.self_status == ClusterStatus.STANDBY)
110 data.self_status = ClusterStatus.ACTIVE;
111 else if (m.group(1).equals(data.other_hostname)
112 && data.other_status == ClusterStatus.STANDBY)
113 data.other_status = ClusterStatus.ACTIVE;
116 } catch (Exception e) {
117 ioCommandLogger.error("41242 Exception occured: " + e.getMessage());
121 // --- debug log (in method) ---
122 if (ioCommandLogger.isDebugEnabled()) {
123 StringBuffer buf = new StringBuffer();
124 buf.append("ClusterController::getData() out ");
125 buf.append("return=(" + data + ")");
126 ioCommandLogger.debug("11559 " + buf.toString());
128 // --- debug log (in method) ---
141 public void setData(ClusterData cd) {
142 // --- debug log (in method) ---
143 if (ioCommandLogger.isDebugEnabled()) {
144 StringBuffer buf = new StringBuffer();
145 buf.append("ClusterController::setData(ClusterData cd) in ");
146 buf.append("cd=(" + cd + ")");
147 ioCommandLogger.debug("11560 " + buf.toString());
149 // --- debug log (in method) ---
151 synchronized (this) {
155 // --- debug log (in method) ---
156 if (ioCommandLogger.isDebugEnabled()) {
157 ioCommandLogger.debug("11561 ClusterController::setData(ClusterData cd) out");
159 // --- debug log (in method) ---
165 * changeClusterMode method
168 * @return result of switch over.
170 public boolean changeClusterMode() {
171 // --- debug log (in method) ---
172 if (ioCommandLogger.isDebugEnabled()) {
173 ioCommandLogger.debug("11562 ClusterController::changeClusterMode() in");
175 // --- debug log (in method) ---
177 synchronized (this) {
178 // get current status
179 ClusterData data = this.getData();
180 String command = null;
181 boolean self_flag = true;
183 if (data != null && data.self_status == ClusterStatus.ACTIVE
184 && data.other_status == ClusterStatus.STANDBY) {
186 command = CRM_STANDBY + " -U " + data.self_hostname + " -v on";
187 } else if (data != null && data.other_status == ClusterStatus.ACTIVE
188 && data.self_status == ClusterStatus.STANDBY) {
190 command = CRM_STANDBY + " -U " + data.other_hostname + " -v on";
192 ioCommandLogger.error("41243 Invalid status: " + data);
193 // --- debug log (out method) ---
194 if (ioCommandLogger.isDebugEnabled()) {
195 ioCommandLogger.debug("11563 ClusterController::changeClusterMode() out return=false");
197 // --- debug log (out method) ---
201 // run crm_standby command
202 String result = runProcess(command);
203 if (result == null || result.length() != 0) {
204 ioCommandLogger.error("41244 Command error: command=" + command);
205 ioCommandLogger.error("41245 Command error: result=" + result);
206 // --- debug log (out method) ---
207 if (ioCommandLogger.isDebugEnabled()) {
208 ioCommandLogger.debug("11564 ClusterController::changeClusterMode() out return=false");
210 // --- debug log (out method) ---
214 int timeout = CHECK_TIMEOUT;
217 // reload current status
218 data = this.getData();
221 ioCommandLogger.error("41246 Invalid status: " + data);
222 // --- debug log (out method) ---
223 if (ioCommandLogger.isDebugEnabled()) {
224 ioCommandLogger.debug("11565 ClusterController::changeClusterMode() out return=false");
226 // --- debug log (out method) ---
228 } else if (self_flag) {
229 if (data.self_status == ClusterStatus.OUT_OF_SERVICE
230 && data.other_status == ClusterStatus.ACTIVE) {
231 command = CRM_STANDBY + " -U " + data.self_hostname
236 if (data.other_status == ClusterStatus.OUT_OF_SERVICE
237 && data.self_status == ClusterStatus.ACTIVE) {
238 command = CRM_STANDBY + " -U " + data.other_hostname
246 ioCommandLogger.error("41247 Switch-Over timeout(" + CHECK_TIMEOUT + "sec)");
247 // --- debug log (out method) ---
248 if (ioCommandLogger.isDebugEnabled()) {
249 ioCommandLogger.debug("11566 ClusterController::changeClusterMode() out return=false");
251 // --- debug log (out method) ---
257 } catch (InterruptedException e) {
258 ioCommandLogger.error("41248 Exception occured: " + e.getMessage());
259 // --- debug log (out method) ---
260 if (ioCommandLogger.isDebugEnabled()) {
261 ioCommandLogger.debug("11567 ClusterController::changeClusterMode() out return=false");
263 // --- debug log (out method) ---
268 // run crm_standby command
269 result = runProcess(command);
270 if (result == null || result.length() != 0) {
271 ioCommandLogger.error("41249 Command error: command=" + command);
272 ioCommandLogger.error("41250 Command error: result=" + result);
273 // --- debug log (out method) ---
274 if (ioCommandLogger.isDebugEnabled()) {
275 ioCommandLogger.debug("11568 ClusterController::changeClusterMode() out return=false");
277 // --- debug log (out method) ---
281 // reload current status
282 data = this.getData();
285 ioCommandLogger.error("41251 Invalid status: null");
286 // --- debug log (out method) ---
287 if (ioCommandLogger.isDebugEnabled()) {
288 ioCommandLogger.debug("11569 ClusterController::changeClusterMode() out return=false");
290 // --- debug log (out method) ---
292 } else if (self_flag) {
293 if (data.self_status != ClusterStatus.STANDBY
294 || data.other_status != ClusterStatus.ACTIVE) {
295 ioCommandLogger.error("41252 Invalid status: " + data);
296 // --- debug log (out method) ---
297 if (ioCommandLogger.isDebugEnabled()) {
298 ioCommandLogger.debug("11570 ClusterController::changeClusterMode() out return=false");
300 // --- debug log (out method) ---
304 if (data.other_status != ClusterStatus.STANDBY
305 || data.self_status != ClusterStatus.ACTIVE) {
306 ioCommandLogger.error("41253 Invalid status: " + data);
307 // --- debug log (out method) ---
308 if (ioCommandLogger.isDebugEnabled()) {
309 ioCommandLogger.debug("11571 ClusterController::changeClusterMode() out return=false");
311 // --- debug log (out method) ---
316 // --- debug log (out method) ---
317 if (ioCommandLogger.isDebugEnabled()) {
318 ioCommandLogger.debug("11572 ClusterController::changeClusterMode() out return=true");
320 // --- debug log (out method) ---
332 * @return result string of command execution
334 protected String runProcess(String command) {
335 // --- debug log (in method) ---
336 if (ioCommandLogger.isDebugEnabled()) {
337 StringBuffer buf = new StringBuffer();
338 buf.append("ClusterController::runProcess(String command) in ");
339 buf.append("command=\"" + command + "\"");
340 ioCommandLogger.debug("11573 " + buf.toString());
342 // --- debug log (in method) ---
343 synchronized (this) {
344 StringBuffer result = new StringBuffer();
347 // TODO using sudo command temporally
348 Process p = Runtime.getRuntime().exec("sudo " + command);
349 InputStream stderr = p.getErrorStream();
350 BufferedReader br = new BufferedReader(new InputStreamReader(stderr));
352 while ((line = br.readLine()) != null) {
353 result.append(line + "\n");
355 InputStream is = p.getInputStream();
356 br = new BufferedReader(new InputStreamReader(is));
357 while ((line = br.readLine()) != null) {
358 result.append(line + "\n");
360 } catch (Exception e) {
361 ioCommandLogger.error("41254 Exception occured: " + e.getMessage());
365 // --- debug log (out method) ---
366 if (ioCommandLogger.isDebugEnabled()) {
367 ioCommandLogger.debug("11574 ClusterController::runProcess(String command) out return=" + result);
369 // --- debug log (out method) ---
370 return (result == null) ? null : result.toString();