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

Last change on this file since 1990 was 1988, checked in by sherbold, 9 years ago
  • updated EqualSOAPDataMap: not a singleton anymore, now each event has a reference to the map. the map is created when the SOAPEvents are converted to SimpleSOAPEvents using the appropriate method from the SOAPUtils
  • the logic for deciding if random SOAP requests are selected or the one of the event itself was changed within the SimpleSOAPEvents. Now methods for both are offered and the caller has to decide which method to choose
  • the test case generation in the model utils now has a parameter to decide if random data or the data of the SimpleSOAPEvents is used
  • Property svn:mime-type set to text/plain
File size: 14.2 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.StringWriter;
18import java.util.ArrayList;
19import java.util.Collection;
20import java.util.Iterator;
21import java.util.LinkedList;
22import java.util.List;
23
24import javax.xml.transform.Transformer;
25import javax.xml.transform.TransformerException;
26import javax.xml.transform.TransformerFactory;
27import javax.xml.transform.TransformerFactoryConfigurationError;
28import javax.xml.transform.dom.DOMSource;
29import javax.xml.transform.stream.StreamResult;
30
31import org.w3c.dom.Attr;
32import org.w3c.dom.Element;
33import org.w3c.dom.Node;
34import org.w3c.dom.NodeList;
35
36import de.ugoe.cs.autoquest.eventcore.Event;
37import de.ugoe.cs.autoquest.plugin.http.eventcore.EqualSOAPDataMap;
38import de.ugoe.cs.autoquest.plugin.http.eventcore.SOAPEventType;
39import de.ugoe.cs.autoquest.plugin.http.eventcore.SimpleSOAPEventType;
40
41/**
42 * <p>
43 * Utilities for working with SOAP events. Their main task is to simply working with
44 * {@link SimpleSOAPEventType} and {@link SOAPEventType}.
45 * </p>
46 *
47 * @author Steffen Herbold
48 */
49public class SOAPUtils {
50
51    /**
52     * <p>
53     * Replaces events with a {@link SOAPEventType} with new events of {@link SimpleSOAPEventType}
54     * and no target.
55     * </p>
56     *
57     * @param sequences
58     *            sequences where the events are replaced
59     * @param keepOnlySOAPEvents
60     *            if true, all events that are not of SOAPEventType or SimpleSOAPEventType are
61     *            removed
62     * @return sequences with {@link SimpleSOAPEventType}s instead of {@link SOAPEventType}s
63     */
64    public static Collection<List<Event>> convertToSimpleSOAPEvent(Collection<List<Event>> sequences,
65                                                       boolean keepOnlySOAPEvents)
66    {
67        Collection<List<Event>> newSequences = new LinkedList<>();
68        EqualSOAPDataMap equalSOAPDataMap = new EqualSOAPDataMap();
69        for( List<Event> sequence : sequences ) {
70            List<Event> newSequence = null;
71            if (sequence != null) {
72                newSequence = new LinkedList<>();
73                for (Event event : sequence) {
74                    if (event.getType() instanceof SOAPEventType) {
75                        SOAPEventType eventType = (SOAPEventType) event.getType();
76                        newSequence.add(new Event(new SimpleSOAPEventType(eventType.getCalledMethod(),
77                                                                          eventType.getServiceName(),
78                                                                          eventType.getClientName(),
79                                                                          eventType
80                                                                              .getSoapRequestBody(),
81                                                                          equalSOAPDataMap)));
82                    }
83                    else {
84                        if (!keepOnlySOAPEvents || event.getType() instanceof SimpleSOAPEventType) {
85                            newSequence.add(event);
86                        }
87                    }
88                }
89            }
90            newSequences.add(newSequence);
91        }
92        return newSequences;
93    }
94   
95    /**
96     * <p>
97     * Removes all non SOAP events from a sequence. Warning: this change is performed in-place!
98     * </p>
99     *
100     * @param sequence
101     *            sequence where the events are replaced
102     */
103    public static void removeNonSOAPEvents(List<Event> sequence) {
104        for (Iterator<Event> eventIter = sequence.iterator(); eventIter.hasNext();) {
105            Event event = eventIter.next();
106            if (!(event.getType() instanceof SOAPEventType)) {
107                eventIter.remove();
108            }
109        }
110    }
111
112    /**
113     * <p>
114     * Helper function to get the name of a service from a SOAP event.
115     * </p>
116     *
117     * @param event
118     *            event for which the service name is retrieved
119     * @return service name
120     */
121    public static String getServiceNameFromEvent(Event event) {
122        if (event.getType() instanceof SOAPEventType) {
123            return ((SOAPEventType) event.getType()).getServiceName();
124        }
125        else if (event.getType() instanceof SimpleSOAPEventType) {
126            return ((SimpleSOAPEventType) event.getType()).getServiceName();
127        }
128        else {
129            throw new RuntimeException(
130                                       "Wrong event type. Only SOAPEventType and SimpleSOAPEventType supported but was: " +
131                                           event.getType().getClass().getName());
132        }
133    }
134
135    /**
136     *
137     * <p>
138     * Helper function to get the called method from a SOAP event
139     * </p>
140     *
141     * @param event
142     *            event for which the called method is retrieved
143     * @return called method
144     */
145    public static String getCalledMethodFromEvent(Event event) {
146        if (event.getType() instanceof SOAPEventType) {
147            return ((SOAPEventType) event.getType()).getCalledMethod();
148        }
149        else if (event.getType() instanceof SimpleSOAPEventType) {
150            return ((SimpleSOAPEventType) event.getType()).getCalledMethod();
151        }
152        else {
153            throw new RuntimeException(
154                                       "Wrong event type. Only SOAPEventType and SimpleSOAPEventType supported but was: " +
155                                           event.getType().getClass().getName());
156        }
157    }
158
159    /**
160     * <p>
161     * Helper function to get the name of a client from a SOAP event.
162     * </p>
163     *
164     * @param event
165     *            event for which the client name is retrieved
166     * @return service name
167     */
168    public static String getClientNameFromEvent(Event event) {
169        if (event.getType() instanceof SOAPEventType) {
170            return ((SOAPEventType) event.getType()).getClientName();
171        }
172        else if (event.getType() instanceof SimpleSOAPEventType) {
173            return ((SimpleSOAPEventType) event.getType()).getClientName();
174        }
175        else {
176            throw new RuntimeException(
177                                       "Wrong event type. Only SOAPEventType and SimpleSOAPEventType supported but was: " +
178                                           event.getType().getClass().getName());
179        }
180    }
181
182    /**
183     * <p>
184     * Helper function to get the body of a SOAP request.
185     * </p>
186     *
187     * @param event
188     *            event for which the SOAP request body is retrieved
189     * @return body of the SOAP event
190     */
191    public static Element getSoapRequestBodyFromEvent(Event event) {
192        return getSoapRequestBodyFromEvent(event, false);
193    }
194   
195    /**
196     * <p>
197     * Helper function to get the body of a SOAP request.
198     * </p>
199     *
200     * @param event
201     *            event for which the SOAP request body is retrieved
202     * @param useRandomRequestBodies
203     *            defines is random request bodies are used or the body of the associated event
204     * @return body of the SOAP event
205     */
206    public static Element getSoapRequestBodyFromEvent(Event event, boolean useRandomRequestBodies) {
207        Element requestBody = null;
208        if (event.getType() instanceof SOAPEventType) {
209            requestBody = ((SOAPEventType) event.getType()).getSoapRequestBody();
210        }
211        else if (event.getType() instanceof SimpleSOAPEventType) {
212            if( useRandomRequestBodies ) {
213                requestBody = ((SimpleSOAPEventType) event.getType()).getRandomSoapRequestBody();
214            } else {
215                requestBody = ((SimpleSOAPEventType) event.getType()).getSoapRequestBody();
216            }
217        }
218        return requestBody;
219    }
220
221    /**
222     * <p>
223     * returns the XML serialization of a DOM node; located here because it is used for SOAP request
224     * bodies
225     * </p>
226     *
227     * @param node
228     *            DOM node that is serialized
229     * @return XML serialization as String; null if node is null
230     */
231    public static String getSerialization(Node node) {
232        if (node == null) {
233            return null;
234        }
235        try {
236            StringWriter writer = new StringWriter();
237            Transformer transformer = TransformerFactory.newInstance().newTransformer();
238            transformer.transform(new DOMSource(node), new StreamResult(writer));
239            return writer.toString();
240        }
241        catch (TransformerFactoryConfigurationError | TransformerException e) {
242            throw new IllegalArgumentException(
243                                               "could not create serialization for SOAP request body.",
244                                               e);
245        }
246    }
247
248    /**
249     * <p>
250     * Fetches all {@link Element}s that are direct children of the parent node, whose name matches
251     * the given name.
252     * </p>
253     *
254     * @param typeNameRaw
255     *            name of elements that are looked for
256     * @param parentNode
257     *            DOM node in which the elements are searched for
258     * @return found {@link Element}s
259     */
260    public static List<Element> getMatchingChildNode(String typeNameRaw, Element parentNode) {
261        List<Element> matchingNodes = new ArrayList<>();
262        Node parameterNode = null;
263        if (parentNode != null) {
264            NodeList parameterNodes = parentNode.getChildNodes();
265            String[] typeNameSplit = typeNameRaw.split(":");
266            String typeName = typeNameSplit[typeNameSplit.length - 1];
267            for (int i = 0; i < parameterNodes.getLength(); i++) {
268                parameterNode = parameterNodes.item(i);
269                if (parameterNode.getNodeType() == Node.ELEMENT_NODE) {
270                    String[] parameterNodeSplit = parameterNode.getNodeName().split(":");
271                    String parameterNodeName = parameterNodeSplit[parameterNodeSplit.length - 1];
272                    if (typeName.equals(parameterNodeName)) {
273                        matchingNodes.add((Element) parameterNode);
274                    }
275                }
276            }
277        }
278        return matchingNodes;
279    }
280
281    /**
282     * <p>
283     * Returns the values found in a currentNode for a defined valueName. To this aim, this methods
284     * first determines if there is an attribute with the name "valueName". If this is the case, the
285     * value of this attribute is returned. Otherwise, the methods looks for {@link Element}s that
286     * are direct children of the provided DOM node with the given name and returns the text content
287     * of those nodes.
288     * </p>
289     * <p>
290     * In case no values can be found, an empty list is returned
291     *
292     * @param valueName
293     *            name of the value that is retrieved
294     * @param node
295     *            node for which the value is retrieved
296     * @return list of the found values.
297     */
298    public static List<String> getValuesFromElement(String valueName, Element node) {
299        List<String> attributeValues = new LinkedList<>();
300
301        if (node != null) {
302            // first check attributes of the node
303            Attr attribute = node.getAttributeNode(valueName);
304            if (attribute != null) {
305                attributeValues.add(attribute.getValue());
306            }
307            else {
308                // now check elements
309                List<Element> elements = getMatchingChildNode(valueName, node);
310                for (Element element : elements) {
311                    attributeValues.add(element.getTextContent());
312                }
313            }
314        }
315
316        return attributeValues;
317    }
318   
319    /**
320     * <p>
321     * Allows the removal of pre- and suffixes from SOAP operation names in {@link SimpleSOAPEventType}.
322     * </p>
323     *
324     * @param sequences sequences where the operation names are normalized
325     */
326    public static Collection<List<Event>> normalizeOperationNames(Collection<List<Event>> sequences, String prefixToRemove, String suffixToRemove) {
327        Collection<List<Event>> normalizedSequences = new LinkedList<>();
328        for(List<Event> sequence : sequences ) {
329            List<Event> normalizedSequence = new LinkedList<>();
330            for (Iterator<Event> eventIter = sequence.iterator(); eventIter.hasNext();) {
331                Event event = eventIter.next();
332                if ((event.getType() instanceof SimpleSOAPEventType)) {
333                    SimpleSOAPEventType eventType = (SimpleSOAPEventType) event.getType();
334                    String methodName = eventType.getCalledMethod();
335                    if( prefixToRemove!=null && methodName.startsWith(prefixToRemove) ) {
336                        methodName = methodName.substring(prefixToRemove.length(), methodName.length());
337                        // remove prefix
338                    }
339                    if( suffixToRemove!=null && methodName.endsWith(suffixToRemove) ) {
340                        methodName = methodName.substring(0, methodName.length()-suffixToRemove.length());
341                    }
342                    event = new Event(new SimpleSOAPEventType(methodName, eventType.getServiceName(), eventType.getClientName(), eventType.getSoapRequestBody(), eventType.getEqualSOAPDataMap()), event.getTarget());
343                }
344                normalizedSequence.add(event);
345            }
346            normalizedSequences.add(normalizedSequence);
347        }
348        return normalizedSequences;
349    }
350
351    /**
352     * <p>
353     * prevent instantiation
354     * </p>
355     */
356    private SOAPUtils() {}
357}
Note: See TracBrowser for help on using the repository browser.