source: trunk/autoquest-plugin-http/src/main/java/de/ugoe/cs/autoquest/plugin/http/eventcore/SimpleSOAPEventType.java @ 1984

Last change on this file since 1984 was 1984, checked in by sherbold, 9 years ago
  • SimpleSOAPEventType now maintain a repository with potential test data and allow random selection of a request body based on all observed calls to an operation of the same receiver with the same client
  • Property svn:mime-type set to text/plain
File size: 10.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.plugin.http.eventcore;
16
17import java.io.ByteArrayInputStream;
18import java.io.IOException;
19import java.util.Collections;
20import java.util.HashMap;
21import java.util.Map;
22import java.util.Random;
23import java.util.Set;
24
25import javax.xml.parsers.DocumentBuilderFactory;
26import javax.xml.parsers.ParserConfigurationException;
27
28import org.apache.commons.collections4.set.ListOrderedSet;
29import org.w3c.dom.Element;
30import org.xml.sax.SAXException;
31
32import de.ugoe.cs.autoquest.eventcore.IEventType;
33import de.ugoe.cs.autoquest.plugin.http.HTTPUtils;
34import de.ugoe.cs.autoquest.plugin.http.SOAPUtils;
35
36/**
37 * <p>
38 * A simplified SOAP event type that only contains the name of the called method and the name of the
39 * service.
40 * </p>
41 *
42 * @author Steffen Herbold
43 */
44public class SimpleSOAPEventType implements IEventType {
45
46    /**  */
47    private static final long serialVersionUID = 1L;
48   
49    /**
50     * see {@link RequestBodyMode}
51     */
52    private static RequestBodyMode requestBodyMode = RequestBodyMode.LOCALEVENT;
53
54    /**
55     * <p>
56     * the SOAP method called in this request
57     * </p>
58     */
59    private final String calledMethod;
60
61    /**
62     * <p>
63     * the name of the service; this is either the path or, if a path map is available
64     * </p>
65     */
66    private final String serviceName;
67
68    /**
69     * <p>
70     * the name of the client; this is either the host/ip and port of the sender or, if a path map
71     * is available, a human readable name that may be based also on the receiver
72     * </p>
73     */
74    private final String clientName;
75
76    /**
77     * <p>
78     * the body of the SOAP request; storage as serialized XML string to allow object serialization
79     * </p>
80     */
81    private final String soapRequestBody;
82
83    /**
84     * <p>
85     * Constructor. Creates a new SimpleSOAPEventType.
86     * </p>
87     *
88     */
89    public SimpleSOAPEventType(String calledMethod,
90                               String serviceName,
91                               String clientName,
92                               Element soapRequestBody)
93    {
94        if (calledMethod == null) {
95            throw new IllegalArgumentException("called method must not be null");
96        }
97        if (serviceName == null) {
98            throw new IllegalArgumentException("serviceName must not be null");
99        }
100        if (clientName == null) {
101            throw new IllegalArgumentException("clientName must not be null");
102        }
103        this.calledMethod = calledMethod;
104        this.serviceName = serviceName;
105        this.clientName = clientName;
106        this.soapRequestBody = SOAPUtils.getSerialization(soapRequestBody);
107        EqualSOAPDataMap.INSTANCE.add(this, this.soapRequestBody);
108    }
109
110    /**
111     * <p>
112     * the SOAP method called in this request
113     * </p>
114     *
115     * @return the SOAP method called in this request
116     */
117    public String getCalledMethod() {
118        return calledMethod;
119    }
120
121    /**
122     * <p>
123     * the name of the service called in this request
124     * </p>
125     *
126     * @return the name of the service called in this request
127     */
128    public String getServiceName() {
129        return serviceName;
130    }
131
132    /**
133     * <p>
134     * the name of the client calling in this request
135     * </p>
136     *
137     * @return the name of the client calling in this request
138     */
139    public String getClientName() {
140        return clientName;
141    }
142
143    /**
144     * <p>
145     * returns the body of the SOAP request; how the body is determined is defined by the {@link RequestBodyMode}.
146     * </p>
147     *
148     * @return body of the SOAP request
149     */
150    public Element getSoapRequestBody() {
151        String requestBody;
152        switch (requestBodyMode)
153        {
154            case LOCALEVENT:
155                requestBody = soapRequestBody;
156                break;
157            case RANDOM:
158                requestBody = EqualSOAPDataMap.INSTANCE.getRandom(this);
159                break;
160            default:
161                throw new RuntimeException("undefined RequestBodyMode");
162        }
163        if( requestBody==null ) {
164            System.err.println("foobar" + this);
165            System.err.println(EqualSOAPDataMap.INSTANCE.getAll(this));
166        }
167        try {
168            return DocumentBuilderFactory.newInstance().newDocumentBuilder()
169                .parse(new ByteArrayInputStream(requestBody.getBytes())).getDocumentElement();
170        }
171        catch (SAXException | IOException | ParserConfigurationException e) {
172            return null;
173        }
174    }
175   
176   
177
178    /*
179     * (non-Javadoc)
180     *
181     * @see de.ugoe.cs.autoquest.eventcore.IEventType#getName()
182     */
183    @Override
184    public String getName() {
185        return "(" + serviceName + ", " + calledMethod + ")";
186    }
187
188    /*
189     * (non-Javadoc)
190     *
191     * @see de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPEventType#equals(java.lang.Object)
192     */
193    @Override
194    public boolean equals(Object obj) {
195        if (this == obj) {
196            return true;
197        }
198        else if (obj instanceof SimpleSOAPEventType) {
199            return HTTPUtils.equals(calledMethod, ((SimpleSOAPEventType) obj).calledMethod) &&
200                HTTPUtils.equals(serviceName, ((SimpleSOAPEventType) obj).serviceName) &&
201                HTTPUtils.equals(clientName, ((SimpleSOAPEventType) obj).clientName);
202        }
203        else {
204            return false;
205        }
206    }
207
208    /*
209     * (non-Javadoc)
210     *
211     * @see de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPEventType#hashCode()
212     */
213    @Override
214    public int hashCode() {
215        int hashCode = calledMethod.hashCode() + serviceName.hashCode() + clientName.hashCode();
216        return hashCode;
217    }
218
219    /*
220     * (non-Javadoc)
221     *
222     * @see java.lang.Object#toString()
223     */
224    @Override
225    public String toString() {
226        return "SimpleSOAPEventType(" + serviceName + ", " + calledMethod + ")";
227    }
228   
229    /**
230     * <p>
231     * returns the current {@link RequestBodyMode}
232     * </p>
233     *
234     * @return the requestBodyMode
235     */
236    public static RequestBodyMode getRequestBodyMode() {
237        return requestBodyMode;
238    }
239   
240    /**
241     * <p>
242     * sets the {@link RequestBodyMode}
243     * </p>
244     *
245     * @param new requestBodyMode
246     */
247    public static void setRequestBodyMode(RequestBodyMode requestBodyMode) {
248        SimpleSOAPEventType.requestBodyMode = requestBodyMode;
249    }
250   
251    /**
252     * <p>
253     * Determines how getSoapRequestBody works.
254     * <ul>
255     * <li>LOCALEVENT: returns the request body of the event type itself</li>
256     * <li>RANDOM: returns a randomly draw request body for the called method using {@link EqualSOAPDataMap#getRandom(SimpleSOAPEventType)}.
257     * </ul>
258     * </p>
259     *
260     * @author Steffen Herbold
261     */
262    public static enum RequestBodyMode {LOCALEVENT, RANDOM};
263   
264    /**
265     * <p>
266     * Handles all request bodies of equal SOAP events. Can be used to view either all request bodies sent to an operation or to randomly draw one of the bodies.
267     * </p>
268     *
269     * @author Steffen Herbold
270     */
271    public static class EqualSOAPDataMap {
272       
273        /**
274         * Singleton. Handle to only instance of this class
275         */
276        public final static EqualSOAPDataMap INSTANCE = new EqualSOAPDataMap();
277       
278        /**
279         * Map with all soapRequestBodies for all equal {@link SimpleSOAPEventType}s
280         */
281        private final Map<SimpleSOAPEventType, ListOrderedSet<String>> soapRequestBodies = new HashMap<>();
282       
283        /**
284         * random number generator for picking a random request body
285         */
286        private final Random random = new Random(1); // TODO static seed for testing
287       
288        private EqualSOAPDataMap() {
289            // private constructor to avoid initialization
290        }
291
292        /**
293         * <p>
294         * Adds a new body to the map.
295         * </p>
296         *
297         * @param simpleSOAPEventType
298         */
299        public void add(SimpleSOAPEventType simpleSOAPEventType, String soapRequestBody) {
300            if( soapRequestBody!=null ) {
301                ListOrderedSet<String> requestBodySet = soapRequestBodies.get(simpleSOAPEventType);
302                if( requestBodySet==null ) {
303                    requestBodySet = new ListOrderedSet<>();
304                    soapRequestBodies.put(simpleSOAPEventType, requestBodySet);
305                }
306                requestBodySet.add(soapRequestBody);
307            }
308        }
309       
310        /**
311         * <p>
312         * Retrieves all bodies associated with the simpleSoapEventType; null if not found
313         * </p>
314         *
315         * @param simpleSoapEventType
316         * @return
317         */
318        public Set<String> getAll(SimpleSOAPEventType simpleSoapEventType) {
319            return Collections.unmodifiableSet(soapRequestBodies.get(simpleSoapEventType));
320        }
321       
322        /**
323         * <p>
324         * Randomly draws one of the SOAP event type bodies associated with the event
325         * </p>
326         *
327         * @param simpleSOAPEventType
328         * @return
329         */
330        public String getRandom(SimpleSOAPEventType simpleSOAPEventType) {
331            ListOrderedSet<String> requestBodySet = soapRequestBodies.get(simpleSOAPEventType);
332            if( requestBodySet==null || requestBodySet.isEmpty() ) {
333                throw new RuntimeException("no request body known for SimpleSOAPEventType: " + simpleSOAPEventType);
334            }
335           
336            return requestBodySet.get(random.nextInt(requestBodySet.size()));
337        }
338    }
339}
Note: See TracBrowser for help on using the repository browser.