1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.mock;
14
15 import java.util.Collections;
16 import java.util.LinkedList;
17 import java.util.List;
18
19 import javax.servlet.http.HttpServletRequest;
20 import javax.servlet.http.HttpServletResponse;
21 import javax.wsdl.BindingOperation;
22 import javax.wsdl.Part;
23 import javax.xml.namespace.QName;
24
25 import org.apache.xmlbeans.XmlObject;
26 import org.mortbay.jetty.Request;
27 import org.w3c.dom.Element;
28 import org.w3c.dom.Node;
29 import org.w3c.dom.NodeList;
30
31 import com.eviware.soapui.SoapUI;
32 import com.eviware.soapui.impl.wsdl.WsdlOperation;
33 import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
34 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
35 import com.eviware.soapui.model.mock.MockResult;
36 import com.eviware.soapui.model.mock.MockRunListener;
37 import com.eviware.soapui.model.mock.MockRunner;
38 import com.eviware.soapui.support.xml.XmlUtils;
39
40 public class WsdlMockRunner implements MockRunner
41 {
42 private final WsdlMockService mockService;
43 private List<WsdlMockResult> mockResults = Collections.synchronizedList( new LinkedList<WsdlMockResult>());
44 private int maxResults = 100;
45 private int removed = 0;
46 private WsdlMockRunContext mockContext;
47
48 public WsdlMockRunner( WsdlMockService mockService, WsdlTestRunContext context ) throws Exception
49 {
50 this.mockService = mockService;
51
52 mockContext = new WsdlMockRunContext( mockService, context );
53
54 SoapUI.getMockEngine().startMockService( this );
55
56 MockRunListener[] mockRunListeners = mockService.getMockRunListeners();
57
58 for( MockRunListener listener : mockRunListeners )
59 {
60 listener.onMockRunnerStart( this );
61 }
62 }
63
64 public WsdlMockRunContext getMockContext()
65 {
66 return mockContext;
67 }
68
69 public void addMockResult( WsdlMockResult mockResult )
70 {
71 mockResults.add( mockResult );
72 if( mockResults.size() > maxResults )
73 {
74 mockResults.remove( 0 );
75 removed++;
76 }
77 }
78
79 public void stop()
80 {
81 SoapUI.getMockEngine().stopMockService( this );
82
83 MockRunListener[] mockRunListeners = mockService.getMockRunListeners();
84
85 for( MockRunListener listener : mockRunListeners )
86 {
87 listener.onMockRunnerStop( this );
88 }
89 }
90
91 public WsdlMockService getMockService()
92 {
93 return mockService;
94 }
95
96 public WsdlMockResult dispatchRequest( HttpServletRequest request, HttpServletResponse response ) throws DispatchException
97 {
98 WsdlMockResult result = null;
99 MockRunListener[] mockRunListeners = mockService.getMockRunListeners();
100
101 try
102 {
103 for( MockRunListener listener : mockRunListeners )
104 {
105 listener.onMockRequest( this, request, response );
106 }
107
108 long timestamp = System.currentTimeMillis();
109 String soapAction = request.getHeader( "SOAPAction" );
110
111 WsdlMockRequest mockRequest = new WsdlMockRequest( request, response, mockContext );
112
113 SoapVersion soapVersion = mockRequest.getSoapVersion();
114 if( soapVersion == null )
115 throw new DispatchException( "Unrecognized SOAP Version" );
116
117 XmlObject contentElm = mockRequest.getContentElement();
118 if( contentElm == null )
119 throw new DispatchException( "Missing content element in body" );
120
121 QName contentQName = XmlUtils.getQName( contentElm.getDomNode() );
122 NodeList contentChildNodes = null;
123
124 for( int c = 0; c < mockService.getMockOperationCount(); c++ )
125 {
126 WsdlMockOperation mockOperation = ( WsdlMockOperation ) mockService.getMockOperationAt( c );
127 WsdlOperation wsdlOperation = ( WsdlOperation ) mockOperation.getOperation();
128 if( wsdlOperation == null )
129 continue;
130
131 if( mockService.isRequireSoapVersion() &&
132 wsdlOperation.getInterface().getSoapVersion() != mockRequest.getSoapVersion() )
133 {
134 continue;
135 }
136
137 String action = wsdlOperation.getAction() == null ? "\"\"" : "\"" + wsdlOperation.getAction() + "\"";
138
139
140 if( (soapAction == null && wsdlOperation.getAction() == null ) ||
141 (action.equals( soapAction ) || (wsdlOperation.getAction() != null && wsdlOperation.getAction().equals( soapAction ) )))
142 {
143 QName qname = wsdlOperation.getRequestBodyElementQName();
144
145 if( !qname.equals( contentQName ))
146 continue;
147
148 long startTime = 0;
149
150
151 if( wsdlOperation.getStyle().equals( WsdlOperation.STYLE_DOCUMENT ))
152 {
153
154 startTime = System.nanoTime();
155 result = mockOperation.dispatchRequest( mockRequest, response );
156 }
157 else if( wsdlOperation.getStyle().equals( WsdlOperation.STYLE_RPC ))
158 {
159 BindingOperation bindingOperation = wsdlOperation.getBindingOperation();
160 List<Part> parts = bindingOperation.getOperation().getInput().getMessage().getOrderedParts( null );
161
162 if( contentChildNodes == null )
163 contentChildNodes = XmlUtils.getChildElements( ( Element ) contentElm.getDomNode() );
164
165 int i = 0;
166
167 if( parts.size() > 0 )
168 {
169 for( ; i < contentChildNodes.getLength() && !parts.isEmpty(); i++ )
170 {
171 Node item = contentChildNodes.item( i );
172 if( item.getNodeType() != Node.ELEMENT_NODE )
173 continue;
174
175 int j=0;
176 while ((j<parts.size()) && (!item.getNodeName().equals( parts.get( j ).getName())))
177 {
178 j++;
179 }
180
181 if (j==parts.size())
182 break;
183
184 parts.remove( j );
185 }
186 }
187
188
189 if( i == contentChildNodes.getLength() && parts.isEmpty() )
190 {
191 startTime = System.nanoTime();
192 result = mockOperation.dispatchRequest( mockRequest, response );
193 }
194 }
195
196 if( startTime == 0 )
197 {
198 throw new DispatchException( "Failed to find matching operation for request" );
199 }
200 else
201 {
202 ((Request)request).setHandled( true );
203 result.setTimeTaken( ( System.nanoTime() - startTime ) / 1000000 );
204 result.setTimestamp( timestamp );
205 addMockResult( result );
206 return result;
207 }
208 }
209 }
210
211 throw new DispatchException( "Missing operation for soapAction [" + soapAction + "] and body element [" +
212 contentQName + "] with SOAP Version [" + mockRequest.getSoapVersion() + "]" );
213 }
214 catch( Exception e )
215 {
216 e.printStackTrace();
217
218 if( e instanceof DispatchException )
219 throw (DispatchException)e;
220
221 throw new DispatchException( e );
222 }
223 finally
224 {
225 if( result != null )
226 {
227 for( MockRunListener listener : mockRunListeners )
228 {
229 listener.onMockResult( result );
230 }
231 }
232 }
233 }
234
235 public MockResult getMockResultAt( int index )
236 {
237 return index <= removed ? null : mockResults.get( index-removed );
238 }
239
240 public int getMockResultCount()
241 {
242 return mockResults.size() + removed;
243 }
244 }