View Javadoc

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