/* * SoapUI, Copyright (C) 2004-2016 SmartBear Software * * Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://ec.europa.eu/idabc/eupl * * Unless required by applicable law or agreed to in writing, software distributed under the Licence is * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the Licence for the specific language governing permissions and limitations * under the Licence. */ package com.eviware.soapui.tools; import com.eviware.soapui.SoapUI; import com.eviware.soapui.impl.wsdl.WsdlProject; import com.eviware.soapui.model.mock.MockResult; import com.eviware.soapui.model.mock.MockRunContext; import com.eviware.soapui.model.mock.MockRunner; import com.eviware.soapui.model.mock.MockService; import com.eviware.soapui.model.project.ProjectFactoryRegistry; import com.eviware.soapui.model.support.MockRunListenerAdapter; import com.eviware.soapui.support.DateUtil; import org.apache.commons.cli.CommandLine; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * Standalone tool-runner used from maven-plugin, can also be used from * command-line (see xdocs) or directly from other classes. * <p> * For standalone usage, set the project file (with setProjectFile) and other * desired properties before calling run * </p> * * @author Ole.Matzura */ public class SoapUIMockServiceRunner extends AbstractSoapUIRunner { private String mockService; private String port; private String path; private List<MockRunner> runners = new ArrayList<MockRunner>(); private boolean block; private String projectPassword; private WsdlProject project; private boolean saveAfterRun; public static String TITLE = "SoapUI " + SoapUI.SOAPUI_VERSION + " MockService Runner"; /** * Runs the specified MockService in the specified SoapUI project file, see * SoapUI xdocs for details. * * @param args * @throws Exception */ public static void main(String[] args) throws Exception { System.exit(new SoapUIMockServiceRunner().runFromCommandLine(args)); } public void setMockService(String mockService) { this.mockService = mockService; } public void setPath(String path) { this.path = path; } public void setPort(String port) { this.port = port; } public SoapUIMockServiceRunner() { super(TITLE); } public SoapUIMockServiceRunner(String title) { super(title); } public boolean runRunner() throws Exception { initGroovyLog(); String projectFile = getProjectFile(); // WsdlProject project = new WsdlProject( projectFile, // getProjectPassword() ); project = (WsdlProject) ProjectFactoryRegistry.getProjectFactory("wsdl").createNew(projectFile, getProjectPassword()); if (project.isDisabled()) { throw new Exception("Failed to load SoapUI project file [" + projectFile + "]"); } initProject(); if (mockService == null) { log.info("Running all MockServices in project [" + project.getName() + "]"); } else { log.info("Running MockService [" + mockService + "] in project [" + project.getName() + "]"); } log.info("Press any key to terminate"); long startTime = System.nanoTime(); for (int c = 0; c < project.getMockServiceCount(); c++) { MockService mockService = project.getMockServiceAt(c); if (this.mockService == null || mockService.getName().equals(this.mockService)) { runMockService(mockService); } } for (int c = 0; c < project.getRestMockServiceCount(); c++) { MockService mockService = project.getRestMockServiceAt(c); if (this.mockService == null || mockService.getName().equals(this.mockService)) { runMockService(mockService); } } log.info("Started " + runners.size() + " runner" + ((runners.size() == 1) ? "" : "s")); if (block) { System.out.println("Press any key to terminate..."); while (System.in.available() == 0) { Thread.sleep(1000); // check if runners are still running for (int c = 0; c < runners.size(); c++) { if (!runners.get(c).isRunning()) { runners.remove(c); c--; } } if (runners.isEmpty()) { break; } } if (System.in.available() > 0) { System.in.read(); } for (MockRunner runner : runners) { runner.stop(); } if (saveAfterRun && !project.isRemote()) { try { project.save(); } catch (Throwable t) { log.error("Failed to save project", t); } } } long timeTaken = (System.nanoTime() - startTime) / 1000000; log.info("time taken: " + timeTaken + "ms"); exportReports(); return block; } protected void initProject() throws Exception { initProjectProperties(project); } protected void exportReports() throws Exception { } /** * Runs the specified MockService * * @param mockService */ public void runMockService(MockService mockService) { try { if (path != null) { mockService.setPath(path); } if (port != null) { mockService.setPort(Integer.parseInt(port)); } mockService.addMockRunListener(new LogListener()); MockRunner runner = mockService.start(); runner.setLogEnabled(false); runners.add(runner); } catch (Exception e) { SoapUI.logError(e); } } public class LogListener extends MockRunListenerAdapter { private int responseCount; public void onMockRunnerStart(MockRunner mockRunner) { MockRunContext mockContext = mockRunner.getMockContext(); log.info("MockService started on port " + mockContext.getMockService().getPort() + " at path [" + mockContext.getMockService().getPath() + "]"); } public void onMockRunnerStop(MockRunner mockRunner) { log.info("MockService stopped, handled " + responseCount + " requests"); } public void onMockResult(MockResult result) { responseCount++; if (result.getMockResponse() == null) { log.info("Handled request " + responseCount + " - [missing mockResponse] in [" + result.getTimeTaken() + "ms] at [" + DateUtil.formatExtraFull(new Date(result.getTimestamp())) + "]"); } else { log.info("Handled request " + responseCount + "; [" + result.getMockResponse().getMockOperation().getName() + "] with [" + result.getMockResponse().getName() + "] in [" + result.getTimeTaken() + "ms] at [" + DateUtil.formatExtraFull(new Date(result.getTimestamp())) + "]"); } } } @Override protected SoapUIOptions initCommandLineOptions() { SoapUIOptions options = new SoapUIOptions("mockservicerunner"); options.addOption("m", true, "Specified the name of the MockService to run"); options.addOption("p", true, "Sets the local port to listen on"); options.addOption("a", true, "Sets the url path to listen on"); options.addOption("s", true, "Sets the soapui-settings.xml file to use"); options.addOption("b", false, "Turns off blocking read for termination"); options.addOption("x", true, "Sets project password for decryption if project is encrypted"); options.addOption("v", true, "Sets password for soapui-settings.xml file"); options.addOption("D", true, "Sets system property with name=value"); options.addOption("G", true, "Sets global property with name=value"); options.addOption("P", true, "Sets or overrides project property with name=value"); options.addOption("S", false, "Saves the project after running the mockService(s)"); return options; } @Override protected boolean processCommandLine(CommandLine cmd) { if (cmd.hasOption("m")) { setMockService(getCommandLineOptionSubstSpace(cmd, "m")); } if (cmd.hasOption("a")) { setPath(getCommandLineOptionSubstSpace(cmd, "a")); } if (cmd.hasOption("p")) { setPort(cmd.getOptionValue("p")); } if (cmd.hasOption("s")) { setSettingsFile(getCommandLineOptionSubstSpace(cmd, "s")); } setBlock(!cmd.hasOption('b')); setSaveAfterRun(cmd.hasOption('S')); if (cmd.hasOption("x")) { setProjectPassword(cmd.getOptionValue("x")); } if (cmd.hasOption("v")) { setSoapUISettingsPassword(cmd.getOptionValue("v")); } if (cmd.hasOption("D")) { setSystemProperties(cmd.getOptionValues("D")); } if (cmd.hasOption("G")) { setGlobalProperties(cmd.getOptionValues("G")); } if (cmd.hasOption("P")) { setProjectProperties(cmd.getOptionValues("P")); } return true; } public void setProjectPassword(String projectPassword) { this.projectPassword = projectPassword; } public String getProjectPassword() { return projectPassword; } public void setBlock(boolean block) { this.block = block; } public void setSaveAfterRun(boolean saveAfterRun) { this.saveAfterRun = saveAfterRun; } public WsdlProject getProject() { return project; } public void stopAll() { for (MockRunner runner : runners) { runner.stop(); } } }