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    }