001 /******************************************************************************
002 * Copyright (C) MActor Developers. All rights reserved. *
003 * ---------------------------------------------------------------------------*
004 * This file is part of MActor. *
005 * *
006 * MActor is free software; you can redistribute it and/or modify *
007 * it under the terms of the GNU General Public License as published by *
008 * the Free Software Foundation; either version 2 of the License, or *
009 * (at your option) any later version. *
010 * *
011 * MActor is distributed in the hope that it will be useful, *
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
014 * GNU General Public License for more details. *
015 * *
016 * You should have received a copy of the GNU General Public License *
017 * along with MActor; if not, write to the Free Software *
018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
019 ******************************************************************************/
020 package org.mactor.ui.cmd;
021
022 import java.util.Iterator;
023 import java.util.TreeMap;
024 import java.util.Map.Entry;
025
026 import org.apache.log4j.Logger;
027 import org.dom4j.Element;
028 import org.mactor.brokers.Message;
029 import org.mactor.brokers.http.HttpClient;
030 import org.mactor.brokers.http.HttpRequest;
031 import org.mactor.brokers.http.HttpRequestListener;
032 import org.mactor.brokers.http.HttpResponse;
033 import org.mactor.brokers.http.HttpServerManager;
034 import org.mactor.framework.MactorException;
035
036 public class RunningTestRegistry {
037 protected static Logger log = Logger.getLogger(RunningTestRegistry.class);
038 private static final int SERVER_PORT = 9876;
039 private static final int PORT_RANGE_LOW = 9877;
040 private static final int PORT_RANGE_HIGH = 9977;
041 private static final String BROWSER_LISTENER_PATH = "/m";
042 private static final String SERVER_PATH_PEER = "/MactorRunningTestsRegistry";
043 private static final String INSTANCE_PATH = "/MactorRunningTest";
044 private static final String SERVER_URL = "http://localhost:" + SERVER_PORT + SERVER_PATH_PEER;
045 TreeMap<Integer, String> runningTests = new TreeMap<Integer, String>();
046 int port;
047 boolean connected = false;
048 private String instanceId;
049 private PeerRequestHandler peerHandler = new PeerRequestHandler();
050 private BrowserIndexRequestHandler browserhandler = new BrowserIndexRequestHandler();
051 public RunningTestRegistry(String instanceId) {
052 this.instanceId = instanceId;
053 try {
054 if (!establishLocalServer()) {
055 log.warn("Failed to establish registry server client for instance " + instanceId);
056 return;
057 }
058 for (int i = 0; i < 10 && !connected; i++) {
059 if (!connectWithRegistryServer()) {
060 if (!startRegistryServer()) {
061 continue;
062 }
063 Thread.sleep(1000);
064 } else {
065 connected = true;
066 }
067 }
068 } catch (InterruptedException ie) {
069 }
070 }
071 private boolean connectWithRegistryServer() {
072 try {
073 Message result = HttpClient.sendMessage(SERVER_URL, "POST", Message.createMessage("<register><port>" + port + "</port><id>" + instanceId + "</id></register>"), true, null, null);
074 System.out.println("received:" + result.getContent());
075 return result != null && result.getContentDocument().getRootElement().getName().equals("ok");
076 } catch (MactorException me) {
077 // Message resutl =
078 }
079 return false;
080 }
081 private boolean startRegistryServer() {
082 try {
083 HttpServerManager.getHttpServer(SERVER_PORT).addRequestListener(SERVER_PATH_PEER, peerHandler);
084 HttpServerManager.getHttpServer(SERVER_PORT).addRequestListener(BROWSER_LISTENER_PATH, browserhandler);
085 return true;
086 } catch (MactorException me) {
087 }
088 return true;
089 }
090 private boolean establishLocalServer() {
091 for (int i = PORT_RANGE_LOW; i < PORT_RANGE_HIGH; i++) {
092 try {
093 HttpServerManager.getHttpServer(i).addRequestListener(INSTANCE_PATH, peerHandler);
094 this.port = i;
095 return true;
096 } catch (MactorException me) {
097 }
098 }
099 return false;
100 }
101 private class BrowserIndexRequestHandler implements HttpRequestListener {
102 public HttpResponse onRequest(HttpRequest request) throws Exception {
103 HttpResponse res = new HttpResponse();
104 StringBuffer sb = new StringBuffer("<html><head><title>MActor Running Tests Registry</title></head><body>");
105 sb.append("<table>");
106 for (Entry<Integer, String> e : runningTests.entrySet()) {
107 sb.append("<tr><td>").append("<a href=\"http://localhost:" + SERVER_PORT + BROWSER_LISTENER_PATH + "/" + e.getKey() + "\">" + e.getValue() + "</a>");
108 sb.append("</td></tr>");
109 }
110 sb.append("</table>");
111 sb.append("</body></html>");
112 res.setData(sb.toString());
113 return res;
114 }
115 }
116 private class BrowserInstanceRequestHandler implements HttpRequestListener {
117 int clientPort;
118 String clientId;
119 public BrowserInstanceRequestHandler(int clientPort, String clientId) {
120 this.clientPort = clientPort;
121 this.clientId = clientId;
122 }
123 public HttpResponse onRequest(HttpRequest request) throws Exception {
124 HttpResponse res = new HttpResponse();
125 StringBuffer sb = new StringBuffer("<html><head><title>MActor Running Tests Registry (" + clientId + ")</title></head><body>");
126 sb.append("</body></html>");
127 try {
128 Message result = HttpClient.sendMessage("http://localhost:" + clientPort + INSTANCE_PATH, "POST", Message.createMessage("<query/>"), true, null, null);
129 Iterator it = result.getContentDocument().getRootElement().elementIterator("test");
130 if (!it.hasNext()) {
131 } else {
132 sb.append("<table>");
133 while (it.hasNext()) {
134 Element testEl = (Element) it.next();
135 sb.append("<tr><td>").append(testEl.element("name").getTextTrim());
136 sb.append("</td><td>").append(testEl.element("node").getTextTrim());
137 sb.append("</td><td>").append(testEl.element("msg").getTextTrim());
138 sb.append("</td></tr>");
139 }
140 sb.append("</table>");
141 }
142 } catch (MactorException me) {
143 sb.append("Unable to get any information from instance '" + clientId + "'");
144 runningTests.remove(new Integer(clientPort));
145 HttpServerManager.getHttpServer(SERVER_PORT).removeRequestListener(BROWSER_LISTENER_PATH + "/" + clientPort);
146 }
147 res.setData(sb.toString());
148 return res;
149 }
150 }
151 private String getInstanceStatus() {
152 return "<status><test><name>test1</name><node>action1</node><msg></msg></test></status>";
153 }
154 private class PeerRequestHandler implements HttpRequestListener {
155 public HttpResponse onRequest(HttpRequest request) throws Exception {
156 String responseData = null;
157 HttpResponse res = new HttpResponse();
158 try {
159 Message m = Message.createMessage(request.getData());
160 Element root = m.getContentDocument().getRootElement();
161 if ("register".equals(root.getName())) {
162 Integer clientPort = new Integer(root.element("port").getTextTrim());
163 String clientId = root.element("id").getTextTrim();
164 if (!runningTests.containsKey(clientPort)) {
165 log.info("Adding intance " + clientPort + "-" + instanceId + " to running registry ");
166 runningTests.put(clientPort, clientId);
167 }
168 try {
169 HttpServerManager.getHttpServer(SERVER_PORT).addRequestListener(BROWSER_LISTENER_PATH + "/" + clientPort, new BrowserInstanceRequestHandler(clientPort, clientId));
170 } catch (MactorException me) {
171 }
172 res.setData("<ok/>");
173 } else if ("alive".equals(root.getName())) {
174 res.setData("<ok/>");
175 } else if ("query".equals(root.getName())) {
176 res.setData(getInstanceStatus());
177 } else {
178 res.setData("<error>invalid request</error>");
179 }
180 } catch (Exception e) {
181 log.info(instanceId + " received invalid http request. Error:" + e.getMessage() + "t. Request:" + request.getData());
182 res.setData("<error/>");
183 }
184 return res;
185 }
186 }
187 public static void main(String[] args) throws Exception {
188 new RunningTestRegistry("1");
189 }
190 }