1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.rest;
14
15 import java.beans.PropertyChangeEvent;
16 import java.net.MalformedURLException;
17 import java.net.URL;
18 import java.util.ArrayList;
19 import java.util.List;
20 import java.util.Map;
21
22 import javax.xml.namespace.QName;
23
24 import org.apache.xmlbeans.SchemaGlobalElement;
25 import org.apache.xmlbeans.SchemaType;
26 import org.apache.xmlbeans.XmlException;
27 import org.apache.xmlbeans.XmlString;
28
29 import com.eviware.soapui.config.AttachmentConfig;
30 import com.eviware.soapui.config.RestRequestConfig;
31 import com.eviware.soapui.config.StringToStringMapConfig;
32 import com.eviware.soapui.impl.rest.RestRepresentation.Type;
33 import com.eviware.soapui.impl.rest.support.RestParamProperty;
34 import com.eviware.soapui.impl.rest.support.RestParamsPropertyHolder;
35 import com.eviware.soapui.impl.rest.support.RestRequestParamsPropertyHolder;
36 import com.eviware.soapui.impl.support.AbstractHttpRequest;
37 import com.eviware.soapui.impl.wsdl.HttpAttachmentPart;
38 import com.eviware.soapui.impl.wsdl.WsdlSubmit;
39 import com.eviware.soapui.impl.wsdl.submit.RequestTransportRegistry;
40 import com.eviware.soapui.impl.wsdl.submit.transports.http.HttpResponse;
41 import com.eviware.soapui.impl.wsdl.submit.transports.jms.JMSHeader;
42 import com.eviware.soapui.impl.wsdl.support.PathUtils;
43 import com.eviware.soapui.impl.wsdl.support.jms.header.JMSHeaderConfig;
44 import com.eviware.soapui.impl.wsdl.support.jms.property.JMSPropertiesConfig;
45 import com.eviware.soapui.model.ModelItem;
46 import com.eviware.soapui.model.iface.MessagePart;
47 import com.eviware.soapui.model.iface.SubmitContext;
48 import com.eviware.soapui.model.iface.MessagePart.ContentPart;
49 import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
50 import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
51 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
52 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionsResult;
53 import com.eviware.soapui.model.testsuite.TestProperty;
54 import com.eviware.soapui.model.testsuite.TestPropertyListener;
55 import com.eviware.soapui.support.StringUtils;
56 import com.eviware.soapui.support.UISupport;
57 import com.eviware.soapui.support.types.StringList;
58 import com.eviware.soapui.support.types.StringToStringMap;
59
60 /***
61 * Request implementation holding a SOAP request
62 *
63 * @author Ole.Matzura
64 */
65
66 public class RestRequest extends AbstractHttpRequest<RestRequestConfig> implements RestRequestInterface
67 {
68 private RestMethod method;
69 private RestParamsPropertyHolder params;
70 private ParamUpdater paramUpdater;
71
72 public RestRequest( RestMethod method, RestRequestConfig requestConfig, boolean forLoadTest )
73 {
74 super( requestConfig, method.getOperation(), "/rest_request.gif", false );
75 this.method = method;
76
77 if( requestConfig.getParameters() == null )
78 requestConfig.addNewParameters();
79
80 StringToStringMap paramValues = StringToStringMap.fromXml( requestConfig.getParameters() );
81 params = new RestRequestParamsPropertyHolder( method.getOverlayParams(), this, paramValues );
82 paramUpdater = new ParamUpdater( paramValues );
83 params.addTestPropertyListener( paramUpdater );
84
85 if( method != null )
86 method.addPropertyChangeListener( this );
87 }
88
89 public ModelItem getParent()
90 {
91 return getRestMethod();
92 }
93
94 public RestMethod getRestMethod()
95 {
96 return method;
97 }
98
99 protected RequestIconAnimator<?> initIconAnimator()
100 {
101 return new RequestIconAnimator<AbstractHttpRequest<?>>( this, "/rest_request.gif", "/exec_rest_request", 4, "gif" );
102 }
103
104 public MessagePart[] getRequestParts()
105 {
106 List<MessagePart> result = new ArrayList<MessagePart>();
107
108 for( int c = 0; c < getPropertyCount(); c++ )
109 {
110 result.add( new ParameterMessagePart( getPropertyAt( c ) ) );
111 }
112
113 if( getMethod() == RestRequestInterface.RequestMethod.POST
114 || getMethod() == RestRequestInterface.RequestMethod.PUT )
115 {
116 result.add( new RestContentPart() );
117 }
118
119 return result.toArray( new MessagePart[result.size()] );
120 }
121
122 public RestRepresentation[] getRepresentations()
123 {
124 return getRepresentations( null, null );
125 }
126
127 public RestRepresentation[] getRepresentations( RestRepresentation.Type type )
128 {
129 return getRepresentations( type, null );
130 }
131
132 public RestRepresentation[] getRepresentations( RestRepresentation.Type type, String mediaType )
133 {
134 return getRestMethod().getRepresentations( type, mediaType );
135 }
136
137 public MessagePart[] getResponseParts()
138 {
139 return new MessagePart[0];
140 }
141
142 public RestRequestInterface.RequestMethod getMethod()
143 {
144 return getRestMethod().getMethod();
145 }
146
147 public String getAccept()
148 {
149 String accept = getConfig().getAccept();
150 return accept == null ? "" : accept;
151 }
152
153 public void setAccept( String acceptEncoding )
154 {
155 String old = getAccept();
156 getConfig().setAccept( acceptEncoding );
157 notifyPropertyChanged( "accept", old, acceptEncoding );
158 }
159
160 public void setMediaType( String mediaType )
161 {
162 String old = getMediaType();
163 getConfig().setMediaType( mediaType );
164 notifyPropertyChanged( "mediaType", old, mediaType );
165 }
166
167 public String getMediaType()
168 {
169 if( getConfig().getMediaType() == null )
170 {
171 String mediaType = getRestMethod().getDefaultRequestMediaType();
172 getConfig().setMediaType( mediaType );
173 notifyPropertyChanged( "mediaType", null, mediaType );
174 }
175 return getConfig().getMediaType();
176 }
177
178 public void setMethod( RequestMethod method )
179 {
180 getRestMethod().setMethod( method );
181 }
182
183 public WsdlSubmit<RestRequest> submit( SubmitContext submitContext, boolean async ) throws SubmitException
184 {
185 String endpoint = PropertyExpander.expandProperties( submitContext, getEndpoint() );
186
187 if( StringUtils.isNullOrEmpty( endpoint ) )
188 {
189 try
190 {
191 endpoint = new URL( getPath() ).toString();
192 }
193 catch( MalformedURLException e )
194 {
195 }
196 }
197
198 if( StringUtils.isNullOrEmpty( endpoint ) )
199 {
200 UISupport.showErrorMessage( "Missing endpoint for request [" + getName() + "]" );
201 return null;
202 }
203
204 try
205 {
206 WsdlSubmit<RestRequest> submitter = new WsdlSubmit<RestRequest>( this, getSubmitListeners(),
207 RequestTransportRegistry.getTransport( endpoint, submitContext ) );
208 submitter.submitRequest( submitContext, async );
209 return submitter;
210 }
211 catch( Exception e )
212 {
213 throw new SubmitException( e.toString() );
214 }
215 }
216
217 public PropertyExpansion[] getPropertyExpansions()
218 {
219 PropertyExpansionsResult result = new PropertyExpansionsResult( this, this );
220 result.addAll( super.getPropertyExpansions() );
221 result.addAll( getRestMethod().getPropertyExpansions() );
222 addJMSHeaderExpansions( result, getJMSHeaderConfig(), this );
223
224 return result.toArray();
225 }
226
227 public void addJMSHeaderExpansions( PropertyExpansionsResult result, JMSHeaderConfig jmsHeaderConfig,
228 ModelItem modelItem )
229 {
230 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, jmsHeaderConfig,
231 JMSHeader.JMSCORRELATIONID ) );
232 result.addAll( PropertyExpansionUtils
233 .extractPropertyExpansions( modelItem, jmsHeaderConfig, JMSHeader.JMSREPLYTO ) );
234 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, jmsHeaderConfig, JMSHeader.JMSTYPE ) );
235 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, jmsHeaderConfig,
236 JMSHeader.JMSPRIORITY ) );
237 result.addAll( PropertyExpansionUtils
238 .extractPropertyExpansions( modelItem, jmsHeaderConfig, JMSHeader.TIMETOLIVE ) );
239 result.addAll( PropertyExpansionUtils
240 .extractPropertyExpansions( modelItem, jmsHeaderConfig, JMSHeader.DURABLE_SUBSCRIPTION_NAME ) );
241 result.addAll( PropertyExpansionUtils
242 .extractPropertyExpansions( modelItem, jmsHeaderConfig, JMSHeader.CLIENT_ID ) );
243 }
244
245 public TestProperty addProperty( String name )
246 {
247 return params.addProperty( name );
248 }
249
250 public void moveProperty( String propertyName, int targetIndex )
251 {
252 params.moveProperty( propertyName, targetIndex );
253 }
254
255 public TestProperty removeProperty( String propertyName )
256 {
257 return params.removeProperty( propertyName );
258 }
259
260 public boolean renameProperty( String name, String newName )
261 {
262 return params.renameProperty( name, newName );
263 }
264
265 public void addTestPropertyListener( TestPropertyListener listener )
266 {
267 params.addTestPropertyListener( listener );
268 }
269
270 public ModelItem getModelItem()
271 {
272 return this;
273 }
274
275 @Override
276 public RestResource getOperation()
277 {
278 return ( RestResource )method.getOperation();
279 }
280
281 public Map<String, TestProperty> getProperties()
282 {
283 return params.getProperties();
284 }
285
286 public RestParamProperty getProperty( String name )
287 {
288 return params.getProperty( name );
289 }
290
291 public RestParamProperty getPropertyAt( int index )
292 {
293 return params.getPropertyAt( index );
294 }
295
296 public int getPropertyCount()
297 {
298 return params.getPropertyCount();
299 }
300
301 public String[] getPropertyNames()
302 {
303 return params.getPropertyNames();
304 }
305
306 public String getPropertyValue( String name )
307 {
308 return params.getPropertyValue( name );
309 }
310
311 public boolean hasProperty( String name )
312 {
313 return params.hasProperty( name );
314 }
315
316 public void removeTestPropertyListener( TestPropertyListener listener )
317 {
318 params.removeTestPropertyListener( listener );
319 }
320
321 public void setPropertyValue( String name, String value )
322 {
323 params.setPropertyValue( name, value );
324 }
325
326 public void resetPropertyValues()
327 {
328 params.clear();
329 for( String name : params.getPropertyNames() )
330 {
331 params.getProperty( name ).setValue( params.getProperty( name ).getDefaultValue() );
332 }
333 }
334
335 public void propertyChange( PropertyChangeEvent evt )
336 {
337 if( evt.getPropertyName().equals( "path" ) )
338 {
339 notifyPropertyChanged( "path", null, getPath() );
340 }
341 else if( evt.getPropertyName().equals( "method" ) )
342 {
343 notifyPropertyChanged( "method", evt.getOldValue(), evt.getNewValue() );
344 }
345 }
346
347 public String[] getResponseMediaTypes()
348 {
349 StringList result = new StringList();
350
351 for( RestRepresentation representation : getRepresentations( Type.RESPONSE, null ) )
352 {
353 if( !result.contains( representation.getMediaType() ) )
354 result.add( representation.getMediaType() );
355 }
356
357 return result.toStringArray();
358 }
359
360 public boolean isPostQueryString()
361 {
362 return hasRequestBody() && getConfig().getPostQueryString();
363 }
364
365 public void setPostQueryString( boolean b )
366 {
367 boolean old = isPostQueryString();
368 getConfig().setPostQueryString( b );
369 notifyPropertyChanged( "postQueryString", old, b );
370
371 if( !"multipart/form-data".equals( getMediaType() ) )
372 {
373 setMediaType( b ? "application/x-www-form-urlencoded" : getMediaType() );
374 }
375 }
376
377 public final static class ParameterMessagePart extends MessagePart.ParameterPart
378 {
379 private String name;
380
381 public ParameterMessagePart( TestProperty propertyAt )
382 {
383 this.name = propertyAt.getName();
384 }
385
386 @Override
387 public SchemaType getSchemaType()
388 {
389 return XmlString.type;
390 }
391
392 @Override
393 public SchemaGlobalElement getPartElement()
394 {
395 return null;
396 }
397
398 @Override
399 public QName getPartElementName()
400 {
401 return new QName( getName() );
402 }
403
404 public String getDescription()
405 {
406 return null;
407 }
408
409 public String getName()
410 {
411 return name;
412 }
413 }
414
415 public String getPropertiesLabel()
416 {
417 return "Request Params";
418 }
419
420 public RestParamsPropertyHolder getParams()
421 {
422 return params;
423 }
424
425 public HttpAttachmentPart getAttachmentPart( String partName )
426 {
427 return null;
428 }
429
430 public HttpAttachmentPart[] getDefinedAttachmentParts()
431 {
432 return new HttpAttachmentPart[0];
433 }
434
435 public class RestContentPart extends ContentPart implements MessagePart
436 {
437 @Override
438 public SchemaGlobalElement getPartElement()
439 {
440 return null;
441 }
442
443 @Override
444 public QName getPartElementName()
445 {
446 return null;
447 }
448
449 @Override
450 public SchemaType getSchemaType()
451 {
452 return null;
453 }
454
455 public String getDescription()
456 {
457 return null;
458 }
459
460 public String getName()
461 {
462 return null;
463 }
464
465 public String getMediaType()
466 {
467 return getConfig().getMediaType();
468 }
469 }
470
471 public boolean hasRequestBody()
472 {
473 return getRestMethod().hasRequestBody();
474 }
475
476 public RestResource getResource()
477 {
478 return getOperation();
479 }
480
481 public String getPath()
482 {
483 if( !StringUtils.isNullOrEmpty( getConfig().getFullPath() ) || getResource() == null )
484 return getConfig().getFullPath();
485 else
486 return getResource().getFullPath();
487 }
488
489 public void setPath( String fullPath )
490 {
491 String old = getPath();
492
493 if( getResource() != null && getResource().getFullPath().equals( fullPath ) )
494 getConfig().unsetFullPath();
495 else
496 getConfig().setFullPath( fullPath );
497
498 notifyPropertyChanged( "path", old, fullPath );
499 }
500
501 public String getResponseContentAsXml()
502 {
503 HttpResponse response = getResponse();
504 if( response == null )
505 return null;
506
507 return response.getContentAsXml();
508 }
509
510 @Override
511 public void release()
512 {
513 super.release();
514
515 if( getResource() != null )
516 getResource().removePropertyChangeListener( this );
517
518 }
519
520 public void updateConfig( RestRequestConfig request )
521 {
522 setConfig( request );
523
524 updateParams();
525
526 List<AttachmentConfig> attachmentConfigs = getConfig().getAttachmentList();
527 for( int i = 0; i < attachmentConfigs.size(); i++ )
528 {
529 AttachmentConfig config = attachmentConfigs.get( i );
530 getAttachmentsList().get( i ).updateConfig( config );
531 }
532 }
533
534 protected void updateParams()
535 {
536 StringToStringMap paramValues = StringToStringMap.fromXml( getConfig().getParameters() );
537 ( ( RestRequestParamsPropertyHolder )params ).reset( getRestMethod().getOverlayParams(), paramValues );
538 paramUpdater.setValues( paramValues );
539 }
540
541 public boolean hasEndpoint()
542 {
543 return super.hasEndpoint() || PathUtils.isHttpPath( getPath() );
544 }
545
546 private class ParamUpdater implements TestPropertyListener
547 {
548 private StringToStringMap values;
549
550 public ParamUpdater( StringToStringMap paramValues )
551 {
552 values = paramValues;
553 }
554
555 public void setValues( StringToStringMap paramValues )
556 {
557 values = paramValues;
558 }
559
560 private void sync()
561 {
562 try
563 {
564 getConfig().setParameters( StringToStringMapConfig.Factory.parse( values.toXml() ) );
565 }
566 catch( XmlException e )
567 {
568 e.printStackTrace();
569 }
570 }
571
572 public void propertyAdded( String name )
573 {
574 sync();
575 }
576
577 public void propertyMoved( String name, int oldIndex, int newIndex )
578 {
579 sync();
580 }
581
582 public void propertyRemoved( String name )
583 {
584 sync();
585 }
586
587 public void propertyRenamed( String oldName, String newName )
588 {
589 sync();
590 }
591
592 public void propertyValueChanged( String name, String oldValue, String newValue )
593 {
594 sync();
595 }
596 }
597
598 public List<TestProperty> getPropertyList()
599 {
600 return params.getPropertyList();
601 }
602
603 protected void setRestMethod( RestMethod restMethod )
604 {
605 if( this.method != null )
606 this.method.removePropertyChangeListener( this );
607
608 this.method = restMethod;
609
610 if( method != null )
611 method.addPropertyChangeListener( this );
612
613 updateParams();
614 }
615
616 private JMSHeaderConfig jmsHeaderConfig;
617 private JMSPropertiesConfig jmsPropertyConfig;
618
619 public JMSHeaderConfig getJMSHeaderConfig()
620 {
621 if( jmsHeaderConfig == null )
622 {
623 if( !getConfig().isSetJmsConfig() )
624 {
625 getConfig().addNewJmsConfig();
626 }
627 jmsHeaderConfig = new JMSHeaderConfig( getConfig().getJmsConfig(), this );
628 }
629 return jmsHeaderConfig;
630 }
631
632 public JMSPropertiesConfig getJMSPropertiesConfig()
633 {
634 if( jmsPropertyConfig == null )
635 {
636 if( !getConfig().isSetJmsPropertyConfig() )
637 {
638 getConfig().addNewJmsPropertyConfig();
639 }
640 jmsPropertyConfig = new JMSPropertiesConfig( getConfig().getJmsPropertyConfig(), this );
641 }
642 return jmsPropertyConfig;
643 }
644 }