View Javadoc

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