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