source: trunk/autoquest-httpmonitor/src/main/java/de/ugoe/cs/autoquest/httpmonitor/proxy/HttpMonitoringProxy.java @ 1382

Last change on this file since 1382 was 1382, checked in by pharms, 10 years ago
File size: 8.6 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.httpmonitor.proxy;
16
17import javax.servlet.Servlet;
18
19import de.ugoe.cs.autoquest.httpmonitor.HttpMonitorComponent;
20import de.ugoe.cs.autoquest.httpmonitor.HttpMonitorException;
21import de.ugoe.cs.autoquest.httpmonitor.HttpMonitorExchangeHandler;
22import de.ugoe.cs.autoquest.httpmonitor.HttpMonitorLogManager;
23import de.ugoe.cs.autoquest.httpmonitor.HttpMonitorServer;
24import de.ugoe.cs.autoquest.httpmonitor.Runner;
25import de.ugoe.cs.autoquest.httpmonitor.ShutdownHook;
26import de.ugoe.cs.util.console.Console;
27
28/**
29 * <p>
30 * The HTTP monitory proxy monitor starts a web server ({@link HttpMonitorServer}) that receives
31 * proxies HTTP messages and response. Each exchange of a request and a response is forwarded to
32 * an exchange handler. The exchange handler is either a local log manager
33 * ({@link HttpMonitorLogManager}) or a connection to an external and central HTTP monitor via
34 * an {@link HttpMonitorRemoteExchangeHandler}. The class ensures that on shutdown e.g. caused
35 * by CTRL-C the server and all other requied components are stopped correctly.
36 * </p>
37 *
38 * @author Patrick Harms
39 */
40public class HttpMonitoringProxy implements HttpMonitorComponent {
41
42    /**  */
43    private static final long serialVersionUID = 1L;
44
45    /**
46     * the port on which the webserver shall listen.
47     */
48    private int port;
49   
50    /**
51     * the web server receiving the HTTP requests to be proxied
52     */
53    private HttpMonitorServer server;
54   
55    /**
56     * the manager for all currently recorded exchanges
57     */
58    private ExchangeListenerManager exchangeListenerManager;
59   
60    /**
61     *  the exchange handler to handle are request/response combinations, i.e., exchanges
62     */
63    private HttpMonitorExchangeHandler exchangeHandler;
64   
65    /**
66     * the directory into which the log files shall be written
67     */
68    private String logFileBaseDir;
69
70    /**
71     * the thread needed to handle CTRL-C events
72     */
73    private Thread shutdownHook;
74
75    /**
76     * the name of the proxied server
77     */
78    private String proxiedServer;
79   
80    /**
81     * the port of the proxied server
82     */
83    private int proxiedPort;
84   
85    /**
86     * the name of the server where the HTTP monitor runs if the exchanges are not logged locally
87     */
88    private String httpMonitorServer;
89   
90    /**
91     * the port of the server where the HTTP monitor runs if the exchanges are not logged locally
92     */
93    private int httpMonitorPort;
94   
95    /**
96     * <p>
97     * initializes the proxy with the command line arguments. Those are the log directory
98     * as first argument, the port to listen to as second argument, the proxied server and port
99     * as third argument, and either the server and port of the HTTP monitor or the term local as
100     * fourth argument. If the term local is provided as fourth argument, logging of exchanges
101     * takes place locally.
102     * </p>
103     *
104     * @param commandLineArguments the command line arguments when starting the monitor using
105     *                             the {@link Runner}
106     */
107    public HttpMonitoringProxy(String[] commandLineArguments) {
108        if (commandLineArguments.length != 4) {
109            Console.printerrln("invalid number of command line parameters. Three are required:");
110            Console.printerrln("  1. the port on which to listen");
111            Console.printerrln("  2. the server and port to be proxied (format \"host:port\")");
112            Console.printerrln
113                ("  3. variant a: the value \"local\" for logging recorded exchanges locally");
114            Console.printerrln
115                ("     variant b: the server and port of the HTTP monitor to send the recorded\n" +
116                 "                exchanges to (format \"host:port\")");
117            throw new IllegalArgumentException();
118        }
119       
120        this.logFileBaseDir = commandLineArguments[0];
121
122        try {
123            this.port = Integer.parseInt(commandLineArguments[1]);
124        }
125        catch (NumberFormatException e) {
126            Console.printerrln("invalid port specification " + commandLineArguments[1]);
127        }
128        Console.println("listening on port " + this.port);
129
130        proxiedServer = commandLineArguments[2];
131       
132        int index = proxiedServer.indexOf(':');
133        if (index > -1) {
134            try {
135                proxiedPort = Integer.parseInt(proxiedServer.substring(index + 1));
136            }
137            catch (NumberFormatException e) {
138                Console.printerrln
139                    ("invalid port specification " + proxiedServer.substring(index + 1));
140            }
141           
142            proxiedServer = proxiedServer.substring(0, index);
143        }
144        else {
145            proxiedPort = 80;
146        }
147       
148        Console.println("proxing " + proxiedServer + ":" + proxiedPort);
149       
150        httpMonitorServer = commandLineArguments[3];
151       
152        index = httpMonitorServer.indexOf(':');
153        if (index > -1) {
154            try {
155                httpMonitorPort = Integer.parseInt(httpMonitorServer.substring(index + 1));
156            }
157            catch (NumberFormatException e) {
158                Console.printerrln
159                    ("invalid port specification " + httpMonitorServer.substring(index + 1));
160            }
161           
162            httpMonitorServer = httpMonitorServer.substring(0, index);
163        }
164        else if ("local".equals(httpMonitorServer)) {
165            httpMonitorServer = null;
166        }
167        else {
168            httpMonitorPort = 80;
169        }
170       
171        if (httpMonitorServer != null) {
172            Console.println("sending log data to " + httpMonitorServer + ":" + httpMonitorPort);
173            exchangeHandler =
174                new HttpMonitorRemoteExchangeHandler(httpMonitorServer, httpMonitorPort);
175        }
176        else {
177            Console.println("storing logs locally into directory " + logFileBaseDir);
178            exchangeHandler = new HttpMonitorLogManager(logFileBaseDir);
179        }
180    }
181
182    /* (non-Javadoc)
183     * @see de.ugoe.cs.autoquest.htmlmonitor.HttpMonitorComponent#init()
184     */
185    @Override
186    public synchronized void init() throws HttpMonitorException {
187        if (server != null) {
188            throw new IllegalStateException("already initialized.");
189        }
190       
191        exchangeHandler.init();
192       
193        exchangeListenerManager = new ExchangeListenerManager(exchangeHandler);
194        exchangeListenerManager.init();
195       
196        Servlet servlet =
197            new HttpMonitoringProxyServlet(proxiedServer, proxiedPort, exchangeListenerManager);
198        server = new HttpMonitorServer(port, servlet);
199        server.init();
200     
201        shutdownHook = new Thread
202            (new ShutdownHook(server, exchangeListenerManager, exchangeHandler));
203    }
204
205    /* (non-Javadoc)
206     * @see de.ugoe.cs.autoquest.htmlmonitor.HttpMonitorComponent#start()
207     */
208    @Override
209    public synchronized void start() {
210        if ((exchangeHandler == null) || (exchangeListenerManager == null) || (server == null)) {
211            throw new IllegalStateException("not initialized.");
212        }
213       
214        try {
215            Runtime.getRuntime().addShutdownHook(shutdownHook);
216            exchangeHandler.start();
217            exchangeListenerManager.start();
218            server.start();
219        }
220        catch (HttpMonitorException e) {
221            Console.printerrln("could not start HTTP monitoring proxy: " + e);
222            Console.logException(e);
223        }
224    }
225
226    /* (non-Javadoc)
227     * @see de.ugoe.cs.autoquest.htmlmonitor.HttpMonitorComponent#stop()
228     */
229    @Override
230    public synchronized void stop() {
231        if ((exchangeHandler == null) || (exchangeListenerManager == null) || (server == null)) {
232            throw new IllegalStateException("not initialized.");
233        }
234       
235        Runtime.getRuntime().removeShutdownHook(shutdownHook);
236        server.stop();
237        exchangeListenerManager.stop();
238        exchangeHandler.stop();
239       
240        server = null;
241        exchangeListenerManager = null;
242        exchangeHandler = null;
243    }
244
245}
Note: See TracBrowser for help on using the repository browser.