View Javadoc

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