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

Last change on this file since 1561 was 1561, checked in by pharms, 10 years ago
  • update of namespaces for HTTP logfiles
File size: 7.7 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 java.io.IOException;
18import java.io.OutputStreamWriter;
19import java.util.HashSet;
20import java.util.Set;
21import java.util.logging.Level;
22
23import javax.xml.bind.JAXBContext;
24import javax.xml.bind.JAXBException;
25import javax.xml.bind.Marshaller;
26
27import org.eclipse.jetty.client.HttpClient;
28import org.eclipse.jetty.client.api.Request;
29import org.eclipse.jetty.client.api.Response.CompleteListener;
30import org.eclipse.jetty.client.api.Result;
31import org.eclipse.jetty.client.util.OutputStreamContentProvider;
32import org.eclipse.jetty.http.HttpMethod;
33import org.eclipse.jetty.http.HttpVersion;
34import org.eclipse.jetty.util.thread.QueuedThreadPool;
35
36import de.ugoe.cs.autoquest.httpmonitor.HttpMonitor;
37import de.ugoe.cs.autoquest.httpmonitor.HttpMonitorComponent;
38import de.ugoe.cs.autoquest.httpmonitor.HttpMonitorException;
39import de.ugoe.cs.autoquest.httpmonitor.HttpMonitorExchangeHandler;
40import de.ugoe.cs.autoquest.plugin.http.logdata.HttpExchange;
41import de.ugoe.cs.autoquest.plugin.http.logdata.ObjectFactory;
42import de.ugoe.cs.util.console.Console;
43
44/**
45 * <p>
46 * If the exchanges recorded by the proxy are to be transmitted to a central {@link HttpMonitor},
47 * this exchanges handler is used. It is called by the exchange listener on completion of a proxied
48 * request/response. It then creates an HTTP request to the central monitor and sends it there.
49 * It is initialized with the name of the server and the port on which the central monitor runs.
50 * If the exchanges can not be forwarded to the central server, they are discarded.
51 * </p>
52 *
53 * @author Patrick Harms
54 */
55public class HttpMonitorRemoteExchangeHandler
56    implements CompleteListener, HttpMonitorExchangeHandler, HttpMonitorComponent
57{
58
59    /**
60     * <p>
61     * the HTTP client used internally to send data to the central server
62     * </p>
63     */
64    private HttpClient httpClient;
65   
66    /**
67     * <p>
68     * the host name of the central server
69     * </p>
70     */
71    private String httpMonitorServer;
72   
73    /**
74     * <p>
75     * the port of the central server
76     * </p>
77     */
78    private int httpMonitorPort;
79
80    /**
81     * <p>
82     * a set of requests send to the central server for which the response was not received yet
83     * </p>
84     */
85    private Set<Request> openRequests = new HashSet<Request>();
86   
87    /**
88     * <p>
89     * initializes the exchange handler with the host and port of the central server
90     * </p>
91     *
92     * @param httpMonitorServer the host name of the central server
93     * @param httpMonitorPort   the port of the central server
94     */
95    public HttpMonitorRemoteExchangeHandler(String httpMonitorServer, int httpMonitorPort) {
96        this.httpMonitorServer = httpMonitorServer;
97        this.httpMonitorPort = httpMonitorPort;
98    }
99
100    /* (non-Javadoc)
101     * @see de.ugoe.cs.autoquest.httpmonitor.HttpMonitorComponent#init()
102     */
103    @Override
104    public void init() throws IllegalStateException, HttpMonitorException {
105        httpClient = createHttpClient();
106    }
107
108    /* (non-Javadoc)
109     * @see de.ugoe.cs.autoquest.httpmonitor.HttpMonitorComponent#start()
110     */
111    @Override
112    public void start() throws IllegalStateException, HttpMonitorException {
113        try {
114            httpClient.start();
115            httpClient.getContentDecoderFactories().clear();
116        }
117        catch (Exception e) {
118            throw new HttpMonitorException("could not start client for HTTP-Monitor", e);
119        }
120    }
121
122    /* (non-Javadoc)
123     * @see de.ugoe.cs.autoquest.httpmonitor.HttpMonitorComponent#stop()
124     */
125    @Override
126    public void stop() {
127        if (httpClient != null) {
128            try {
129                httpClient.stop();
130            }
131            catch (Exception e) {
132                Console.traceln(Level.WARNING, "could not stop client for HTTP-Monitor");
133                Console.logException(e);
134            }
135        }
136       
137        httpClient = null;
138    }
139
140    /* (non-Javadoc)
141     * @see de.ugoe.cs.autoquest.httpmonitor.HttpMonitorExchangeHandler#handleHttpExchange()
142     */
143    @Override
144    public void handleHttpExchange(HttpExchange httpExchange) {
145        // send the exchange to the server and wait for completion
146        synchronized (openRequests) {
147            Request httpMonitorRequest = httpClient.newRequest(httpMonitorServer, httpMonitorPort);
148            httpMonitorRequest.method(HttpMethod.POST);
149            httpMonitorRequest.version(HttpVersion.HTTP_1_1);
150
151            OutputStreamContentProvider out = new OutputStreamContentProvider();
152            httpMonitorRequest.content(out);
153            httpMonitorRequest.send(this);
154
155            try {
156                JAXBContext jaxbContext =
157                        JAXBContext.newInstance(HttpExchange.class.getPackage().getName());
158                Marshaller marshaller = jaxbContext.createMarshaller();
159
160                OutputStreamWriter writer = new OutputStreamWriter(out.getOutputStream(), "UTF-8");
161                marshaller.marshal(new ObjectFactory().createHttpExchange(httpExchange), writer);
162
163                out.getOutputStream().close();
164            }
165            catch (JAXBException e) {
166                Console.printerrln("could not convert request and response to XML string: " + e);
167                Console.logException(e);
168            }
169            catch (IOException e) {
170                Console.printerrln
171                ("could not close the stream for sending data to the HTML monitor: " + e);
172                Console.logException(e);
173            }
174           
175            openRequests.add(httpMonitorRequest);
176           
177            try {
178                // wait for the request to be removed fromt the list asynchronously
179                while (openRequests.contains(httpMonitorRequest)) {
180                    openRequests.wait();
181                }
182            }
183            catch (InterruptedException e) {
184                // ignore, as this may only happen on system shutdown
185            }
186        }
187    }
188
189    /* (non-Javadoc)
190     * @see org.eclipse.jetty.client.api.Response.CompleteListener#onComplete(Result)
191     */
192    @Override
193    public void onComplete(Result result) {
194        if (result.isFailed()) {
195            Console.traceln
196                (Level.WARNING, "could not log exchange correctly: " + result.getFailure());
197            Console.logException((Exception) result.getFailure());
198        }
199       
200        synchronized (openRequests) {
201            openRequests.remove(result.getRequest());
202            openRequests.notify();
203        }
204    }
205
206    /**
207     * <p>
208     * convenience method to create an initialize the utilized HTTP client
209     * </p>
210     */
211    private HttpClient createHttpClient() {
212        HttpClient client = new HttpClient();
213       
214        QueuedThreadPool executor = new QueuedThreadPool(10);
215        executor.setName("HttpMonitorClients");
216        client.setExecutor(executor);
217
218        client.setMaxConnectionsPerDestination(10000);
219        client.setIdleTimeout(30000);
220        client.setConnectTimeout(30000);
221        client.setStopTimeout(30000);
222        client.setRequestBufferSize(1024*1024);
223        client.setResponseBufferSize(1024*1024);
224       
225        return client;
226    }
227}
Note: See TracBrowser for help on using the repository browser.