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