View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 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.panels.request.actions;
14  
15  import java.awt.Dimension;
16  import java.io.File;
17  import java.io.IOException;
18  import java.net.MalformedURLException;
19  import java.net.URL;
20  import java.util.Calendar;
21  
22  import javax.swing.SwingUtilities;
23  
24  import org.wsI.testing.x2003.x03.common.AddStyleSheet;
25  import org.wsI.testing.x2003.x03.log.Environment;
26  import org.wsI.testing.x2003.x03.log.HttpMessageEntry;
27  import org.wsI.testing.x2003.x03.log.Implementation;
28  import org.wsI.testing.x2003.x03.log.Log;
29  import org.wsI.testing.x2003.x03.log.LogDocument;
30  import org.wsI.testing.x2003.x03.log.MessageEntry;
31  import org.wsI.testing.x2003.x03.log.Monitor;
32  import org.wsI.testing.x2003.x03.log.NameVersionPair;
33  import org.wsI.testing.x2003.x03.log.TcpMessageType;
34  import org.wsI.testing.x2004.x07.analyzerConfig.AssertionResults;
35  import org.wsI.testing.x2004.x07.analyzerConfig.Configuration;
36  import org.wsI.testing.x2004.x07.analyzerConfig.ConfigurationDocument;
37  import org.wsI.testing.x2004.x07.analyzerConfig.LogFile;
38  import org.wsI.testing.x2004.x07.analyzerConfig.ReportFile;
39  import org.wsI.testing.x2004.x07.analyzerConfig.LogFile.CorrelationType;
40  
41  import com.eviware.soapui.SoapUI;
42  import com.eviware.soapui.impl.wsdl.WsdlRequest;
43  import com.eviware.soapui.impl.wsdl.actions.iface.tools.support.AbstractToolsAction;
44  import com.eviware.soapui.impl.wsdl.actions.iface.tools.support.ArgumentBuilder;
45  import com.eviware.soapui.impl.wsdl.actions.iface.tools.support.ProcessToolRunner;
46  import com.eviware.soapui.impl.wsdl.actions.iface.tools.support.RunnerContext;
47  import com.eviware.soapui.impl.wsdl.actions.iface.tools.support.ToolHost;
48  import com.eviware.soapui.impl.wsdl.actions.iface.tools.wsi.WSIAnalyzeAction;
49  import com.eviware.soapui.impl.wsdl.actions.iface.tools.wsi.WSIReportPanel;
50  import com.eviware.soapui.model.iface.Response;
51  import com.eviware.soapui.model.settings.Settings;
52  import com.eviware.soapui.settings.WSISettings;
53  import com.eviware.soapui.support.UISupport;
54  import com.eviware.soapui.support.types.StringToStringMap;
55  import com.eviware.soapui.support.types.StringToStringsMap;
56  import com.eviware.soapui.ui.support.DefaultDesktopPanel;
57  
58  /***
59   * Validates the request XML of a WsdlRequest
60   * 
61   * @author Ole.Matzura
62   */
63  
64  public class WSIValidateRequestAction extends AbstractToolsAction<WsdlRequest>
65  {
66  	private String configFile;
67  	private File logFile;
68  	private String wsiDir;
69  
70  	public WSIValidateRequestAction()
71  	{
72  		super( "Check WS-I Compliance", "Validates the current request/response againt the WS-I Basic Profile" );
73  	}
74  
75  	protected void generate( StringToStringMap values, ToolHost toolHost, WsdlRequest modelItem ) throws Exception
76  	{
77  		if( modelItem.getResponse() == null )
78  		{
79  			UISupport.showErrorMessage( "Response required for WS-I validations" );
80  			return;
81  		}
82  
83  		wsiDir = SoapUI.getSettings().getString( WSISettings.WSI_LOCATION,
84  				System.getProperty( "wsi.dir", System.getenv( "WSI_HOME" ) ) );
85  		if( wsiDir == null )
86  		{
87  			UISupport.showErrorMessage( "WSI Test Tools directory must be set in global preferences" );
88  			return;
89  		}
90  
91  		if( modelItem.getAttachmentCount() > 0 || modelItem.getResponse().getAttachments().length > 0 )
92  		{
93  			if( !UISupport.confirm( "Message contains attachments which is not supported by "
94  					+ "validation tools, validate anyway?", "Validation Warning" ) )
95  				return;
96  		}
97  
98  		ProcessBuilder builder = new ProcessBuilder();
99  
100 		File reportFile = File.createTempFile( "wsi-report", ".xml" );
101 
102 		ArgumentBuilder args = buildArgs( reportFile, modelItem );
103 		builder.command( args.getArgs() );
104 		builder.directory( new File( wsiDir + File.separatorChar + "java" + File.separatorChar + "bin" ) );
105 
106 		toolHost.run( new WSIProcessToolRunner( builder, reportFile, modelItem ) );
107 	}
108 
109 	private ArgumentBuilder buildArgs( File reportFile, WsdlRequest modelItem ) throws Exception
110 	{
111 		File logFile = buildLog( modelItem );
112 		File file = buildConfig( reportFile, logFile, modelItem );
113 		Settings settings = modelItem.getSettings();
114 
115 		ArgumentBuilder builder = new ArgumentBuilder( new StringToStringMap() );
116 		builder.startScript( "Analyzer", ".bat", ".sh" );
117 
118 		builder.addArgs( "-config", file.getAbsolutePath() );
119 
120 		// add this to command-line due to bug in wsi-tools (?)
121 		if( settings.getBoolean( WSISettings.ASSERTION_DESCRIPTION ) )
122 			builder.addArgs( "-assertionDescription", "true" );
123 
124 		return builder;
125 	}
126 
127 	private File buildLog( WsdlRequest modelItem ) throws Exception
128 	{
129 		LogDocument logDoc = LogDocument.Factory.newInstance();
130 		Log log = logDoc.addNewLog();
131 		log.setTimestamp( Calendar.getInstance() );
132 
133 		addMonitorConfig( log );
134 		addMessageConfig( log, modelItem );
135 
136 		logFile = File.createTempFile( "wsi-analyzer-log", ".xml" );
137 		logDoc.save( logFile );
138 		return logFile;
139 	}
140 
141 	private File buildConfig( File reportFile, File logFile, WsdlRequest modelItem ) throws IOException
142 	{
143 		Settings settings = modelItem.getSettings();
144 
145 		ConfigurationDocument configDoc = ConfigurationDocument.Factory.newInstance();
146 		Configuration config = configDoc.addNewConfiguration();
147 
148 		config.setVerbose( settings.getBoolean( WSISettings.VERBOSE ) );
149 		AssertionResults results = config.addNewAssertionResults();
150 		results.setType( AssertionResults.Type.Enum.forString( settings.getString( WSISettings.RESULTS_TYPE,
151 				AssertionResults.Type.ONLY_FAILED.toString() ) ) );
152 
153 		results.setMessageEntry( settings.getBoolean( WSISettings.MESSAGE_ENTRY ) );
154 		results.setFailureMessage( settings.getBoolean( WSISettings.FAILURE_MESSAGE ) );
155 		results.setAssertionDescription( settings.getBoolean( WSISettings.ASSERTION_DESCRIPTION ) );
156 
157 		ReportFile report = config.addNewReportFile();
158 		report.setLocation( reportFile.getAbsolutePath() );
159 		report.setReplace( true );
160 
161 		AddStyleSheet stylesheet = report.addNewAddStyleSheet();
162 		stylesheet.setHref( ".//..//common//Profiles//SSBP10_BP11_TAD.xml" );
163 		stylesheet.setType( "text/xsl" );
164 		stylesheet.setAlternate( false );
165 
166 		config.setTestAssertionsFile( "../../common/profiles/SSBP10_BP11_TAD.xml" );
167 
168 		LogFile logFileConfig = config.addNewLogFile();
169 		logFileConfig.setStringValue( logFile.getAbsolutePath() );
170 		logFileConfig.setCorrelationType( CorrelationType.ENDPOINT );
171 
172 		/*
173 		 * WsdlInterface iface = (WsdlInterface)
174 		 * modelItem.getOperation().getInterface();
175 		 * 
176 		 * WsdlReferenceConfig wsdlRef = config.addNewWsdlReference();
177 		 * wsdlRef.setWsdlURI( iface.getWsdlDefinition() );
178 		 * WsdlElementReferenceConfig wsdlElement = wsdlRef.addNewWsdlElement();
179 		 * wsdlElement.setType( WsdlElementTypeConfig.BINDING );
180 		 * wsdlElement.setStringValue( iface.getBindingName().getLocalPart() );
181 		 * wsdlElement.setNamespace( iface.getBindingName().getNamespaceURI() );
182 		 * wsdlRef.setServiceLocation( modelItem.getEndpoint() );
183 		 */
184 
185 		configFile = configDoc.toString();
186 
187 		File file = File.createTempFile( "wsi-analyzer-config", ".xml" );
188 
189 		configDoc.save( file );
190 		return file;
191 	}
192 
193 	private void addMessageConfig( Log log, WsdlRequest modelItem ) throws MalformedURLException
194 	{
195 		HttpMessageEntry requestMessage = HttpMessageEntry.Factory.newInstance();
196 		requestMessage.addNewMessageContent().setStringValue( modelItem.getRequestContent() );
197 		requestMessage.setConversationID( "1" );
198 		requestMessage.setTimestamp( Calendar.getInstance() );
199 		requestMessage.setID( "1" );
200 		URL endpoint = new URL( modelItem.getEndpoint() );
201 		requestMessage.setSenderHostAndPort( "localhost" );
202 
203 		if( endpoint.getPort() > 0 )
204 			requestMessage.setReceiverHostAndPort( endpoint.getHost() + ":" + endpoint.getPort() );
205 		else
206 			requestMessage.setReceiverHostAndPort( endpoint.getHost() );
207 
208 		requestMessage.setType( TcpMessageType.REQUEST );
209 
210 		Response response = modelItem.getResponse();
211 		HttpMessageEntry responseMessage = HttpMessageEntry.Factory.newInstance();
212 		responseMessage.addNewMessageContent().setStringValue( response.getContentAsString() );
213 		responseMessage.setConversationID( "1" );
214 		responseMessage.setType( TcpMessageType.RESPONSE );
215 		responseMessage.setTimestamp( Calendar.getInstance() );
216 		responseMessage.setID( "2" );
217 		responseMessage.setSenderHostAndPort( requestMessage.getReceiverHostAndPort() );
218 		responseMessage.setReceiverHostAndPort( requestMessage.getSenderHostAndPort() );
219 
220 		String requestHeaders = buildHttpHeadersString( response.getRequestHeaders() );
221 		requestMessage.setHttpHeaders( "POST " + endpoint.getPath() + " HTTP/1.1\r\n" + requestHeaders );
222 
223 		responseMessage.setHttpHeaders( buildHttpHeadersString( response.getResponseHeaders() ) );
224 
225 		log.setMessageEntryArray( new MessageEntry[] { requestMessage, responseMessage } );
226 	}
227 
228 	private void addMonitorConfig( Log log ) throws Exception
229 	{
230 		Monitor monitor = log.addNewMonitor();
231 
232 		monitor.setVersion( "1.5" );
233 		monitor.setReleaseDate( Calendar.getInstance() );
234 
235 		org.wsI.testing.x2003.x03.monitorConfig.Configuration conf = monitor.addNewConfiguration();
236 		conf.setCleanupTimeoutSeconds( 0 );
237 		conf.setLogDuration( 0 );
238 
239 		org.wsI.testing.x2003.x03.monitorConfig.LogFile logFileConf = conf.addNewLogFile();
240 		logFileConf.setLocation( "report.xml" );
241 		logFileConf.setReplace( true );
242 
243 		/*
244 		 * ArrayOfRedirectConfig mintConf = conf.addNewManInTheMiddle();
245 		 * RedirectConfig redirect = mintConf.addNewRedirect();
246 		 * redirect.setListenPort( 9999 ); redirect.setMaxConnections( 10 );
247 		 * redirect.setReadTimeoutSeconds( 10 );
248 		 * 
249 		 * URL endpoint = new URL( modelItem.getEndpoint()); if(
250 		 * endpoint.getPort() > 0 ) redirect.setSchemeAndHostPort(
251 		 * endpoint.getHost() + ":" + endpoint.getPort()); else
252 		 * redirect.setSchemeAndHostPort( endpoint.getHost() );
253 		 */
254 
255 		Environment env = monitor.addNewEnvironment();
256 		NameVersionPair osConf = env.addNewOperatingSystem();
257 		osConf.setName( "Windows" );
258 		osConf.setVersion( "2003" );
259 
260 		NameVersionPair rtConf = env.addNewRuntime();
261 		rtConf.setName( "java" );
262 		rtConf.setVersion( "1.5" );
263 
264 		NameVersionPair xpConf = env.addNewXmlParser();
265 		xpConf.setName( "xmlbeans" );
266 		xpConf.setVersion( "2.1.0" );
267 
268 		Implementation implConf = monitor.addNewImplementer();
269 		implConf.setName( "soapui" );
270 		implConf.setLocation( "here" );
271 	}
272 
273 	private String buildHttpHeadersString( StringToStringsMap headers )
274 	{
275 		StringBuffer buffer = new StringBuffer();
276 
277 		if( headers.containsKey( "#status#" ) )
278 		{
279 			buffer.append( headers.get( "#status#" ) ).append( "\r\n" );
280 		}
281 
282 		for( String header : headers.keySet() )
283 		{
284 			if( !header.equals( "#status#" ) )
285 			{
286 				for( String value : headers.get( header ) )
287 					buffer.append( header ).append( ": " ).append( value ).append( "\r\n" );
288 			}
289 		}
290 
291 		return buffer.toString();
292 	}
293 
294 	private class WSIProcessToolRunner extends ProcessToolRunner
295 	{
296 		private final File reportFile;
297 		private final WsdlRequest modelItem;
298 
299 		public WSIProcessToolRunner( ProcessBuilder builder, File reportFile, WsdlRequest modelItem )
300 		{
301 			super( builder, "WSI Message Validation", modelItem );
302 			this.reportFile = reportFile;
303 			this.modelItem = modelItem;
304 		}
305 
306 		public String getDescription()
307 		{
308 			return "Running WSI Analysis tools..";
309 		}
310 
311 		protected void afterRun( int exitCode, RunnerContext context )
312 		{
313 			if( exitCode == 0 && context.getStatus() == RunnerContext.RunnerStatus.FINISHED )
314 			{
315 				SwingUtilities.invokeLater( new Runnable()
316 				{
317 
318 					public void run()
319 					{
320 						try
321 						{
322 							WSIReportPanel panel = new WSIReportPanel( WSIAnalyzeAction.transformReport( reportFile ),
323 									configFile, logFile, true );
324 							panel.setPreferredSize( new Dimension( 600, 400 ) );
325 
326 							UISupport.showDesktopPanel( new DefaultDesktopPanel( "WS-I Report",
327 									"WS-I Report for validation of messages in request [" + modelItem.getName() + "]", panel ) );
328 						}
329 						catch( Exception e )
330 						{
331 							UISupport.showErrorMessage( e );
332 						}
333 					}
334 				} );
335 			}
336 		}
337 
338 		public boolean showLog()
339 		{
340 			return modelItem.getSettings().getBoolean( WSISettings.SHOW_LOG );
341 		}
342 
343 		@Override
344 		protected void beforeProcess( ProcessBuilder processBuilder, RunnerContext context )
345 		{
346 			processBuilder.environment().put( "WSI_HOME", wsiDir );
347 		}
348 	}
349 }