/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.test.infrastructure.process; import org.mule.runtime.core.util.concurrent.Latch; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TestProcess implements CommandServer.CommandListener { private Logger logger = LoggerFactory.getLogger(TestProcess.class); private final Latch clientSocketAcceptedLatch = new Latch(); private final Latch contextStartedLatch = new Latch(); private Process process; private String instanceId; private ServerSocket loggerSocket; private CommandServer commandServer; private Thread loggerThread; public TestProcess(String instanceId, int loggerServerPort, int commandServerPort) { this.instanceId = instanceId; createLoggerServerSocket(loggerServerPort); createCommandServer(commandServerPort); } public void destroyQuietly() { try { logger.info(String.format("# Destroying process for instance %s #", instanceId)); loggerThread.interrupt(); closeQuietly(loggerSocket); commandServer.stop(); process.destroy(); } catch (Exception e) { // Nothing to do. } } @Override public void commandReceived(String command) { if (command.equals(CommandServer.MULE_CONTEXT_STARTED_COMMAND)) { contextStartedLatch.release(); } } public void waitUntilStarted() throws InterruptedException { waitUntilStarted(30); } public void waitUntilStarted(int contextStartedTiemout) throws InterruptedException { if (!clientSocketAcceptedLatch.await(TestUtils.getTimeout(20), TimeUnit.SECONDS)) { throw new IllegalStateException(String.format("Client process %s didn not connect connect to logger service", instanceId)); } if (!contextStartedLatch.await(TestUtils.getTimeout(contextStartedTiemout), TimeUnit.SECONDS)) { throw new RuntimeException(String.format("Process %s didn not start within 30 seconds", instanceId)); } } private void createCommandServer(int commandServerPort) { try { logger.info("Creating command server on port: " + commandServerPort + " for instance " + instanceId); commandServer = new CommandServer(commandServerPort); commandServer.start(); commandServer.setCommandListener(this); } catch (IOException e) { if (commandServer != null) { commandServer.stop(); } throw new RuntimeException(e); } } private void createLoggerServerSocket(int loggerServerPort) { try { logger.info("Creating logger service on port: " + loggerServerPort); loggerSocket = new ServerSocket(loggerServerPort, 0, InetAddress.getByName("localhost")); loggerThread = new Thread(String.format("Process %s logger", instanceId)) { @Override public void run() { try { Socket processClientConnection = loggerSocket.accept(); clientSocketAcceptedLatch.release(); BufferedReader processClientLogEntriesInputStream = new BufferedReader(new InputStreamReader(processClientConnection.getInputStream())); while (!Thread.interrupted()) { String logLine = processClientLogEntriesInputStream.readLine(); if (logLine == null) { try { Thread.sleep(200); } catch (InterruptedException e) { return; } } else { logger.info(logLine); } } } catch (IOException e) { throw new RuntimeException(e); } finally { closeQuietly(loggerSocket); } } }; loggerThread.setDaemon(true); loggerThread.start(); } catch (IOException e) { closeQuietly(loggerSocket); throw new RuntimeException(e); } } private void closeQuietly(ServerSocket loggerSocket) { try { if (loggerSocket != null) { loggerSocket.close(); } } catch (IOException e) { // Do nothing. } } public void setProcess(Process process) { this.process = process; } }