1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.rest.support;
14
15 import java.io.File;
16 import java.io.FileOutputStream;
17 import java.io.IOException;
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.LinkedHashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.apache.log4j.Logger;
25 import org.apache.xmlbeans.XmlException;
26 import org.apache.xmlbeans.XmlObject;
27
28 import com.eviware.soapui.SoapUI;
29 import com.eviware.soapui.config.AttachmentConfig;
30 import com.eviware.soapui.config.CompressedStringConfig;
31 import com.eviware.soapui.config.CredentialsConfig;
32 import com.eviware.soapui.config.HttpRequestConfig;
33 import com.eviware.soapui.config.OldRestRequestConfig;
34 import com.eviware.soapui.config.RestParameterConfig;
35 import com.eviware.soapui.config.RestParametersConfig;
36 import com.eviware.soapui.config.RestRequestConfig;
37 import com.eviware.soapui.config.RestRequestStepConfig;
38 import com.eviware.soapui.config.RestResourceRepresentationConfig;
39 import com.eviware.soapui.config.SettingsConfig;
40 import com.eviware.soapui.config.StringToStringMapConfig;
41 import com.eviware.soapui.config.TestAssertionConfig;
42 import com.eviware.soapui.config.StringToStringMapConfig.Entry;
43 import com.eviware.soapui.impl.rest.RestMethod;
44 import com.eviware.soapui.impl.rest.RestRepresentation;
45 import com.eviware.soapui.impl.rest.RestRequest;
46 import com.eviware.soapui.impl.rest.RestResource;
47 import com.eviware.soapui.impl.rest.RestService;
48 import com.eviware.soapui.impl.rest.RestRequestInterface.RequestMethod;
49 import com.eviware.soapui.impl.wsdl.WsdlProject;
50 import com.eviware.soapui.impl.wsdl.teststeps.RestTestRequestStep;
51 import com.eviware.soapui.model.iface.Interface;
52 import com.eviware.soapui.model.project.Project;
53 import com.eviware.soapui.model.testsuite.TestProperty;
54 import com.eviware.soapui.support.StringUtils;
55 import com.eviware.soapui.support.UISupport;
56
57 /***
58 * Convert old-style REST Requests to new ones, creating REST Methods for them
59 * or placing them into existing Methods.
60 *
61 * @author Dain Nilsson
62 */
63 public class RestRequestConverter
64 {
65
66 private static Map<Project, Boolean> autoConvert = new HashMap<Project, Boolean>();
67 private final static Logger log = Logger.getLogger( RestRequestConverter.class );
68
69 public static void convert( RestResource resource, OldRestRequestConfig oldConfig )
70 {
71 convert( resource, oldConfig, getMethod( resource, oldConfig.getMethod(), oldConfig.getName() ) );
72 }
73
74 public static RestMethod getMethod( RestResource resource, String methodType, String requestName )
75 {
76 WsdlProject project = resource.getService().getProject();
77 if( !autoConvert.containsKey( project ) )
78 {
79 autoConvert
80 .put(
81 project,
82 UISupport
83 .confirm(
84 "The model for REST requests has changed slightly,\r\n"
85 + "introducing a new REST Method item in-between each REST Resource and Request.\r\n"
86 + "Any existing REST Request must now be placed under either an existing Method or a new one, "
87 + "either automatically or manually.\r\n\r\nWould You like soapUI to do this automatically using the default values?",
88 "Update REST model for project: " + project.getName() ) );
89 }
90 RestMethod method = null;
91 List<String> options = new ArrayList<String>();
92 for( int c = 0; c < resource.getRestMethodCount(); c++ )
93 {
94 RestMethod restMethod = resource.getRestMethodAt( c );
95 if( restMethod.getMethod().toString().equals( methodType ) )
96 options.add( restMethod.getName() );
97 }
98 if( autoConvert.get( project ) )
99 {
100 if( options.size() > 0 )
101 {
102 method = resource.getRestMethodByName( options.get( 0 ) );
103 log.info( "Placed request '" + requestName + "' under method '" + method.getName() + "' in Resource '"
104 + resource.getName() + "'." );
105 }
106 else
107 {
108 method = resource.addNewMethod( methodType + " Method" );
109 method.setMethod( RequestMethod.valueOf( methodType ) );
110 log.info( "Created new Method for Resource '" + resource.getName() + "'." );
111 }
112 }
113 else
114 {
115 options.add( "[Create new REST Method]" );
116 if( requestName == null )
117 requestName = "REST Request";
118 String message = "Select REST Method to place \"" + resource.getName() + " > " + requestName + "\" under.";
119 Object op = UISupport.prompt( message, "Migrate REST Request", options.toArray() );
120 if( op != null )
121 {
122 int ix = options.indexOf( op );
123 if( ix != -1 && ix != options.size() - 1 )
124 {
125 method = resource.getRestMethodByName( ( String )op );
126 }
127 }
128 else
129 throw new RestConversionException( "Cannot get RestMethod selection!" );
130 if( method == null )
131 {
132 String name = UISupport.prompt( "Name for REST " + methodType + " Method", "Create new REST Method",
133 methodType + " Method" );
134 if( name == null )
135 throw new RestConversionException( "Cannot get name for RestMethod!" );
136 method = resource.addNewMethod( name );
137 method.setMethod( RequestMethod.valueOf( methodType ) );
138 }
139 }
140 return method;
141 }
142
143 public static RestResource resolveResource( RestTestRequestStep requestStep )
144 {
145 Map<String, RestResource> options = new LinkedHashMap<String, RestResource>();
146
147 WsdlProject project = requestStep.getTestCase().getTestSuite().getProject();
148 String serviceName = requestStep.getRequestStepConfig().getService();
149 RestService service = ( RestService )project.getInterfaceByName( serviceName );
150 if( service != null )
151 {
152 addResources( service, options );
153 }
154 else
155 {
156 for( Interface iface : project.getInterfaceList() )
157 {
158 if( iface instanceof RestService )
159 {
160 addResources( ( RestService )iface, options );
161 }
162 }
163 }
164 options.put( "<Delete TestRequest>", null );
165
166 String message = "Select a new REST Resource to place TestRequest \"" + requestStep.getName() + "\" under.";
167 Object op = UISupport.prompt( message, "Missing REST Resource for TestRequest", options.keySet().toArray() );
168 RestResource resource = options.get( op );
169
170 return resource;
171 }
172
173 private static void addResources( RestService service, Map<String, RestResource> list )
174 {
175 for( RestResource resource : service.getResources().values() )
176 {
177 list.put( service.getName() + " > " + resource.getName(), resource );
178 }
179 }
180
181 @SuppressWarnings( "deprecation" )
182 private static void convert( RestResource resource, OldRestRequestConfig oldConfig, RestMethod method )
183 {
184
185 RestRequest request = method.addNewRequest( oldConfig.getName() );
186
187 XmlBeansRestParamsTestPropertyHolder params = new XmlBeansRestParamsTestPropertyHolder( null, oldConfig
188 .getParameters() );
189 RestParamsPropertyHolder parentParams = method.getOverlayParams();
190
191 for( TestProperty prop : params.values() )
192 {
193 if( !parentParams.containsKey( prop.getName() ) )
194 {
195 method.getParams().addParameter( ( RestParamProperty )prop );
196 }
197 request.setPropertyValue( prop.getName(), prop.getValue() );
198 }
199 params.release();
200
201 boolean exists;
202 for( RestResourceRepresentationConfig rep : oldConfig.getRepresentationList() )
203 {
204 exists = false;
205 for( RestRepresentation existing : method.getRepresentations( RestRepresentation.Type.valueOf( rep.getType()
206 .toString() ), rep.getMediaType() ) )
207 {
208 if( existing.getElement() == null && rep.getElement() == null
209 || existing.getElement().equals( rep.getElement() ) )
210 {
211 exists = true;
212 break;
213 }
214 }
215 if( !exists )
216 {
217 RestRepresentation repr = method.addNewRepresentation( RestRepresentation.Type.valueOf( rep.getType()
218 .toString() ) );
219 repr.setConfig( ( RestResourceRepresentationConfig )rep.copy() );
220 }
221 }
222
223 RestRequestConfig newConfig = request.getConfig();
224
225 newConfig.setRequest( oldConfig.getRequest() );
226
227 for( AttachmentConfig ac : oldConfig.getAttachmentList() )
228 try
229 {
230 if( ac.isSetData() )
231 {
232 File temp = File.createTempFile( "pattern", ".suffix" );
233 temp.deleteOnExit();
234 FileOutputStream out = new FileOutputStream( temp ) ;
235 out.write( ac.getData() );
236 request.attachFile( temp, true );
237 }
238 else
239 {
240 request.attachFile( new File( ac.getUrl() ), false );
241 }
242 }
243 catch( IOException e )
244 {
245 e.printStackTrace();
246 }
247 newConfig.setAttachmentArray( oldConfig.getAttachmentArray() );
248
249 if( oldConfig.isSetFullPath() )
250 newConfig.setFullPath( oldConfig.getFullPath() );
251 if( oldConfig.isSetMediaType() )
252 newConfig.setMediaType( oldConfig.getMediaType() );
253 if( oldConfig.isSetPostQueryString() )
254 newConfig.setPostQueryString( oldConfig.getPostQueryString() );
255 if( oldConfig.isSetAccept() )
256 newConfig.setAccept( oldConfig.getAccept() );
257 if( oldConfig.isSetDescription() )
258 newConfig.setDescription( oldConfig.getDescription() );
259 if( oldConfig.isSetId() )
260 newConfig.setId( oldConfig.getId() );
261 if( oldConfig.isSetSettings() )
262 newConfig.setSettings( ( SettingsConfig )oldConfig.getSettings().copy() );
263 if( oldConfig.isSetSslKeystore() )
264 newConfig.setSslKeystore( oldConfig.getSslKeystore() );
265 if( oldConfig.isSetTimestamp() )
266 newConfig.setTimestamp( oldConfig.getTimestamp() );
267 if( oldConfig.isSetWadlId() )
268 newConfig.setWadlId( oldConfig.getWadlId() );
269
270 request.updateConfig( newConfig );
271
272 }
273
274 public static HttpRequestConfig convert( OldRestRequestConfig old )
275 {
276 HttpRequestConfig config = HttpRequestConfig.Factory.newInstance();
277 config.setAssertionArray( old.getAssertionList().toArray( new TestAssertionConfig[old.sizeOfAssertionArray()] ) );
278 config.setAttachmentArray( old.getAttachmentList().toArray( new AttachmentConfig[old.sizeOfAttachmentArray()] ) );
279 XmlObject obj = old.getCredentials();
280 if( obj != null )
281 config.setCredentials( ( CredentialsConfig )obj.copy() );
282 obj = old.getParameters();
283 if( obj != null )
284 config.setParameters( ( RestParametersConfig )obj.copy() );
285
286 obj = old.getRequest();
287 if( obj != null )
288 config.setRequest( ( CompressedStringConfig )obj.copy() );
289 obj = old.getSettings();
290 if( obj != null )
291 config.setSettings( ( SettingsConfig )obj.copy() );
292 if( old.isSetDescription() )
293 config.setDescription( old.getDescription() );
294 config.setEncoding( old.getEncoding() );
295 config.setEndpoint( old.getEndpoint() );
296 config.setSslKeystore( old.getSslKeystore() );
297 if( old.isSetMediaType() )
298 config.setMediaType( old.getMediaType() );
299 if( old.isSetMethod() )
300 config.setMethod( old.getMethod() );
301 if( old.isSetName() )
302 config.setName( old.getName() );
303 if( old.isSetPostQueryString() )
304 config.setPostQueryString( old.getPostQueryString() );
305 return config;
306 }
307
308 public static HttpRequestConfig updateIfNeeded( XmlObject config )
309 {
310 try
311 {
312 if( config instanceof RestRequestStepConfig )
313 {
314 return convert( OldRestRequestConfig.Factory.parse( config.selectChildren( "http://eviware.com/soapui/config",
315 "restRequest" )[0].toString() ) );
316 }
317 else
318 {
319 return ( HttpRequestConfig )config.changeType( HttpRequestConfig.type );
320 }
321 }
322 catch( XmlException e )
323 {
324 return HttpRequestConfig.Factory.newInstance();
325 }
326 }
327
328 public static class RestConversionException extends RuntimeException
329 {
330 public RestConversionException( String message )
331 {
332 super( message );
333 }
334 }
335
336 public static void updateRestTestRequest( RestTestRequestStep restTestRequestStep )
337 {
338 try
339 {
340 RestRequestStepConfig restRequestStepConfig = ( RestRequestStepConfig )restTestRequestStep.getConfig()
341 .getConfig();
342 RestRequestConfig restRequestConfig = restRequestStepConfig.getRestRequest();
343 OldRestRequestConfig oldConfig = OldRestRequestConfig.Factory.parse( restRequestConfig.toString() );
344
345 RestParametersConfig oldParams = oldConfig.getParameters();
346 if( oldParams != null )
347 {
348 StringToStringMapConfig newParams = restRequestConfig.addNewParameters();
349
350 for( RestParameterConfig oldParam : oldParams.getParameterList() )
351 {
352 if( StringUtils.hasContent( oldParam.getValue() ) )
353 {
354 Entry entry = newParams.addNewEntry();
355 entry.setKey( oldParam.getName() );
356 entry.setValue( oldParam.getValue() );
357 }
358 }
359
360 restRequestConfig.getParameters().getDomNode().getParentNode().removeChild(
361 restRequestConfig.getParameters().getDomNode() );
362 }
363 }
364 catch( XmlException e )
365 {
366 SoapUI.logError( e );
367 }
368 }
369 }