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

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