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          iface.removePropertyChangeListener( AbstractInterface.ENDPOINT_PROPERTY, propertyChangeListener );
320    }
321 
322    private class InternalProjectListener extends ProjectListenerAdapter
323    {
324       @Override
325       public void interfaceAdded( Interface iface )
326       {
327          for( String endpoint : iface.getEndpoints() )
328          {
329             // ensure we have defaults
330             getEndpointDefaults( endpoint );
331          }
332 
333          iface.addPropertyChangeListener( AbstractInterface.ENDPOINT_PROPERTY, propertyChangeListener );
334       }
335 
336       @Override
337       public void interfaceRemoved( Interface iface )
338       {
339          iface.removePropertyChangeListener( AbstractInterface.ENDPOINT_PROPERTY, propertyChangeListener );
340          removeUnusedEndpoints();
341       }
342    }
343 
344    private class InternalPropertyChangeListener implements PropertyChangeListener
345    {
346       public void propertyChange( PropertyChangeEvent evt )
347       {
348          // new endpoint?
349          String newValue = evt.getNewValue() == null ? null : evt.getNewValue().toString();
350          if( evt.getOldValue() == null )
351          {
352             getEndpointDefaults( newValue );
353          }
354          // changed endpoint?
355          else if( newValue != null )
356          {
357             String oldValue = evt.getOldValue().toString();
358             EndpointDefaults def = defaults.containsKey( newValue ) ? defaults.get( newValue ) : getEndpointDefaults( oldValue );
359             def.endpointConfig.setStringValue( newValue );
360             defaults.remove( oldValue );
361             defaults.put( newValue, def );
362          }
363          else
364          {
365             removeUnusedEndpoints();
366          }
367       }
368    }
369 
370    public class EndpointDefaults implements PropertyExpansionContainer
371    {
372       private final EndpointConfig endpointConfig;
373 
374       public EndpointDefaults( EndpointConfig endpointConfig )
375       {
376          this.endpointConfig = endpointConfig;
377 
378          if( !endpointConfig.isSetMode() )
379             endpointConfig.setMode( EndpointConfig.Mode.COMPLEMENT );
380       }
381 
382       public String getDomain()
383       {
384          return endpointConfig.getDomain();
385       }
386 
387       public String getPassword()
388       {
389          return endpointConfig.getPassword();
390       }
391 
392       public String getUsername()
393       {
394          return endpointConfig.getUsername();
395       }
396 
397       public String getWssTimeToLive()
398       {
399          return endpointConfig.getWssTimeToLive();
400       }
401 
402       public String getWssType()
403       {
404          String wssPasswordType = endpointConfig.getWssType();
405          return StringUtils.isNullOrEmpty( wssPasswordType ) || WsdlRequest.PW_TYPE_NONE.equals( wssPasswordType ) ? null : wssPasswordType;
406       }
407 
408       public void setDomain( String arg0 )
409       {
410          endpointConfig.setDomain( arg0 );
411       }
412 
413       public void setPassword( String arg0 )
414       {
415          endpointConfig.setPassword( arg0 );
416       }
417 
418       public void setUsername( String arg0 )
419       {
420          endpointConfig.setUsername( arg0 );
421       }
422 
423       public void setWssTimeToLive( String arg0 )
424       {
425          endpointConfig.setWssTimeToLive( arg0 );
426       }
427 
428       public String getIncomingWss()
429       {
430          return endpointConfig.getIncomingWss();
431       }
432 
433       public String getOutgoingWss()
434       {
435          return endpointConfig.getOutgoingWss();
436       }
437 
438       public void setIncomingWss( String arg0 )
439       {
440          endpointConfig.setIncomingWss( arg0 );
441       }
442 
443       public void setOutgoingWss( String arg0 )
444       {
445          endpointConfig.setOutgoingWss( arg0 );
446       }
447 
448       public void setWssType( String wssPasswordType )
449       {
450          if( wssPasswordType == null || wssPasswordType.equals( WsdlRequest.PW_TYPE_NONE ) )
451          {
452             if( endpointConfig.isSetWssType() )
453                endpointConfig.unsetWssType();
454          }
455          else
456          {
457             endpointConfig.setWssType( wssPasswordType );
458          }
459       }
460 
461       public EndpointConfig.Mode.Enum getMode()
462       {
463          return endpointConfig.getMode();
464       }
465 
466       public void setMode( EndpointConfig.Mode.Enum mode )
467       {
468          endpointConfig.setMode( mode );
469       }
470 
471       protected EndpointConfig getConfig()
472       {
473          return endpointConfig;
474       }
475 
476       public PropertyExpansion[] getPropertyExpansions()
477       {
478          PropertyExpansionsResult result = new PropertyExpansionsResult( project, this );
479 
480          result.extractAndAddAll( "username" );
481          result.extractAndAddAll( "password" );
482          result.extractAndAddAll( "domain" );
483 
484          return result.toArray();
485       }
486    }
487 
488    public EndpointDefaults getEndpointDefaults( String endpoint )
489    {
490       if( config == null )
491          initConfig();
492 
493       if( !defaults.containsKey( endpoint ) )
494       {
495          EndpointConfig newEndpoint = config.addNewEndpoint();
496          newEndpoint.setStringValue( endpoint );
497          defaults.put( endpoint, new EndpointDefaults( newEndpoint ) );
498       }
499 
500       return defaults.get( endpoint );
501    }
502 
503    public void onSave()
504    {
505       if( config == null )
506          return;
507 
508       removeUnusedEndpoints();
509 
510       // remove unused
511       for( int c = 0; c < config.sizeOfEndpointArray(); c++ )
512       {
513          EndpointConfig ec = config.getEndpointArray( c );
514          if( StringUtils.isNullOrEmpty( ec.getDomain() ) && StringUtils.isNullOrEmpty( ec.getUsername() )
515                  && StringUtils.isNullOrEmpty( ec.getPassword() ) && StringUtils.isNullOrEmpty( ec.getWssType() )
516                  && StringUtils.isNullOrEmpty( ec.getWssTimeToLive() ) && StringUtils.isNullOrEmpty( ec.getIncomingWss() )
517                  && StringUtils.isNullOrEmpty( ec.getOutgoingWss() ) )
518          {
519             defaults.remove( ec.getStringValue() );
520             config.removeEndpoint( c );
521             c--;
522          }
523       }
524 
525       if( config.sizeOfEndpointArray() == 0 )
526       {
527          project.getConfig().unsetEndpointStrategy();
528          config = null;
529       }
530    }
531 
532    public void importEndpoints( Interface iface )
533    {
534       EndpointStrategy ep = iface.getProject().getEndpointStrategy();
535       if( ep instanceof DefaultEndpointStrategy )
536       {
537          DefaultEndpointStrategy dep = (DefaultEndpointStrategy) ep;
538          String[] endpoints = iface.getEndpoints();
539 
540          for( String endpoint : endpoints )
541          {
542             getEndpointDefaults( endpoint ).getConfig().set( dep.getEndpointDefaults( endpoint ).getConfig() );
543          }
544       }
545    }
546 
547    public JComponent getConfigurationPanel( Interface iface )
548    {
549       return new DefaultEndpointStrategyConfigurationPanel( iface, this );
550    }
551 
552    public void afterRequest( SubmitContext context, Response response )
553    {
554    }
555 
556    public PropertyExpansion[] getPropertyExpansions()
557    {
558       PropertyExpansionsResult result = new PropertyExpansionsResult( project, this );
559 
560       for( EndpointDefaults ed : defaults.values() )
561       {
562          result.addAll( ed.getPropertyExpansions() );
563       }
564 
565       return result.toArray();
566    }
567 
568    public void changeEndpoint( String oldEndpoint, String newEndpoint )
569    {
570       EndpointDefaults endpointDefaults = defaults.remove( oldEndpoint );
571       if( endpointDefaults != null )
572       {
573          endpointDefaults.getConfig().setStringValue( newEndpoint );
574          defaults.put( newEndpoint, endpointDefaults );
575       }
576    }
577 
578    public void afterRequest( SubmitContext context, Request request )
579    {
580    }
581 }