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.tools;
14  
15  import java.text.SimpleDateFormat;
16  import java.util.ArrayList;
17  import java.util.Date;
18  import java.util.List;
19  
20  import javax.servlet.http.HttpServletRequest;
21  import javax.servlet.http.HttpServletResponse;
22  
23  import org.apache.commons.cli.CommandLine;
24  
25  import com.eviware.soapui.SoapUI;
26  import com.eviware.soapui.impl.wsdl.WsdlProject;
27  import com.eviware.soapui.impl.wsdl.mock.WsdlMockService;
28  import com.eviware.soapui.model.mock.MockResult;
29  import com.eviware.soapui.model.mock.MockRunListener;
30  import com.eviware.soapui.model.mock.MockRunner;
31  import com.eviware.soapui.model.mock.MockService;
32  import com.eviware.soapui.model.project.ProjectFactoryRegistry;
33  
34  /***
35   * Standalone tool-runner used from maven-plugin, can also be used from command-line (see xdocs) or
36   * directly from other classes.
37   * <p>
38   * For standalone usage, set the project file (with setProjectFile) and other desired properties before
39   * calling run</p> 
40   * 
41   * @author Ole.Matzura
42   */
43  
44  public class SoapUIMockServiceRunner extends AbstractSoapUIRunner
45  {
46  	private String mockService;
47  	private String port;
48  	private String path;
49  	private List<MockRunner> runners = new ArrayList<MockRunner>();
50  	private boolean block;
51  	private String projectPassword;
52  	private WsdlProject project;
53  	
54  	public static String TITLE = "soapUI " + SoapUI.SOAPUI_VERSION + " MockService Runner";
55  	
56  
57  	/***
58  	 * Runs the specified MockService in the specified soapUI project file, see soapUI xdocs for details.
59  	 * 
60  	 * @param args
61  	 * @throws Exception
62  	 */
63  
64  	public static void main( String [] args) throws Exception
65  	{
66  		new SoapUIMockServiceRunner().runFromCommandLine( args );
67  	}
68  
69  	public void setMockService(String mockService)
70  	{
71  		this.mockService = mockService;
72  	}
73  
74  	public void setPath( String path )
75  	{
76  		this.path = path;
77  	}
78  
79  	public void setPort( String port )
80  	{
81  		this.port = port;
82  	}
83  
84  	public SoapUIMockServiceRunner()
85  	{
86  		super( TITLE );
87  	}
88  	
89  	public SoapUIMockServiceRunner( String title )
90  	{
91  		super( title );
92  	}
93  	
94  	public boolean runRunner() throws Exception
95  	{
96  		initGroovyLog();
97  		
98  		String projectFile = getProjectFile();
99  		
100 //		WsdlProject project = new WsdlProject( projectFile, getProjectPassword() );
101 		WsdlProject project = (WsdlProject) ProjectFactoryRegistry.getProjectFactory("wsdl").createNew(projectFile, getProjectPassword());
102 		if( project.isDisabled() )
103 			throw new Exception( "Failed to load soapUI project file [" + projectFile + "]" );
104 		
105 		initProject();
106 				
107 		if( mockService == null )
108 			log.info( "Running all MockServices in project [" + project.getName() + "]" );
109 		else
110 			log.info( "Running MockService [" + mockService + "] in project [" + project.getName() + "]" );
111 		
112 		log.info( "Press any key to terminate" );
113 		
114 		long startTime = System.nanoTime();
115 		
116 		for( int c = 0; c < project.getMockServiceCount(); c++ )
117 		{
118 			MockService ms = project.getMockServiceAt( c );
119 			if( mockService == null || ms.getName().equals( mockService ))
120 				runMockService( ( WsdlMockService ) ms );
121 		}
122 		
123 		log.info( "Started " + runners.size() + " runner" + ((runners.size() == 1) ? "" : "s" ) );
124 		
125 		if( block )
126 		{
127 			System.out.println( "Press any key to terminate..." );
128 			System.in.read();
129 			for( MockRunner runner : runners )
130 				runner.stop();
131 		}
132 		
133 		long timeTaken = (System.nanoTime()-startTime)/1000000;
134 		log.info( "time taken: " + timeTaken + "ms" );
135 		
136 		exportReports();
137 		
138 		return block;
139 	}
140 	
141 	 protected void initProject() throws Exception
142 	   {
143 	   }
144 	 
145 	 protected void exportReports() throws Exception
146 	 {
147 	 }
148 	
149 	/***
150 	 * Runs the specified MockService
151 	 * 
152 	 * @param mockService
153 	 */
154 	
155 	public void runMockService( WsdlMockService mockService )
156 	{
157 		try
158 		{
159 			if( path != null )
160 				mockService.setPath( path );
161 			
162 			if( port != null )
163 				mockService.setPort( Integer.parseInt( port ));
164 			
165 			mockService.addMockRunListener( new LogListener() );
166 			runners.add( mockService.start() );
167 		}
168 		catch (Exception e)
169 		{
170 			SoapUI.logError( e );
171 		}
172 	}
173 
174    public class LogListener implements MockRunListener
175 	{
176    	private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
177 		private int responseCount;
178    	
179 		public void onMockRunnerStart( MockRunner mockRunner )
180 		{
181 			log.info( "MockService started on port " + mockRunner.getMockService().getPort() + " at path [" + 
182 						mockRunner.getMockService().getPath() + "]" );
183 		}
184 
185 		public void onMockRunnerStop( MockRunner mockRunner )
186 		{
187 			log.info( "MockService stopped, handled " + responseCount + " requests" );
188 		}
189 
190 		public void onMockResult( MockResult result )
191 		{
192 			responseCount++;
193 			log.info( "Handled request " + responseCount + "; [" + result.getMockResponse().getMockOperation().getName() + 
194 						"] with [" + result.getMockResponse().getName() + "] in [" + result.getTimeTaken() + 
195 						"ms] at [" + dateFormat.format( new Date( result.getTimestamp())) + "]" );
196 		}
197 
198 		public void onMockRequest( MockRunner runner, HttpServletRequest request, HttpServletResponse response )
199 		{
200 		}
201 	}
202 
203 	@Override
204 	protected SoapUIOptions initCommandLineOptions()
205 	{
206 		SoapUIOptions options = new SoapUIOptions( "mockservicerunner" );
207 		options.addOption( "m", true, "Specified the name of the MockService to run" );
208 		options.addOption( "p", true, "Sets the local port to listen on" );
209 		options.addOption( "a", true, "Sets the url path to listen on" );
210 		options.addOption( "s", true, "Sets the soapui-settings.xml file to use" );
211 		options.addOption( "b", false, "Turns off blocking read for termination" );
212 		options.addOption( "x", true, "Sets project password for decryption if project is encrypted" );
213 		options.addOption( "v", true, "Sets password for soapui-settings.xml file");
214 		return options;
215 	}
216 
217 	@Override
218 	protected boolean processCommandLine( CommandLine cmd )
219 	{
220 		if( cmd.hasOption( "m" ))
221 			setMockService( getCommandLineOptionSubstSpace( cmd, "m") );
222 		
223 		if( cmd.hasOption( "a"))
224 			setPath( getCommandLineOptionSubstSpace( cmd, "a" ) );
225 
226 		if( cmd.hasOption( "p"))
227 			setPort( cmd.getOptionValue( "p" ) );
228 		
229 		if( cmd.hasOption( "s"))
230 			setSettingsFile( getCommandLineOptionSubstSpace( cmd, "s" ));
231 		
232 		setBlock( !cmd.hasOption( 'b' ));
233 		
234 		if( cmd.hasOption( "x" ) ) {
235 			setProjectPassword( cmd.getOptionValue("x"));
236 		}
237 		
238 		if( cmd.hasOption( "v" ) ) {
239 			setSoapUISettingsPassword( cmd.getOptionValue("v"));
240 		}
241 		
242 		return true;
243 	}
244 
245 	public void setProjectPassword(String projectPassword) {
246 		this.projectPassword = projectPassword;
247 	}
248 
249 	public String getProjectPassword() {
250 		return projectPassword;
251 	}
252 	
253 	public void setBlock( boolean block )
254 	{
255 		this.block = block;
256 	}
257 	
258 	 public WsdlProject getProject()
259 	   {
260 	      return project;
261 	   }
262 }