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