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.ui.support.DefaultDesktopPanel;
54  
55  /***
56   * Validates the current request/response exchange of a WsdlMockResponse with
57   * the WS-I tools
58   * 
59   * @author Ole.Matzura
60   */
61  
62  public class WSIValidateResponseAction extends AbstractToolsAction<WsdlMockResponse>
63  {
64  	private String configFile;
65  	private File logFile;
66  	private String wsiDir;
67  
68  	public WSIValidateResponseAction()
69  	{
70  		super( "Check WS-I Compliance", "Validates the current request/response againt the WS-I Basic Profile" );
71  		// putValue( Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "alt W" ));
72  
73  		// setEnabled( request != null && request.getMockResult() != null );
74  	}
75  
76  	protected void generate( StringToStringMap values, ToolHost toolHost, WsdlMockResponse modelItem ) throws Exception
77  	{
78  		if( modelItem.getMockResult() == null )
79  		{
80  			UISupport.showErrorMessage( "Request/Response required for WS-I validations" );
81  			return;
82  		}
83  
84  		wsiDir = SoapUI.getSettings().getString( WSISettings.WSI_LOCATION,
85  				System.getProperty( "wsi.dir", System.getenv( "WSI_HOME" ) ) );
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 )
93  		{
94  			if( !UISupport.confirm( "Response 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, modelItem );
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, modelItem ) );
108 	}
109 
110 	private ArgumentBuilder buildArgs( File reportFile, WsdlMockResponse modelItem ) throws Exception
111 	{
112 		File logFile = buildLog( modelItem );
113 		File file = buildConfig( reportFile, logFile, modelItem );
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( WsdlMockResponse modelItem ) 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, modelItem );
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, WsdlMockResponse modelItem ) 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( AssertionResults.Type.Enum.forString( settings.getString( WSISettings.RESULTS_TYPE,
152 				AssertionResults.Type.ONLY_FAILED.toString() ) ) );
153 
154 		results.setMessageEntry( settings.getBoolean( WSISettings.MESSAGE_ENTRY ) );
155 		results.setFailureMessage( settings.getBoolean( WSISettings.FAILURE_MESSAGE ) );
156 		results.setAssertionDescription( settings.getBoolean( WSISettings.ASSERTION_DESCRIPTION ) );
157 
158 		ReportFile report = config.addNewReportFile();
159 		report.setLocation( reportFile.getAbsolutePath() );
160 		report.setReplace( true );
161 
162 		AddStyleSheet stylesheet = report.addNewAddStyleSheet();
163 		stylesheet.setHref( ".//..//common//Profiles//SSBP10_BP11_TAD.xml" );
164 		stylesheet.setType( "text/xsl" );
165 		stylesheet.setAlternate( false );
166 
167 		config.setTestAssertionsFile( "../../common/profiles/SSBP10_BP11_TAD.xml" );
168 
169 		LogFile logFileConfig = config.addNewLogFile();
170 		logFileConfig.setStringValue( logFile.getAbsolutePath() );
171 		logFileConfig.setCorrelationType( CorrelationType.ENDPOINT );
172 
173 		/*
174 		 * WsdlInterface iface = (WsdlInterface)
175 		 * modelItem.getOperation().getInterface();
176 		 * 
177 		 * WsdlReferenceConfig wsdlRef = config.addNewWsdlReference();
178 		 * wsdlRef.setWsdlURI( iface.getWsdlDefinition() );
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, WsdlMockResponse modelItem ) throws MalformedURLException
195 	{
196 		HttpMessageEntry requestMessage = HttpMessageEntry.Factory.newInstance();
197 		WsdlMockRequest mockRequest = modelItem.getMockResult().getMockRequest();
198 		requestMessage.addNewMessageContent().setStringValue( mockRequest.getRequestContent() );
199 		requestMessage.setConversationID( "1" );
200 		requestMessage.setTimestamp( Calendar.getInstance() );
201 		requestMessage.setID( "1" );
202 		MockService mockService = modelItem.getMockOperation().getMockService();
203 		URL endpoint = new URL( "http://127.0.0.1:" + mockService.getPort() + mockService.getPath() );
204 		requestMessage.setSenderHostAndPort( "localhost" );
205 
206 		if( endpoint.getPort() > 0 )
207 			requestMessage.setReceiverHostAndPort( endpoint.getHost() + ":" + endpoint.getPort() );
208 		else
209 			requestMessage.setReceiverHostAndPort( endpoint.getHost() );
210 
211 		requestMessage.setType( TcpMessageType.REQUEST );
212 
213 		HttpMessageEntry responseMessage = HttpMessageEntry.Factory.newInstance();
214 		responseMessage.addNewMessageContent().setStringValue( modelItem.getMockResult().getResponseContent() );
215 		responseMessage.setConversationID( "1" );
216 		responseMessage.setType( TcpMessageType.RESPONSE );
217 		responseMessage.setTimestamp( Calendar.getInstance() );
218 		responseMessage.setID( "2" );
219 		responseMessage.setSenderHostAndPort( requestMessage.getReceiverHostAndPort() );
220 		responseMessage.setReceiverHostAndPort( requestMessage.getSenderHostAndPort() );
221 
222 		String requestHeaders = buildHttpHeadersString( mockRequest.getRequestHeaders() );
223 		requestMessage.setHttpHeaders( "POST " + mockRequest.getPath() + " " + mockRequest.getProtocol() + "\r\n"
224 				+ requestHeaders );
225 
226 		responseMessage.setHttpHeaders( "HTTP/1.1 200 OK"
227 				+ buildHttpHeadersString( modelItem.getMockResult().getResponseHeaders() ) );
228 
229 		log.setMessageEntryArray( new MessageEntry[] { requestMessage, responseMessage } );
230 	}
231 
232 	private void addMonitorConfig( Log log ) throws Exception
233 	{
234 		Monitor monitor = log.addNewMonitor();
235 
236 		monitor.setVersion( "1.5" );
237 		monitor.setReleaseDate( Calendar.getInstance() );
238 
239 		org.wsI.testing.x2003.x03.monitorConfig.Configuration conf = monitor.addNewConfiguration();
240 		conf.setCleanupTimeoutSeconds( 0 );
241 		conf.setLogDuration( 0 );
242 
243 		org.wsI.testing.x2003.x03.monitorConfig.LogFile logFileConf = conf.addNewLogFile();
244 		logFileConf.setLocation( "report.xml" );
245 		logFileConf.setReplace( true );
246 
247 		/*
248 		 * ArrayOfRedirectConfig mintConf = conf.addNewManInTheMiddle();
249 		 * RedirectConfig redirect = mintConf.addNewRedirect();
250 		 * redirect.setListenPort( 9999 ); redirect.setMaxConnections( 10 );
251 		 * redirect.setReadTimeoutSeconds( 10 );
252 		 * 
253 		 * URL endpoint = new URL( modelItem.getEndpoint()); if(
254 		 * endpoint.getPort() > 0 ) redirect.setSchemeAndHostPort(
255 		 * endpoint.getHost() + ":" + endpoint.getPort()); else
256 		 * redirect.setSchemeAndHostPort( endpoint.getHost() );
257 		 */
258 
259 		Environment env = monitor.addNewEnvironment();
260 		NameVersionPair osConf = env.addNewOperatingSystem();
261 		osConf.setName( "Windows" );
262 		osConf.setVersion( "2003" );
263 
264 		NameVersionPair rtConf = env.addNewRuntime();
265 		rtConf.setName( "java" );
266 		rtConf.setVersion( "1.5" );
267 
268 		NameVersionPair xpConf = env.addNewXmlParser();
269 		xpConf.setName( "xmlbeans" );
270 		xpConf.setVersion( "2.2.0" );
271 
272 		Implementation implConf = monitor.addNewImplementer();
273 		implConf.setName( "soapui" );
274 		implConf.setLocation( "here" );
275 	}
276 
277 	private String buildHttpHeadersString( StringToStringMap requestHeaders )
278 	{
279 		StringBuffer buffer = new StringBuffer();
280 
281 		if( requestHeaders.containsKey( "#status#" ) )
282 		{
283 			buffer.append( requestHeaders.get( "#status#" ) ).append( "\r\n" );
284 		}
285 
286 		for( String header : requestHeaders.keySet() )
287 		{
288 			if( !header.equals( "#status#" ) )
289 				buffer.append( header ).append( ": " ).append( requestHeaders.get( header ) ).append( "\r\n" );
290 		}
291 
292 		return buffer.toString();
293 	}
294 
295 	private class WSIProcessToolRunner extends ProcessToolRunner
296 	{
297 		private final File reportFile;
298 		private final WsdlMockResponse modelItem;
299 
300 		public WSIProcessToolRunner( ProcessBuilder builder, File reportFile, WsdlMockResponse modelItem )
301 		{
302 			super( builder, "WSI Message Validation", modelItem );
303 			this.reportFile = reportFile;
304 			this.modelItem = modelItem;
305 		}
306 
307 		public String getDescription()
308 		{
309 			return "Running WSI Analysis tools..";
310 		}
311 
312 		protected void afterRun( int exitCode, RunnerContext context )
313 		{
314 			try
315 			{
316 				if( exitCode == 0 && context.getStatus() == RunnerContext.RunnerStatus.FINISHED )
317 				{
318 					WSIReportPanel panel = new WSIReportPanel( reportFile, configFile, logFile, true );
319 					panel.setPreferredSize( new Dimension( 600, 400 ) );
320 
321 					UISupport.showDesktopPanel( new DefaultDesktopPanel( "WS-I Report",
322 							"WS-I Report for validation of messages in MockResponse [" + modelItem.getName() + "]", panel ) );
323 				}
324 			}
325 			catch( Exception e )
326 			{
327 				UISupport.showErrorMessage( e );
328 			}
329 		}
330 
331 		public boolean showLog()
332 		{
333 			return modelItem.getSettings().getBoolean( WSISettings.SHOW_LOG );
334 		}
335 
336 		@Override
337 		protected void beforeProcess( ProcessBuilder processBuilder, RunnerContext context )
338 		{
339 			processBuilder.environment().put( "WSI_HOME", wsiDir );
340 		}
341 	}
342 }