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

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