aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorStephane Gamard <stephane.gamard@searchbox.com>2014-07-10 15:13:26 +0200
committerStephane Gamard <stephane.gamard@searchbox.com>2014-07-10 18:06:46 +0200
commit2f7578b400c12aaee7c4dadc76183a7406ab3530 (patch)
tree773d9f49a252535709981ea78f409a26c7ab11d7 /server
parent239c1c798c2c7685ab71c1b063072dab0be06aae (diff)
downloadsonarqube-2f7578b400c12aaee7c4dadc76183a7406ab3530.tar.gz
sonarqube-2f7578b400c12aaee7c4dadc76183a7406ab3530.zip
SONAR-5409 - Added monitoring service to sonar-process
Diffstat (limited to 'server')
-rw-r--r--server/sonar-process/src/main/java/org/sonar/Application.java41
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/Launcher.java90
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/MonitorService.java81
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/Process.java3
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/ProcessWrapper.java (renamed from server/sonar-process/src/test/java/org/sonar/process/LauncherTest.java)26
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/MonitorServiceTest.java46
6 files changed, 177 insertions, 110 deletions
diff --git a/server/sonar-process/src/main/java/org/sonar/Application.java b/server/sonar-process/src/main/java/org/sonar/Application.java
index 829f264940a..9da457086d1 100644
--- a/server/sonar-process/src/main/java/org/sonar/Application.java
+++ b/server/sonar-process/src/main/java/org/sonar/Application.java
@@ -21,16 +21,15 @@ package org.sonar;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.sonar.process.Launcher;
+import org.sonar.process.MonitorService;
+import org.sonar.process.ProcessWrapper;
import java.io.IOException;
import java.net.DatagramSocket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
-/**
- * @Since 4.5
- */
public class Application {
private final static Logger LOGGER = LoggerFactory.getLogger(Application.class);
@@ -43,27 +42,39 @@ public class Application {
public static void main(String... args) throws InterruptedException, IOException {
final ExecutorService executor = Executors.newFixedThreadPool(2);
- final Launcher sonarQube = new Launcher("SQ", systemAvailableSocket());
- final Launcher elasticsearch = new Launcher("ES", systemAvailableSocket());
+ final MonitorService monitor = new MonitorService(systemAvailableSocket());
+
+ //Create the processes
+ //final ProcessWrapper sonarQube = new ProcessWrapper("SQ", monitor);
+ final ProcessWrapper elasticsearch = null;//new ProcessWrapper("ES", monitor.getMonitoringPort());
+
+ //Register processes to monitor
+ monitor.register(elasticsearch);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
LOGGER.info("Shutting down sonar Node");
- sonarQube.interrupt();
+ //sonarQube.shutdown();
elasticsearch.interrupt();
- executor.shutdownNow();
+ executor.shutdown();
+ try {
+ executor.awaitTermination(10L, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ LOGGER.warn("Executing terminated", e);
+ }
}
});
- LOGGER.info("Starting SQ Node...");
- executor.submit(sonarQube);
-
- LOGGER.info("Starting ES Node...");
+ // Start our processes
+ LOGGER.info("Starting Child processes...");
executor.submit(elasticsearch);
+ //executor.submit(sonarQube);
+
+ // And monitor the activity
+ monitor.run();
- while (!executor.isTerminated()) {
- Thread.sleep(1000);
- }
+ // If monitor is finished, we're done. Cleanup
+ executor.shutdown();
}
}
diff --git a/server/sonar-process/src/main/java/org/sonar/process/Launcher.java b/server/sonar-process/src/main/java/org/sonar/process/Launcher.java
deleted file mode 100644
index fd354c48590..00000000000
--- a/server/sonar-process/src/main/java/org/sonar/process/Launcher.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.process;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-
-/**
- * @Since 4.5
- */
-public class Launcher extends Thread {
-
- private final static Logger LOGGER = LoggerFactory.getLogger(Launcher.class);
-
- final String name;
- final DatagramSocket socket;
- java.lang.Process process;
-
-
- public Launcher(String name, DatagramSocket socket) {
- LOGGER.info("Creating Launcher for '{}' with base port: {}", name, socket.getLocalPort());
- this.name = name;
- this.socket = socket;
- }
-
- private void launch() {
-// new Thread(new Runnable() {
-// @Override
-// public void run() {
-// Runner.main(name, socket.getLocalPort() + "");
-// }
-// }).start();
- }
-
- private void shutdown() {
- process.destroy();
- }
-
- private void monitor() {
- long ping = Long.MAX_VALUE;
- while (true) {
- LOGGER.info("My heart is beating");
- DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
- try {
- socket.setSoTimeout(3000);
- socket.receive(packet);
- } catch (Exception e) {
- // Do nothing
- }
- long newPing = System.currentTimeMillis();
- String message = new String(packet.getData(), 0, 0, packet.getLength());
- LOGGER.info("{} last seen since {}ms", message, (newPing - ping));
- if ((newPing - ping) > 3000) {
- // close everything here...
- }
- ping = newPing;
- }
- }
-
- @Override
- public void run() {
- LOGGER.info("launching child VM for " + name);
- launch();
-
- LOGGER.info("Monitoring VM for " + name);
- while (true) {
- monitor();
- }
- }
-}
diff --git a/server/sonar-process/src/main/java/org/sonar/process/MonitorService.java b/server/sonar-process/src/main/java/org/sonar/process/MonitorService.java
new file mode 100644
index 00000000000..ba4bf7936a5
--- /dev/null
+++ b/server/sonar-process/src/main/java/org/sonar/process/MonitorService.java
@@ -0,0 +1,81 @@
+package org.sonar.process;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.util.HashMap;
+import java.util.Map;
+
+public class MonitorService extends Thread {
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(ProcessWrapper.class);
+
+ final DatagramSocket socket;
+ final Map<String, Thread> processes;
+ final Map<String, Long> processesPing;
+
+ public MonitorService(DatagramSocket socket) {
+ this.socket = socket;
+ processes = new HashMap<String, Thread>();
+ processesPing = new HashMap<String, Long>();
+ }
+
+ public void register(ProcessWrapper process) {
+ this.processes.put(process.getName(), process);
+ this.processesPing.put(process.getName(), System.currentTimeMillis());
+ }
+
+ @Override
+ public void run() {
+ LOGGER.info("Launching Monitoring Thread");
+ long time = System.currentTimeMillis();
+ while (!currentThread().isInterrupted()) {
+ DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
+ try {
+ socket.setSoTimeout(200);
+ socket.receive(packet);
+ time = System.currentTimeMillis();
+ String message = new String(packet.getData());
+ long lastTime = processesPing.get(message);
+ processesPing.put(message, time);
+ LOGGER.info("{} last seen since {}ms", message, (time - lastTime));
+ } catch (Exception e) {
+ // Do nothing
+ }
+ if (!checkAllProcessPing(time)) {
+ break;
+ }
+ }
+ LOGGER.info("Some app has not been pinging");
+ for (Thread process : processes.values()) {
+ if (!process.isInterrupted()) {
+ process.interrupt();
+ }
+ }
+ }
+
+
+ private boolean checkAllProcessPing(long now) {
+
+ //check that all thread wrapper are running
+ for (Thread thread : processes.values()) {
+ if (thread.isInterrupted() || !thread.isAlive()) {
+ return false;
+ }
+ }
+
+ //check that all heartbeats are OK
+ for (Long ping : processesPing.values()) {
+ if ((now - ping) > 3000) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public Integer getMonitoringPort() {
+ return socket.getPort();
+ }
+}
diff --git a/server/sonar-process/src/main/java/org/sonar/process/Process.java b/server/sonar-process/src/main/java/org/sonar/process/Process.java
index b0adaf64431..f170eb393c3 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/Process.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/Process.java
@@ -28,9 +28,6 @@ import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
-/**
- * @Since 4.5
- */
public abstract class Process implements Runnable {
public static final String NAME_PROPERTY = "pName";
diff --git a/server/sonar-process/src/test/java/org/sonar/process/LauncherTest.java b/server/sonar-process/src/main/java/org/sonar/process/ProcessWrapper.java
index 22bdd9683a6..03190f0b440 100644
--- a/server/sonar-process/src/test/java/org/sonar/process/LauncherTest.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/ProcessWrapper.java
@@ -19,6 +19,28 @@
*/
package org.sonar.process;
-public class LauncherTest {
+import com.google.common.annotations.VisibleForTesting;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-} \ No newline at end of file
+public class ProcessWrapper extends Thread {
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(ProcessWrapper.class);
+
+ final String name;
+
+ @VisibleForTesting
+ ProcessWrapper(String name, Integer port) {
+ LOGGER.info("Creating Launcher for '{}' with base port: {}", name, port);
+ this.name = name;
+ }
+
+ public ProcessWrapper(String className, String[] classPath, String name, Integer port) {
+ LOGGER.info("Creating Launcher for '{}' with base port: {}", name, port);
+ this.name = name;
+ }
+
+ public void run() {
+
+ }
+}
diff --git a/server/sonar-process/src/test/java/org/sonar/process/MonitorServiceTest.java b/server/sonar-process/src/test/java/org/sonar/process/MonitorServiceTest.java
new file mode 100644
index 00000000000..4723c22a8e1
--- /dev/null
+++ b/server/sonar-process/src/test/java/org/sonar/process/MonitorServiceTest.java
@@ -0,0 +1,46 @@
+package org.sonar.process;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.DatagramSocket;
+
+public class MonitorServiceTest {
+
+
+ private DatagramSocket socket;
+
+ @Before
+ public void setUp() throws Exception {
+ socket = new DatagramSocket(0);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (socket != null && !socket.isClosed()) {
+ socket.close();
+ }
+ }
+
+ @Test
+ public void should_build() {
+ MonitorService monitor = new MonitorService(socket);
+ }
+
+ class LongProcessWrapper extends ProcessWrapper {
+
+ LongProcessWrapper(String name, Integer port) {
+ super(name, port);
+ }
+
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(10000L);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+} \ No newline at end of file