View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.impl.wsdl.endpoint;
14  
15  import com.eviware.soapui.SoapUI;
16  import com.eviware.soapui.config.DefaultEndpointStrategyConfig;
17  import com.eviware.soapui.config.EndpointConfig;
18  import com.eviware.soapui.config.ProjectConfig;
19  import com.eviware.soapui.impl.support.AbstractHttpRequest;
20  import com.eviware.soapui.impl.support.AbstractInterface;
21  import com.eviware.soapui.impl.wsdl.WsdlProject;
22  import com.eviware.soapui.impl.wsdl.WsdlRequest;
23  import com.eviware.soapui.impl.wsdl.submit.filters.HttpAuthenticationRequestFilter;
24  import com.eviware.soapui.impl.wsdl.submit.filters.WssAuthenticationRequestFilter;
25  import com.eviware.soapui.impl.wsdl.submit.transports.http.BaseHttpRequestTransport;
26  import com.eviware.soapui.model.iface.Interface;
27  import com.eviware.soapui.model.iface.Request;
28  import com.eviware.soapui.model.iface.Response;
29  import com.eviware.soapui.model.iface.SubmitContext;
30  import com.eviware.soapui.model.project.EndpointStrategy;
31  import com.eviware.soapui.model.project.Project;
32  import com.eviware.soapui.model.project.ProjectListener;
33  import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
34  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContainer;
35  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
36  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionsResult;
37  import com.eviware.soapui.model.support.ProjectListenerAdapter;
38  import com.eviware.soapui.support.StringUtils;
39  import com.eviware.soapui.support.types.StringList;
40  import org.apache.commons.httpclient.HttpMethod;
41  import org.apache.commons.httpclient.URI;
42  import org.apache.commons.httpclient.URIException;
43  
44  import javax.swing.*;
45  import java.beans.PropertyChangeEvent;
46  import java.beans.PropertyChangeListener;
47  import java.util.*;
48  
49  public class DefaultEndpointStrategy implements EndpointStrategy, PropertyExpansionContainer
50  {
51     private WsdlProject project;
52     private DefaultEndpointStrategyConfig config;
53     private Map<String, EndpointDefaults> defaults = new HashMap<String, EndpointDefaults>();
54     private PropertyChangeListener propertyChangeListener = new InternalPropertyChangeListener();
55     private ProjectListener projectListener = new InternalProjectListener();
56  
57     public void init( Project project )
58     {
59        this.project = (WsdlProject) project;
60        initConfig();
61  
62        project.addProjectListener( projectListener );
63  
64        for( Interface iface : project.getInterfaceList() )
65        {
66           for( String endpoint : iface.getEndpoints() )
67           {
68              // ensure we have defaults
69              getEndpointDefaults( endpoint );
70           }
71  
72           iface.addPropertyChangeListener( AbstractInterface.ENDPOINT_PROPERTY, propertyChangeListener );
73        }
74  
75        removeUnusedEndpoints();
76     }
77  
78     private void initConfig()
79     {
80        ProjectConfig projectConfig = this.project.getConfig();
81  
82        if( !projectConfig.isSetEndpointStrategy() )
83        {
84           projectConfig.addNewEndpointStrategy();
85        }
86  
87        config = (DefaultEndpointStrategyConfig) projectConfig.getEndpointStrategy().changeType(
88                DefaultEndpointStrategyConfig.type );
89  
90        for( EndpointConfig endpointConfig : config.getEndpointList() )
91        {
92           defaults.put( endpointConfig.getStringValue(), new EndpointDefaults( endpointConfig ) );
93        }
94     }
95  
96     private void removeUnusedEndpoints()
97     {
98        if( config == null )
99           return;
100 
101       Set<String> endpoints = new HashSet<String>();
102 
103       for( Interface iface : project.getInterfaceList() )
104       {
105          endpoints.addAll( Arrays.asList( iface.getEndpoints() ) );
106       }
107 
108       StringList keys = new StringList();
109 
110       for( String key : defaults.keySet() )
111       {
112          if( !endpoints.contains( key ) )
113          {
114             keys.add( key );
115          }
116       }
117 
118       for( String key : keys )
119       {
120          EndpointDefaults def = defaults.remove( key );
121          config.getEndpointList().remove( def );
122       }
123    }
124 
125    public void filterRequest( SubmitContext context, Request wsdlRequest )
126    {
127       HttpMethod httpMethod = (HttpMethod) context.getProperty( BaseHttpRequestTransport.HTTP_METHOD );
128       URI uri = null;
129       try
130       {
131          uri = httpMethod.getURI();
132       }
133       catch( URIException e )
134       {
135          SoapUI.logError( e );
136          return;
137       }
138 
139       EndpointDefaults def = defaults.get( uri.toString() );
140 
141       if( def == null )
142       {
143          for( String ep : defaults.keySet() )
144          {
145             if( PropertyExpansionUtils.expandProperties( context, ep ).equals( uri.toString() ) )
146             {
147                def = defaults.get( ep );
148                break;
149             }
150          }
151 
152          if( def == null )
153             return;
154       }
155 
156       applyDefaultsToWsdlRequest( context, (AbstractHttpRequest) wsdlRequest, def );
157    }
158 
159    protected void applyDefaultsToWsdlRequest( SubmitContext context, AbstractHttpRequest wsdlRequest, EndpointDefaults def )
160    {
161       String requestUsername = PropertyExpansionUtils.expandProperties( context, wsdlRequest.getUsername() );
162       String requestPassword = PropertyExpansionUtils.expandProperties( context, wsdlRequest.getPassword() );
163       String requestDomain = PropertyExpansionUtils.expandProperties( context, wsdlRequest.getDomain() );
164 
165       String defUsername = PropertyExpansionUtils.expandProperties( context, def.getUsername() );
166       String defPassword = PropertyExpansionUtils.expandProperties( context, def.getPassword() );
167       String defDomain = PropertyExpansionUtils.expandProperties( context, def.getDomain() );
168 
169       if( def.getMode() == EndpointConfig.Mode.OVERRIDE )
170       {
171          overrideRequest( context, wsdlRequest, def, requestUsername, requestPassword, requestDomain, defUsername,
172                  defPassword, defDomain );
173       }
174       else if( def.getMode() == EndpointConfig.Mode.COPY )
175       {
176          copyToRequest( context, wsdlRequest, def, requestUsername, requestPassword, requestDomain, defUsername,
177                  defPassword, defDomain );
178       }
179       else if( def.getMode() == EndpointConfig.Mode.COMPLEMENT )
180       {
181          complementRequest( context, wsdlRequest, def, requestUsername, requestPassword, requestDomain, defUsername,
182                  defPassword, defDomain );
183       }
184    }
185 
186    private void overrideRequest(
187            SubmitContext context, AbstractHttpRequest wsdlRequest, EndpointDefaults def,
188            String requestUsername, String requestPassword, String requestDomain, String defUsername,
189            String defPassword, String defDomain
190    )
191    {
192       String username = StringUtils.hasContent( defUsername ) ? defUsername : requestUsername;
193       String password = StringUtils.hasContent( defPassword ) ? defPassword : requestPassword;
194 
195       if( StringUtils.hasContent( username ) || StringUtils.hasContent( password ) )
196       {
197          // only set if not set in request
198          String wssType = def.getWssType();
199          String wssTimeToLive = def.getWssTimeToLive();
200 
201          if( wssType == null )
202          {
203             String domain = StringUtils.hasContent( defDomain ) ? defDomain : requestDomain;
204             HttpAuthenticationRequestFilter.initRequestCredentials( context, username, project.getSettings(), password,
205                     domain );
206          }
207 
208          if( StringUtils.hasContent( wssType ) || StringUtils.hasContent( wssTimeToLive ) )
209          {
210             try
211             {
212                // set to null so existing don't get removed
213                if( wssTimeToLive != null && wssTimeToLive.length() == 0 )
214                   wssTimeToLive = null;
215 
216                WssAuthenticationRequestFilter
217                        .setWssHeaders( context, username, password, wssType, wssTimeToLive );
218             }
219             catch( Exception e )
220             {
221                SoapUI.logError( e );
222             }
223          }
224       }
225    }
226 
227    private void copyToRequest(
228            SubmitContext context, AbstractHttpRequest wsdlRequest, EndpointDefaults def,
229            String requestUsername, String requestPassword, String requestDomain, String defUsername,
230            String defPassword, String defDomain
231    )
232    {
233       // only set if not set in request
234       String wssType = def.getWssType();
235 
236       if( wssType != null )
237       {
238          HttpAuthenticationRequestFilter.initRequestCredentials( context, null, project.getSettings(), null, null );
239       }
240       else
241       {
242          HttpAuthenticationRequestFilter.initRequestCredentials( context, defUsername, project.getSettings(), defPassword,
243                  defDomain );
244       }
245 
246       String wssTimeToLive = def.getWssTimeToLive();
247       if( wssTimeToLive == null )
248          wssTimeToLive = "";
249 
250       try
251       {
252          WssAuthenticationRequestFilter.setWssHeaders( context, defUsername, defPassword, wssType, wssTimeToLive );
253       }
254       catch( Exception e )
255       {
256          SoapUI.logError( e );
257       }
258    }
259 
260    private void complementRequest(
261            SubmitContext context, AbstractHttpRequest httpRequest, EndpointDefaults def,
262            String requestUsername, String requestPassword, String requestDomain, String defUsername,
263            String defPassword, String defDomain
264    )
265    {
266       String username = StringUtils.hasContent( requestUsername ) ? requestUsername : defUsername;
267       String password = StringUtils.hasContent( requestPassword ) ? requestPassword : defPassword;
268 
269       if( httpRequest instanceof WsdlRequest )
270       {
271          WsdlRequest wsdlRequest = (WsdlRequest) httpRequest;
272          // only set if not set in request
273          String wssType = StringUtils.isNullOrEmpty( wsdlRequest.getWssPasswordType() ) ? def.getWssType() : ( StringUtils
274                  .hasContent( username ) && StringUtils.hasContent( password ) ) ? null : wsdlRequest
275                  .getWssPasswordType();
276 
277          String wssTimeToLive = StringUtils.isNullOrEmpty( wsdlRequest.getWssTimeToLive() ) ? def.getWssTimeToLive()
278                  : null;
279 
280          if( !StringUtils.hasContent( wssType ) && ( StringUtils.hasContent( username ) || StringUtils.hasContent( password ) ) )
281          {
282             String domain = StringUtils.hasContent( requestDomain ) ? requestDomain : defDomain;
283             HttpAuthenticationRequestFilter.initRequestCredentials( context, username, project.getSettings(), password,
284                     domain );
285          }
286          else if( StringUtils.hasContent( wssType ) || StringUtils.hasContent( wssTimeToLive ) )
287          {
288             try
289             {
290                // set to null so existing don't get removed
291                if( wssTimeToLive != null && wssTimeToLive.length() == 0 )
292                   wssTimeToLive = null;
293 
294                if( StringUtils.hasContent( username ) || StringUtils.hasContent( password ) )
295                   WssAuthenticationRequestFilter
296                           .setWssHeaders( context, username, password, wssType, wssTimeToLive );
297             }
298             catch( Exception e )
299             {
300                SoapUI.logError( e );
301             }
302          }
303       }
304       else
305       {
306          if( ( StringUtils.hasContent( username ) || StringUtils.hasContent( password ) ) )
307          {
308             String domain = StringUtils.hasContent( requestDomain ) ? requestDomain : defDomain;
309             HttpAuthenticationRequestFilter.initRequestCredentials( context, username, project.getSettings(), password,
310                     domain );
311          }
312       }
313    }
314 
315    public void release()
316    {
317       project.removeProjectListener( projectListener );
318       for( Interface iface : project.getInterfaceList() )
319       {
320          iface.removePropertyChangeListener( AbstractInterface.ENDPOINT_PROPERTY, propertyChangeListener );
321       }
322    }
323 
324    private class InternalProjectListener extends ProjectListenerAdapter
325    {
326       @Override
327       public void interfaceAdded( Interface iface )
328       {
329          for( String endpoint : iface.getEndpoints() )
330          {
331             // ensure we have defaults
332             getEndpointDefaults( endpoint );
333          }
334 
335          iface.addPropertyChangeListener( AbstractInterface.ENDPOINT_PROPERTY, propertyChangeListener );
336       }
337 
338       @Override
339       public void interfaceRemoved( Interface iface )
340       {
341          iface.removePropertyChangeListener( AbstractInterface.ENDPOINT_PROPERTY, propertyChangeListener );
342          removeUnusedEndpoints();
343       }
344    }
345 
346    private class InternalPropertyChangeListener implements PropertyChangeListener
347    {
348       public void propertyChange( PropertyChangeEvent evt )
349       {
350          // new endpoint?
351          String newValue = evt.getNewValue() == null ? null : evt.getNewValue().toString();
352          if( evt.getOldValue() == null )
353          {
354             getEndpointDefaults( newValue );
355          }
356          // changed endpoint?
357          else if( newValue != null )
358          {
359             String oldValue = evt.getOldValue().toString();
360             EndpointDefaults def = defaults.containsKey( newValue ) ? defaults.get( newValue ) : getEndpointDefaults( oldValue );
361             def.endpointConfig.setStringValue( newValue );
362             defaults.remove( oldValue );
363             defaults.put( newValue, def );
364          }
365          else
366          {
367             removeUnusedEndpoints();
368          }
369       }
370    }
371 
372    public class EndpointDefaults implements PropertyExpansionContainer
373    {
374       private final EndpointConfig endpointConfig;
375 
376       public EndpointDefaults( EndpointConfig endpointConfig )
377       {
378          this.endpointConfig = endpointConfig;
379 
380          if( !endpointConfig.isSetMode() )
381             endpointConfig.setMode( EndpointConfig.Mode.COMPLEMENT );
382       }
383 
384       public String getDomain()
385       {
386          return endpointConfig.getDomain();
387       }
388 
389       public String getPassword()
390       {
391          return endpointConfig.getPassword();
392       }
393 
394       public String getUsername()
395       {
396          return endpointConfig.getUsername();
397       }
398 
399       public String getWssTimeToLive()
400       {
401          return endpointConfig.getWssTimeToLive();
402       }
403 
404       public String getWssType()
405       {
406          String wssPasswordType = endpointConfig.getWssType();
407          return StringUtils.isNullOrEmpty( wssPasswordType ) || WsdlRequest.PW_TYPE_NONE.equals( wssPasswordType ) ? null : wssPasswordType;
408       }
409 
410       public void setDomain( String arg0 )
411       {
412          endpointConfig.setDomain( arg0 );
413       }
414 
415       public void setPassword( String arg0 )
416       {
417          endpointConfig.setPassword( arg0 );
418       }
419 
420       public void setUsername( String arg0 )
421       {
422          endpointConfig.setUsername( arg0 );
423       }
424 
425       public void setWssTimeToLive( String arg0 )
426       {
427          endpointConfig.setWssTimeToLive( arg0 );
428       }
429 
430       public String getIncomingWss()
431       {
432          return endpointConfig.getIncomingWss();
433       }
434 
435       public String getOutgoingWss()
436       {
437          return endpointConfig.getOutgoingWss();
438       }
439 
440       public void setIncomingWss( String arg0 )
441       {
442          endpointConfig.setIncomingWss( arg0 );
443       }
444 
445       public void setOutgoingWss( String arg0 )
446       {
447          endpointConfig.setOutgoingWss( arg0 );
448       }
449 
450       public void setWssType( String wssPasswordType )
451       {
452          if( wssPasswordType == null || wssPasswordType.equals( WsdlRequest.PW_TYPE_NONE ) )
453          {
454             if( endpointConfig.isSetWssType() )
455                endpointConfig.unsetWssType();
456          }
457          else
458          {
459             endpointConfig.setWssType( wssPasswordType );
460          }
461       }
462 
463       public EndpointConfig.Mode.Enum getMode()
464       {
465          return endpointConfig.getMode();
466       }
467 
468       public void setMode( EndpointConfig.Mode.Enum mode )
469       {
470          endpointConfig.setMode( mode );
471       }
472 
473       protected EndpointConfig getConfig()
474       {
475          return endpointConfig;
476       }
477 
478       public PropertyExpansion[] getPropertyExpansions()
479       {
480          PropertyExpansionsResult result = new PropertyExpansionsResult( project, this );
481 
482          result.extractAndAddAll( "username" );
483          result.extractAndAddAll( "password" );
484          result.extractAndAddAll( "domain" );
485 
486          return result.toArray();
487       }
488    }
489 
490    public EndpointDefaults getEndpointDefaults( String endpoint )
491    {
492       if( config == null )
493          initConfig();
494 
495       if( !defaults.containsKey( endpoint ) )
496       {
497          EndpointConfig newEndpoint = config.addNewEndpoint();
498          newEndpoint.setStringValue( endpoint );
499          defaults.put( endpoint, new EndpointDefaults( newEndpoint ) );
500       }
501 
502       return defaults.get( endpoint );
503    }
504 
505    public void onSave()
506    {
507       if( config == null )
508          return;
509 
510       removeUnusedEndpoints();
511 
512       // remove unused
513       for( int c = 0; c < config.sizeOfEndpointArray(); c++ )
514       {
515          EndpointConfig ec = config.getEndpointArray( c );
516          if( StringUtils.isNullOrEmpty( ec.getDomain() ) && StringUtils.isNullOrEmpty( ec.getUsername() )
517                  && StringUtils.isNullOrEmpty( ec.getPassword() ) && StringUtils.isNullOrEmpty( ec.getWssType() )
518                  && StringUtils.isNullOrEmpty( ec.getWssTimeToLive() ) && StringUtils.isNullOrEmpty( ec.getIncomingWss() )
519                  && StringUtils.isNullOrEmpty( ec.getOutgoingWss() ) )
520          {
521             defaults.remove( ec.getStringValue() );
522             config.removeEndpoint( c );
523             c--;
524          }
525       }
526 
527       if( config.sizeOfEndpointArray() == 0 )
528       {
529          project.getConfig().unsetEndpointStrategy();
530          config = null;
531       }
532    }
533 
534    public void importEndpoints( Interface iface )
535    {
536       EndpointStrategy ep = iface.getProject().getEndpointStrategy();
537       if( ep instanceof DefaultEndpointStrategy )
538       {
539          DefaultEndpointStrategy dep = (DefaultEndpointStrategy) ep;
540          String[] endpoints = iface.getEndpoints();
541 
542          for( String endpoint : endpoints )
543          {
544             getEndpointDefaults( endpoint ).getConfig().set( dep.getEndpointDefaults( endpoint ).getConfig() );
545          }
546       }
547    }
548 
549    public JComponent getConfigurationPanel( Interface iface )
550    {
551       return new DefaultEndpointStrategyConfigurationPanel( iface, this );
552    }
553 
554    public void afterRequest( SubmitContext context, Response response )
555    {
556    }
557 
558    public PropertyExpansion[] getPropertyExpansions()
559    {
560       PropertyExpansionsResult result = new PropertyExpansionsResult( project, this );
561 
562       for( EndpointDefaults ed : defaults.values() )
563       {
564          result.addAll( ed.getPropertyExpansions() );
565       }
566 
567       return result.toArray();
568    }
569 
570    public void changeEndpoint( String oldEndpoint, String newEndpoint )
571    {
572       EndpointDefaults endpointDefaults = defaults.remove( oldEndpoint );
573       if( endpointDefaults != null )
574       {
575          endpointDefaults.getConfig().setStringValue( newEndpoint );
576          defaults.put( newEndpoint, endpointDefaults );
577       }
578    }
579 
580    public void afterRequest( SubmitContext context, Request request )
581    {
582    }
583 }