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

Last change on this file since 1991 was 1991, checked in by pharms, 9 years ago
  • added ordering id for requests and responses
File size: 9.4 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.IdGenerator;
25import de.ugoe.cs.autoquest.httpmonitor.Runner;
26import de.ugoe.cs.autoquest.httpmonitor.ShutdownHook;
27import de.ugoe.cs.autoquest.httpmonitor.SimpleIdGenerator;
28import de.ugoe.cs.util.console.Console;
29
30/**
31 * <p>
32 * The HTTP monitory proxy monitor starts a web server ({@link HttpMonitorServer}) that receives
33 * proxied HTTP messages and response. Each exchange of a request and a response is forwarded to
34 * an exchange handler. The exchange handler is either a local log manager
35 * ({@link HttpMonitorLogManager}) or a connection to an external and central HTTP monitor via
36 * an {@link HttpMonitorRemoteExchangeHandler}. It also holds a reference to an id generator. If
37 * the exchanges are handled locally, then also a local {@link SimpleIdGenerator} is used. If
38 * the exchanges are send to a central HTTP monitor, then this monitor is used as id generator via
39 * an {@link HttpMonitorRemoteIdGenerator}. The class ensures that on shutdown e.g. caused
40 * by CTRL-C the server and all other requied components are stopped correctly.
41 * </p>
42 *
43 * @author Patrick Harms
44 */
45public class HttpMonitoringProxy implements HttpMonitorComponent {
46
47    /**
48     * the port on which the webserver shall listen.
49     */
50    private int port;
51   
52    /**
53     * the web server receiving the HTTP requests to be proxied
54     */
55    private HttpMonitorServer server;
56   
57    /**
58     * the manager for all currently recorded exchanges
59     */
60    private ExchangeListenerManager exchangeListenerManager;
61   
62    /**
63     *  the exchange handler to handle are request/response combinations, i.e., exchanges
64     */
65    private HttpMonitorExchangeHandler exchangeHandler;
66   
67    /**
68     *  the id generator used to generate order ids for the requests and responses
69     */
70    private IdGenerator idGenerator;
71   
72    /**
73     * the directory into which the log files shall be written
74     */
75    private String logFileBaseDir;
76
77    /**
78     * the thread needed to handle CTRL-C events
79     */
80    private Thread shutdownHook;
81
82    /**
83     * the name of the proxied server
84     */
85    private String proxiedServer;
86   
87    /**
88     * the port of the proxied server
89     */
90    private int proxiedPort;
91   
92    /**
93     * the name of the server where the HTTP monitor runs if the exchanges are not logged locally
94     */
95    private String httpMonitorServer;
96   
97    /**
98     * the port of the server where the HTTP monitor runs if the exchanges are not logged locally
99     */
100    private int httpMonitorPort;
101   
102    /**
103     * <p>
104     * initializes the proxy with the command line arguments. Those are the log directory
105     * as first argument, the port to listen to as second argument, the proxied server and port
106     * as third argument, and either the server and port of the HTTP monitor or the term local as
107     * fourth argument. If the term local is provided as fourth argument, logging of exchanges
108     * takes place locally.
109     * </p>
110     *
111     * @param commandLineArguments the command line arguments when starting the monitor using
112     *                             the {@link Runner}
113     */
114    public HttpMonitoringProxy(String[] commandLineArguments) {
115        if (commandLineArguments.length != 4) {
116            Console.printerrln("invalid number of command line parameters. Three are required:");
117            Console.printerrln("  1. the port on which to listen");
118            Console.printerrln("  2. the server and port to be proxied (format \"host:port\")");
119            Console.printerrln
120                ("  3. variant a: the value \"local\" for logging recorded exchanges locally");
121            Console.printerrln
122                ("     variant b: the server and port of the HTTP monitor to send the recorded\n" +
123                 "                exchanges to (format \"host:port\")");
124            throw new IllegalArgumentException();
125        }
126       
127        this.logFileBaseDir = commandLineArguments[0];
128
129        try {
130            this.port = Integer.parseInt(commandLineArguments[1]);
131        }
132        catch (NumberFormatException e) {
133            Console.printerrln("invalid port specification " + commandLineArguments[1]);
134        }
135        Console.println("listening on port " + this.port);
136
137        proxiedServer = commandLineArguments[2];
138       
139        int index = proxiedServer.indexOf(':');
140        if (index > -1) {
141            try {
142                proxiedPort = Integer.parseInt(proxiedServer.substring(index + 1));
143            }
144            catch (NumberFormatException e) {
145                Console.printerrln
146                    ("invalid port specification " + proxiedServer.substring(index + 1));
147            }
148           
149            proxiedServer = proxiedServer.substring(0, index);
150        }
151        else {
152            proxiedPort = 80;
153        }
154       
155        Console.println("proxing " + proxiedServer + ":" + proxiedPort);
156       
157        httpMonitorServer = commandLineArguments[3];
158       
159        index = httpMonitorServer.indexOf(':');
160        if (index > -1) {
161            try {
162                httpMonitorPort = Integer.parseInt(httpMonitorServer.substring(index + 1));
163            }
164            catch (NumberFormatException e) {
165                Console.printerrln
166                    ("invalid port specification " + httpMonitorServer.substring(index + 1));
167            }
168           
169            httpMonitorServer = httpMonitorServer.substring(0, index);
170        }
171        else if ("local".equals(httpMonitorServer)) {
172            httpMonitorServer = null;
173        }
174        else {
175            httpMonitorPort = 80;
176        }
177       
178        if (httpMonitorServer != null) {
179            Console.println("sending log data to " + httpMonitorServer + ":" + httpMonitorPort);
180            exchangeHandler =
181                new HttpMonitorRemoteExchangeHandler(httpMonitorServer, httpMonitorPort);
182           
183            idGenerator = new HttpMonitorRemoteIdGenerator(httpMonitorServer, httpMonitorPort);
184        }
185        else {
186            Console.println("storing logs locally into directory " + logFileBaseDir);
187            exchangeHandler = new HttpMonitorLogManager(logFileBaseDir);
188            idGenerator = new SimpleIdGenerator();
189        }
190    }
191
192    /* (non-Javadoc)
193     * @see de.ugoe.cs.autoquest.htmlmonitor.HttpMonitorComponent#init()
194     */
195    @Override
196    public synchronized void init() throws HttpMonitorException {
197        if (server != null) {
198            throw new IllegalStateException("already initialized.");
199        }
200       
201        exchangeHandler.init();
202        idGenerator.init();
203       
204        exchangeListenerManager = new ExchangeListenerManager(exchangeHandler, idGenerator);
205        exchangeListenerManager.init();
206       
207        Servlet servlet =
208            new HttpMonitoringProxyServlet(proxiedServer, proxiedPort, exchangeListenerManager);
209        server = new HttpMonitorServer(port, servlet);
210        server.init();
211     
212        shutdownHook = new Thread
213            (new ShutdownHook(server, exchangeListenerManager, exchangeHandler));
214    }
215
216    /* (non-Javadoc)
217     * @see de.ugoe.cs.autoquest.htmlmonitor.HttpMonitorComponent#start()
218     */
219    @Override
220    public synchronized void start() {
221        if ((exchangeHandler == null) || (idGenerator == null) ||
222            (exchangeListenerManager == null) || (server == null))
223        {
224            throw new IllegalStateException("not initialized.");
225        }
226       
227        try {
228            Runtime.getRuntime().addShutdownHook(shutdownHook);
229            exchangeHandler.start();
230            idGenerator.start();
231            exchangeListenerManager.start();
232            server.start();
233        }
234        catch (HttpMonitorException e) {
235            Console.printerrln("could not start HTTP monitoring proxy: " + e);
236            Console.logException(e);
237        }
238    }
239
240    /* (non-Javadoc)
241     * @see de.ugoe.cs.autoquest.htmlmonitor.HttpMonitorComponent#stop()
242     */
243    @Override
244    public synchronized void stop() {
245        if ((exchangeHandler == null) || (idGenerator == null) ||
246            (exchangeListenerManager == null) || (server == null))
247        {
248            throw new IllegalStateException("not initialized.");
249        }
250       
251        Runtime.getRuntime().removeShutdownHook(shutdownHook);
252        server.stop();
253        exchangeListenerManager.stop();
254        idGenerator.stop();
255        exchangeHandler.stop();
256       
257        server = null;
258        exchangeListenerManager = null;
259        idGenerator = null;
260        exchangeHandler = null;
261    }
262
263}
Note: See TracBrowser for help on using the repository browser.