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