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 RestRequestParamsPropertyHolder 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.extractPropertyExpansions( modelItem, jmsHeaderConfig,
240 JMSHeader.DURABLE_SUBSCRIPTION_NAME ) );
241 result
242 .addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, jmsHeaderConfig, JMSHeader.CLIENT_ID ) );
243 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, jmsHeaderConfig,
244 JMSHeader.SEND_AS_BYTESMESSAGE ) );
245 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( modelItem, jmsHeaderConfig,
246 JMSHeader.SOAP_ACTION_ADD ) );
247
248 }
249
250 public TestProperty addProperty( String name )
251 {
252 return params.addProperty( name );
253 }
254
255 public void moveProperty( String propertyName, int targetIndex )
256 {
257 params.moveProperty( propertyName, targetIndex );
258 }
259
260 public TestProperty removeProperty( String propertyName )
261 {
262 return params.removeProperty( propertyName );
263 }
264
265 public boolean renameProperty( String name, String newName )
266 {
267 return params.renameProperty( name, newName );
268 }
269
270 public void addTestPropertyListener( TestPropertyListener listener )
271 {
272 params.addTestPropertyListener( listener );
273 }
274
275 public ModelItem getModelItem()
276 {
277 return this;
278 }
279
280 @Override
281 public RestResource getOperation()
282 {
283 return ( RestResource )method.getOperation();
284 }
285
286 public Map<String, TestProperty> getProperties()
287 {
288 return params.getProperties();
289 }
290
291 public RestParamProperty getProperty( String name )
292 {
293 return params.getProperty( name );
294 }
295
296 public RestParamProperty getPropertyAt( int index )
297 {
298 return params.getPropertyAt( index );
299 }
300
301 public int getPropertyCount()
302 {
303 return params.getPropertyCount();
304 }
305
306 public String[] getPropertyNames()
307 {
308 return params.getPropertyNames();
309 }
310
311 public String getPropertyValue( String name )
312 {
313 return params.getPropertyValue( name );
314 }
315
316 public boolean hasProperty( String name )
317 {
318 return params.hasProperty( name );
319 }
320
321 public void removeTestPropertyListener( TestPropertyListener listener )
322 {
323 params.removeTestPropertyListener( listener );
324 }
325
326 public void setPropertyValue( String name, String value )
327 {
328 params.setPropertyValue( name, value );
329 }
330
331 public void resetPropertyValues()
332 {
333 params.clear();
334 for( String name : params.getPropertyNames() )
335 {
336 params.getProperty( name ).setValue( params.getProperty( name ).getDefaultValue() );
337 }
338 }
339
340 public void propertyChange( PropertyChangeEvent evt )
341 {
342 if( evt.getPropertyName().equals( "path" ) )
343 {
344 notifyPropertyChanged( "path", null, getPath() );
345 }
346 else if( evt.getPropertyName().equals( "method" ) )
347 {
348 notifyPropertyChanged( "method", evt.getOldValue(), evt.getNewValue() );
349 }
350 }
351
352 public String[] getResponseMediaTypes()
353 {
354 StringList result = new StringList();
355
356 for( RestRepresentation representation : getRepresentations( Type.RESPONSE, null ) )
357 {
358 if( !result.contains( representation.getMediaType() ) )
359 result.add( representation.getMediaType() );
360 }
361
362 return result.toStringArray();
363 }
364
365 public boolean isPostQueryString()
366 {
367 return hasRequestBody() && getConfig().getPostQueryString();
368 }
369
370 public void setPostQueryString( boolean b )
371 {
372 boolean old = isPostQueryString();
373 getConfig().setPostQueryString( b );
374 notifyPropertyChanged( "postQueryString", old, b );
375
376 if( !"multipart/form-data".equals( getMediaType() ) )
377 {
378 setMediaType( b ? "application/x-www-form-urlencoded" : getMediaType() );
379 }
380 }
381
382 public final static class ParameterMessagePart extends MessagePart.ParameterPart
383 {
384 private String name;
385
386 public ParameterMessagePart( TestProperty propertyAt )
387 {
388 this.name = propertyAt.getName();
389 }
390
391 @Override
392 public SchemaType getSchemaType()
393 {
394 return XmlString.type;
395 }
396
397 @Override
398 public SchemaGlobalElement getPartElement()
399 {
400 return null;
401 }
402
403 @Override
404 public QName getPartElementName()
405 {
406 return new QName( getName() );
407 }
408
409 public String getDescription()
410 {
411 return null;
412 }
413
414 public String getName()
415 {
416 return name;
417 }
418 }
419
420 public String getPropertiesLabel()
421 {
422 return "Request Params";
423 }
424
425 public RestParamsPropertyHolder getParams()
426 {
427 return params;
428 }
429
430 public HttpAttachmentPart getAttachmentPart( String partName )
431 {
432 return null;
433 }
434
435 public HttpAttachmentPart[] getDefinedAttachmentParts()
436 {
437 return new HttpAttachmentPart[0];
438 }
439
440 public class RestContentPart extends ContentPart implements MessagePart
441 {
442 @Override
443 public SchemaGlobalElement getPartElement()
444 {
445 return null;
446 }
447
448 @Override
449 public QName getPartElementName()
450 {
451 return null;
452 }
453
454 @Override
455 public SchemaType getSchemaType()
456 {
457 return null;
458 }
459
460 public String getDescription()
461 {
462 return null;
463 }
464
465 public String getName()
466 {
467 return null;
468 }
469
470 public String getMediaType()
471 {
472 return getConfig().getMediaType();
473 }
474 }
475
476 public boolean hasRequestBody()
477 {
478 return getRestMethod().hasRequestBody();
479 }
480
481 public RestResource getResource()
482 {
483 return getOperation();
484 }
485
486 public String getPath()
487 {
488 if( !StringUtils.isNullOrEmpty( getConfig().getFullPath() ) || getResource() == null )
489 return getConfig().getFullPath();
490 else
491 return getResource().getFullPath();
492 }
493
494 public void setPath( String fullPath )
495 {
496 String old = getPath();
497
498 if( getResource() != null && getResource().getFullPath().equals( fullPath ) )
499 getConfig().unsetFullPath();
500 else
501 getConfig().setFullPath( fullPath );
502
503 notifyPropertyChanged( "path", old, fullPath );
504 }
505
506 public String getResponseContentAsXml()
507 {
508 HttpResponse response = getResponse();
509 if( response == null )
510 return null;
511
512 return response.getContentAsXml();
513 }
514
515 @Override
516 public void release()
517 {
518 super.release();
519
520 if( method != null )
521 method.removePropertyChangeListener( this );
522
523 params.removeTestPropertyListener( paramUpdater );
524 params.release();
525 }
526
527 public void updateConfig( RestRequestConfig request )
528 {
529 setConfig( request );
530
531 updateParams();
532
533 List<AttachmentConfig> attachmentConfigs = getConfig().getAttachmentList();
534 for( int i = 0; i < attachmentConfigs.size(); i++ )
535 {
536 AttachmentConfig config = attachmentConfigs.get( i );
537 getAttachmentsList().get( i ).updateConfig( config );
538 }
539
540 if( jmsHeaderConfig != null )
541 {
542 jmsHeaderConfig.setJMSHeaderConfConfig( request.getJmsConfig() );
543 }
544
545 if( jmsPropertyConfig != null )
546 {
547 jmsPropertyConfig.setJmsPropertyConfConfig( request.getJmsPropertyConfig() );
548 }
549 }
550
551 protected void updateParams()
552 {
553 StringToStringMap paramValues = StringToStringMap.fromXml( getConfig().getParameters() );
554 params.reset( getRestMethod().getOverlayParams(), paramValues );
555 paramUpdater.setValues( paramValues );
556 }
557
558 public boolean hasEndpoint()
559 {
560 return super.hasEndpoint() || PathUtils.isHttpPath( getPath() );
561 }
562
563 private class ParamUpdater implements TestPropertyListener
564 {
565 private StringToStringMap values;
566
567 public ParamUpdater( StringToStringMap paramValues )
568 {
569 values = paramValues;
570 }
571
572 public void setValues( StringToStringMap paramValues )
573 {
574 values = paramValues;
575 }
576
577 private void sync()
578 {
579 try
580 {
581 getConfig().setParameters( StringToStringMapConfig.Factory.parse( values.toXml() ) );
582 }
583 catch( XmlException e )
584 {
585 e.printStackTrace();
586 }
587 }
588
589 public void propertyAdded( String name )
590 {
591 sync();
592 }
593
594 public void propertyMoved( String name, int oldIndex, int newIndex )
595 {
596 sync();
597 }
598
599 public void propertyRemoved( String name )
600 {
601 sync();
602 }
603
604 public void propertyRenamed( String oldName, String newName )
605 {
606 sync();
607 }
608
609 public void propertyValueChanged( String name, String oldValue, String newValue )
610 {
611 sync();
612 }
613 }
614
615 public List<TestProperty> getPropertyList()
616 {
617 return params.getPropertyList();
618 }
619
620 protected void setRestMethod( RestMethod restMethod )
621 {
622 if( this.method != null )
623 this.method.removePropertyChangeListener( this );
624
625 this.method = restMethod;
626
627 if( method != null )
628 method.addPropertyChangeListener( this );
629
630 updateParams();
631 }
632
633 private JMSHeaderConfig jmsHeaderConfig;
634 private JMSPropertiesConfig jmsPropertyConfig;
635
636 public JMSHeaderConfig getJMSHeaderConfig()
637 {
638 if( jmsHeaderConfig == null )
639 {
640 if( !getConfig().isSetJmsConfig() )
641 {
642 getConfig().addNewJmsConfig();
643 }
644 jmsHeaderConfig = new JMSHeaderConfig( getConfig().getJmsConfig(), this );
645 }
646 return jmsHeaderConfig;
647 }
648
649 public JMSPropertiesConfig getJMSPropertiesConfig()
650 {
651 if( jmsPropertyConfig == null )
652 {
653 if( !getConfig().isSetJmsPropertyConfig() )
654 {
655 getConfig().addNewJmsPropertyConfig();
656 }
657 jmsPropertyConfig = new JMSPropertiesConfig( getConfig().getJmsPropertyConfig(), this );
658 }
659 return jmsPropertyConfig;
660 }
661
662 }