/* * Copyright 2017 Nokia Solutions and Networks * Licensed under the Apache License, Version 2.0, * see license.txt file for details. */ package org.robotframework.ide.eclipse.main.plugin.launch.remote; import java.io.IOException; import java.net.SocketTimeoutException; import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.TimeUnit; import org.rf.ide.core.execution.RobotDefaultAgentEventListener; import org.rf.ide.core.execution.server.AgentServerStatusListener; import org.robotframework.ide.eclipse.main.plugin.launch.RobotConsoleFacade; import com.google.common.base.Splitter; class RemoteConnectionStatusTracker extends RobotDefaultAgentEventListener implements AgentServerStatusListener { private static final String POISON_PILL = "POISON_PILL"; private final BlockingQueue<String> messagesQueue = new ArrayBlockingQueue<>(50); private RobotConsoleFacade redConsole; @Override public void serverEstablished(final String host, final int port) { writeMessageLine("Remote execution server is listening on " + host + ":" + port + ", you can execute tests on remote client"); } @Override public void clientConnected(final int clientId) { writeMessageLine("Remote connection has been established (client id #" + clientId + ")"); } @Override public void clientConnectionClosed(final int clientId) { writeMessageLine("Remote connection closed (client id #" + clientId + ")"); endQueueing(); } @Override public void clientConnectionTimedOut(final SocketTimeoutException e) { writeMessageLine("A timeout was reached while waiting for a remote connection"); endQueueing(); } @Override public void clientConnectionError(final IOException e) { writeMessageLine("Connection error occurred:\n" + indentMessage(e.getMessage())); endQueueing(); } @Override public void clientEventHandlingError(final RobotAgentEventsListenerException e) { writeMessageLine("Error occurred when communicating with agent:\n" + indentMessage(e.getMessage())); endQueueing(); } private static String indentMessage(final String message) { final List<String> msgLines = Splitter.on('\n').splitToList(message); return "\t" + String.join("\n\t", msgLines); } @Override public void handleVersions(final String pythonVersion, final String robotVersion, final int protocolVersion) { writeMessageLine("client python version: " + pythonVersion); writeMessageLine("client robot version: " + robotVersion); } @Override public void handleClosed() { writeMessageLine("tests finished on client machine"); } private void writeMessageLine(final String message) { try { messagesQueue.put(message); } catch (final InterruptedException e) { // FIXME : handle this stuff here e.printStackTrace(); } } private void endQueueing() { try { messagesQueue.put(POISON_PILL); } catch (final InterruptedException e) { // FIXME : handle this stuff here e.printStackTrace(); } } void startTrackingInto(final RobotConsoleFacade redConsole) { this.redConsole = redConsole; new Thread(this::writeMessagesToStream).start(); } private void writeMessagesToStream() { try { // take with timeout for the first time, since maybe nothing was written if // server failed before setting up String msg = messagesQueue.poll(10_000, TimeUnit.MILLISECONDS); if (msg == null) { return; } while (!POISON_PILL.equals(msg)) { redConsole.writeLine(msg); msg = messagesQueue.take(); } } catch (final InterruptedException | IOException e) { // FIXME : handle this stuff here e.printStackTrace(); } } }