source: trunk/autoquest-plugin-http/src/main/java/de/ugoe/cs/autoquest/plugin/http/HTTPLogParser.java @ 1417

Last change on this file since 1417 was 1417, checked in by pharms, 10 years ago
  • made the plugin a real plugin
  • added first extraction of SOAP information
  • implemented equals and hash code correctly
  • parsed events can now be used to generate task trees
File size: 6.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.plugin.http;
16
17import java.io.ByteArrayInputStream;
18import java.io.File;
19import java.io.InputStream;
20import java.util.Collection;
21import java.util.LinkedList;
22import java.util.List;
23import java.util.logging.Level;
24
25import javax.xml.bind.JAXBContext;
26import javax.xml.bind.JAXBElement;
27import javax.xml.bind.JAXBException;
28import javax.xml.bind.Unmarshaller;
29import javax.xml.soap.MessageFactory;
30import javax.xml.soap.SOAPMessage;
31import javax.xml.transform.stream.StreamSource;
32
33import org.xml.sax.SAXException;
34
35import de.ugoe.cs.autoquest.eventcore.Event;
36import de.ugoe.cs.autoquest.eventcore.IEventType;
37import de.ugoe.cs.autoquest.httpmonitor.exchange.Content;
38import de.ugoe.cs.autoquest.httpmonitor.exchange.HttpExchange;
39import de.ugoe.cs.autoquest.httpmonitor.exchange.Session;
40import de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPEventType;
41import de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPTarget;
42import de.ugoe.cs.autoquest.plugin.http.eventcore.SOAPEventType;
43import de.ugoe.cs.util.console.Console;
44
45/**
46 * <p>
47 * Parser for HTTP Monitor logs. Uses JAXB for parsing and is therefore quite simple. For each
48 * exchange in the log, it creates an appropriate event. It differes between default HTTP events
49 * and SOAP events.
50 * </p>
51 *
52 * @author Patrick Harms
53 */
54public class HTTPLogParser {
55
56    /**
57     * <p>
58     * the event sequences parsed by this parser
59     * </p>
60     */
61    private Collection<List<Event>> sequences = new LinkedList<List<Event>>();
62   
63    /**
64     * <p>
65     * the message factory used for parsing SOAP messages
66     * </p>
67     */
68    private MessageFactory soapMessageFactory;
69
70    /**
71     * <p>
72     * Parses a log file written by the HTTPMonitor and creates a collection of event sequences.
73     * </p>
74     *
75     * @param filename
76     *            name and path of the log file
77     *
78     * @throws SAXException in the case, the file could not be parsed
79     */
80    public void parseFile(String filename) throws JAXBException {
81        if (filename == null) {
82            throw new IllegalArgumentException("filename must not be null");
83        }
84
85        parseFile(new File(filename));
86    }
87
88    /**
89     * <p>
90     * Parses a log file written by the HTTPMonitor and creates a collection of event sequences.
91     * </p>
92     *
93     * @param file
94     *            file to be parsed
95     *
96     * @throws SAXException in the case, the file could not be parsed
97     */
98    public void parseFile(File file) throws JAXBException {
99        if (file == null) {
100            throw new IllegalArgumentException("file must not be null");
101        }
102       
103        JAXBContext jc = JAXBContext.newInstance(Session.class.getPackage().getName());
104       
105        Unmarshaller unmarshaller = jc.createUnmarshaller();
106        StreamSource source = new StreamSource(file);
107       
108        @SuppressWarnings("unchecked")
109        JAXBElement<Session> sessionObj = (JAXBElement<Session>) unmarshaller.unmarshal(source);
110       
111        Session session = sessionObj.getValue();
112
113        if ((session.getHttpExchange() != null) && (session.getHttpExchange().size() > 0)) {
114            List<Event> sequence = new LinkedList<Event>();
115            for (HttpExchange exchange : session.getHttpExchange()) {
116                sequence.add(new Event(createEvent(exchange),
117                                       new HTTPTarget(exchange.getReceiver())));
118            }
119            sequences.add(sequence);
120        }
121       
122    }
123
124    /**
125     * <p>
126     * instantiates the appropriate event type. If it encounters a SOAP exchange, a SOAP event type
127     * is instantiated. Otherwise a normal HTTP event type is created.
128     * </p>
129     *
130     * @param exchange the exchange for which an event type is to be created
131     *
132     * @return as described
133     */
134    private IEventType createEvent(HttpExchange exchange) {
135        Content requestContent =
136            exchange.getRequest() != null ? exchange.getRequest().getContent() : null;
137       
138        SOAPMessage soapRequest = getSOAPMessage(requestContent);
139       
140        Content responseContent =
141            exchange.getResponse() != null ? exchange.getResponse().getContent() : null;
142           
143        SOAPMessage soapResponse = getSOAPMessage(responseContent);
144       
145        if (soapRequest != null) {
146            return new SOAPEventType(exchange, soapRequest, soapResponse);
147        }
148        else {
149            return new HTTPEventType(exchange);
150        }
151    }
152
153    /**
154     * <p>
155     * convenience method to convert the content of an HTTP request or response into a SOAP message
156     * </p>
157     *
158     * @param content the content to be converted into a SOAP message
159     *
160     * @return the SOAP message contained in the content or null if either the content is null or
161     *         the content does not contain a SOAP message
162     */
163    private SOAPMessage getSOAPMessage(Content content) {
164        if ((content != null) && (content.getData() != null)) {
165            try {
166                if (soapMessageFactory == null) {
167                    soapMessageFactory = MessageFactory.newInstance();
168                }
169           
170                String encoding = content.getEncoding();
171                if (encoding == null) {
172                    encoding = "UTF-8";
173                }
174               
175                InputStream in = new ByteArrayInputStream(content.getData().getBytes(encoding));
176                return soapMessageFactory.createMessage(null, in);
177            }
178            catch (Exception e) {
179                if (content.getData().toLowerCase().indexOf("envelope") > 0) {
180                    Console.traceln(Level.WARNING, "HTTP message seems to be a SOAP message but " +
181                                    "it could not be parsed as such: " + e);
182                    Console.logException(e);
183                }
184            }
185        }
186       
187        return null;
188    }
189
190    /**
191     * <p>
192     * returns the sequences parsed by this parser
193     * </p>
194     *
195     * @return as described
196     */
197    public Collection<List<Event>> getSequences() {
198        return sequences;
199    }
200}
Note: See TracBrowser for help on using the repository browser.