package betsy.bpel; import java.nio.file.Path; import betsy.bpel.engines.AbstractBPELEngine; import betsy.bpel.model.BPELProcess; import betsy.bpel.model.BPELTestSuite; import betsy.bpel.reporting.BPELCsvReport; import betsy.bpel.reporting.Reporter; import betsy.common.analytics.Analyzer; import betsy.common.tasks.FileTasks; import betsy.common.tasks.WaitTasks; import betsy.common.timeouts.timeout.TimeoutRepository; import betsy.common.util.IOCapture; import betsy.common.util.LogUtil; import betsy.common.util.Progress; import org.apache.log4j.Logger; import org.apache.log4j.MDC; import org.codehaus.groovy.runtime.StackTraceUtils; import pebl.builder.Aggregator; import pebl.builder.Builder; import pebl.builder.PEBLEngineAdder; import pebl.builder.PEBLPerformanceResultsAdder; import pebl.builder.PEBLTestResultsEnricher; import pebl.xsd.PEBL; import static betsy.common.config.Configuration.get; public class BPELComposite { private static final Logger LOGGER = Logger.getLogger(BPELComposite.class); private final TestingAPI testingAPI = new TestingAPI(); private BPELTestSuite testSuite; private LogUtil logUtil; public TestingAPI getTestingAPI() { return testingAPI; } private void log(String name, Runnable closure) { logUtil.log(name, LOGGER, closure); } private void log(Path path, Runnable closure) { logUtil.log(path, LOGGER, closure); } public void execute() { final Progress progress = new Progress(testSuite.getProcessesCount()); logUtil = new LogUtil(testSuite); MDC.put("progress", progress.toString()); // prepare test suite // MUST BE OUTSITE OF LOG -> as it deletes whole file tree FileTasks.deleteDirectory(testSuite.getPath()); FileTasks.mkdirs(testSuite.getPath()); log(testSuite.getPath(), () -> { // fail fast for (AbstractBPELEngine engine : testSuite.getEngines()) { checkIsRunning(engine); } for (AbstractBPELEngine engine : testSuite.getEngines()) { FileTasks.mkdirs(engine.getPath()); log(engine.getPath(), () -> { for (BPELProcess process : engine.getProcesses()) { progress.next(); MDC.put("progress", progress.toString()); try { executeProcess(process); } catch (Exception e) { if (get("continue.on.exception").contains("true")) { Throwable cleanedException = StackTraceUtils.deepSanitize(e); LOGGER.error("something went wrong during execution", cleanedException); } else { throw e; } } } }); } createReports(); }); } protected void checkIsRunning(AbstractBPELEngine engine) { if (engine.isRunning()) { throw new IllegalStateException("EngineExtended " + engine + " is running"); } } protected void createReports() { log(testSuite.getReportsPath(), () -> { new Reporter(testSuite).createReports(); new Analyzer(testSuite.getCsvFilePath(), testSuite.getReportsPath()).createAnalytics(new BPELCsvReport()); PEBL pebl = Builder.getPebl(); PEBLEngineAdder.addEngines(pebl); PEBLPerformanceResultsAdder.addPerformanceResults(pebl); new PEBLTestResultsEnricher().addTestResults(testSuite, pebl); new Aggregator().computeFeatureResults(pebl); pebl.writeTo(testSuite.getPath()); }); } protected void executeProcess(final BPELProcess process) { new Retry(process).atMostThreeTimes(() -> log(process.getTargetPath(), () -> { buildPackageAndTest(process); try { install(process); startup(process); deploy(process); test(process); collect(process); } finally { // ensure shutdownServices shutdown(process); } })); } protected void shutdown(final BPELProcess process) { log(process.getTargetPath() + "/engine_shutdown", () -> new UniformProcessEngineManagementAPI(process.getEngine()).shutdown()); } protected void deploy(final BPELProcess process) { log(process.getTargetPath() + "/deploy", () -> new UniformProcessEngineManagementAPI(process.getEngine()).deploy(process.getName(), process.getDeploymentPackagePath())); } protected void install(final BPELProcess process) { log(process.getTargetPath() + "/engine_install", () -> new UniformProcessEngineManagementAPI(process.getEngine()).install()); } protected void startup(BPELProcess process) { log(process.getTargetPath() + "/engine_startup", () -> new UniformProcessEngineManagementAPI(process.getEngine()).startup()); } protected void test(final BPELProcess process) { log(process.getTargetPath() + "/test", () -> { try { try { testingAPI.startup(); } catch (Exception ignore) { testingAPI.shutdown(); LOGGER.debug("Address already in use - waiting " + TimeoutRepository.getTimeout("BPELCompositetest").getTimeoutInSeconds() + " seconds to get available"); WaitTasks.sleep(TimeoutRepository.getTimeout("BPELComposite.test").getTimeoutInMs()); testingAPI.startup(); } testSoapUi(process); } finally { testingAPI.shutdown(); } }); } protected void collect(final BPELProcess process) { log(process.getTargetPath() + "/collect", () -> new UniformProcessEngineManagementAPI(process.getEngine()).storeLogs(process.getTargetLogsPath())); } protected void testSoapUi(final BPELProcess process) { log(process.getTargetPath() + "/test_soapui", () -> IOCapture.captureIO(() -> testingAPI.executeEngineDependentTest(process.getTargetSoapUIFilePath(), process.getTargetReportsPath()))); WaitTasks.sleep(TimeoutRepository.getTimeout("BPELComposite.testSoapUi").getTimeoutInMs()); } protected void buildPackageAndTest(final BPELProcess process) { log(process.getTargetPath() + "/build", () -> { buildPackage(process); buildTest(process); }); } protected void buildTest(final BPELProcess process) { log(process.getTargetPath() + "/build_test", () -> IOCapture.captureIO(() -> testingAPI.generateEngineDependentTest(process))); } protected void buildPackage(final BPELProcess process) { log(process.getTargetPath() + "/build_package", () -> IOCapture.captureIO( () -> { Path path = new UniformProcessEngineManagementAPI(process.getEngine()).buildArchives(process); process.setDeploymentPackagePath(path); })); } public void setTestSuite(BPELTestSuite testSuite) { this.testSuite = testSuite; } }