aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-11-22 16:34:08 +0100
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-11-24 09:23:58 +0100
commite09aed353ec5539a1e326e3f8c6bcf6be3dca727 (patch)
tree9f3fbd4ac657daf39598b53f650be5cfc62388cf /server
parent888854f9dd04feb372be60d249de2056d98d07c0 (diff)
downloadsonarqube-e09aed353ec5539a1e326e3f8c6bcf6be3dca727.tar.gz
sonarqube-e09aed353ec5539a1e326e3f8c6bcf6be3dca727.zip
SONAR-10112 add MBean to monitor queue and workers of AsyncExecution
Diffstat (limited to 'server')
-rw-r--r--server/sonar-ce/src/test/java/org/sonar/ce/async/SynchronousAsyncExecutionTest.java19
-rw-r--r--server/sonar-ce/src/test/java/org/sonar/ce/monitoring/CeTasksMBeanImplTest.java32
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionExecutorServiceImpl.java20
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionMBean.java31
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionMBeanImpl.java57
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionModule.java1
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionMonitoring.java28
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/async/AsyncExecutionMBeanImplTest.java87
8 files changed, 256 insertions, 19 deletions
diff --git a/server/sonar-ce/src/test/java/org/sonar/ce/async/SynchronousAsyncExecutionTest.java b/server/sonar-ce/src/test/java/org/sonar/ce/async/SynchronousAsyncExecutionTest.java
index 57f0a7163df..a8c6c4ee972 100644
--- a/server/sonar-ce/src/test/java/org/sonar/ce/async/SynchronousAsyncExecutionTest.java
+++ b/server/sonar-ce/src/test/java/org/sonar/ce/async/SynchronousAsyncExecutionTest.java
@@ -1,3 +1,22 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.ce.async;
import java.util.HashSet;
diff --git a/server/sonar-ce/src/test/java/org/sonar/ce/monitoring/CeTasksMBeanImplTest.java b/server/sonar-ce/src/test/java/org/sonar/ce/monitoring/CeTasksMBeanImplTest.java
index c161c86d5a8..da5997c3f00 100644
--- a/server/sonar-ce/src/test/java/org/sonar/ce/monitoring/CeTasksMBeanImplTest.java
+++ b/server/sonar-ce/src/test/java/org/sonar/ce/monitoring/CeTasksMBeanImplTest.java
@@ -52,6 +52,19 @@ public class CeTasksMBeanImplTest {
assertThat(getMBean()).isNull();
}
+ /**
+ * Dumb implementation of CEQueueStatus which returns constant values for get methods and throws UnsupportedOperationException
+ * for other methods.
+ */
+ @CheckForNull
+ private ObjectInstance getMBean() throws Exception {
+ try {
+ return ManagementFactory.getPlatformMBeanServer().getObjectInstance(new ObjectName(CeTasksMBean.OBJECT_NAME));
+ } catch (InstanceNotFoundException e) {
+ return null;
+ }
+ }
+
@Test
public void get_methods_delegate_to_the_CEQueueStatus_instance() {
assertThat(underTest.getPendingCount()).isEqualTo(PENDING_COUNT);
@@ -77,13 +90,9 @@ public class CeTasksMBeanImplTest {
assertThat(section.getName()).isEqualTo("Compute Engine Tasks");
assertThat(section.getAttributesCount()).isEqualTo(7);
}
-
- /**
- * Dumb implementation of CEQueueStatus which returns constant values for get methods and throws UnsupportedOperationException
- * for other methods.
- */
private static class DumbCEQueueStatus implements CEQueueStatus {
+
@Override
public long getPendingCount() {
return PENDING_COUNT;
@@ -123,13 +132,13 @@ public class CeTasksMBeanImplTest {
public long getProcessingTime() {
return PROCESSING_TIME;
}
-
private long methodNotImplemented() {
throw new UnsupportedOperationException("Not Implemented");
}
- }
+ }
private static class DumbCeConfiguration implements CeConfiguration {
+
@Override
public void refresh() {
throw new UnsupportedOperationException("Refresh is not implemented");
@@ -166,13 +175,4 @@ public class CeTasksMBeanImplTest {
}
}
-
- @CheckForNull
- private ObjectInstance getMBean() throws Exception {
- try {
- return ManagementFactory.getPlatformMBeanServer().getObjectInstance(new ObjectName(CeTasksMBean.OBJECT_NAME));
- } catch (InstanceNotFoundException e) {
- return null;
- }
- }
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionExecutorServiceImpl.java b/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionExecutorServiceImpl.java
index 60c87fc9fa6..f329d52ec40 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionExecutorServiceImpl.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionExecutorServiceImpl.java
@@ -20,7 +20,6 @@
package org.sonar.server.async;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
-import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import org.sonar.api.utils.log.Logger;
@@ -30,8 +29,8 @@ import org.sonar.server.util.AbstractStoppableExecutorService;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
public class AsyncExecutionExecutorServiceImpl
- extends AbstractStoppableExecutorService<ExecutorService>
- implements AsyncExecutionExecutorService {
+ extends AbstractStoppableExecutorService<ThreadPoolExecutor>
+ implements AsyncExecutionExecutorService, AsyncExecutionMonitoring {
private static final Logger LOG = Loggers.get(AsyncExecutionExecutorServiceImpl.class);
private static final int MIN_THREAD_COUNT = 1;
@@ -56,4 +55,19 @@ public class AsyncExecutionExecutorServiceImpl
public void addToQueue(Runnable r) {
this.submit(r);
}
+
+ @Override
+ public int getQueueSize() {
+ return delegate.getQueue().size();
+ }
+
+ @Override
+ public int getWorkerCount() {
+ return delegate.getPoolSize();
+ }
+
+ @Override
+ public int getLargestWorkerCount() {
+ return delegate.getLargestPoolSize();
+ }
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionMBean.java b/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionMBean.java
new file mode 100644
index 00000000000..08de7ef7a93
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionMBean.java
@@ -0,0 +1,31 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.async;
+
+public interface AsyncExecutionMBean {
+
+ String OBJECT_NAME = "SonarQube:name=AsyncExecution";
+
+ long getQueueSize();
+
+ long getWorkerCount();
+
+ long getLargestWorkerCount();
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionMBeanImpl.java b/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionMBeanImpl.java
new file mode 100644
index 00000000000..b562fa80f0b
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionMBeanImpl.java
@@ -0,0 +1,57 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.async;
+
+import org.picocontainer.Startable;
+import org.sonar.process.Jmx;
+
+public class AsyncExecutionMBeanImpl implements AsyncExecutionMBean, Startable {
+
+ private final AsyncExecutionMonitoring asyncExecutionMonitoring;
+
+ public AsyncExecutionMBeanImpl(AsyncExecutionMonitoring asyncExecutionMonitoring) {
+ this.asyncExecutionMonitoring = asyncExecutionMonitoring;
+ }
+
+ @Override
+ public void start() {
+ Jmx.register(OBJECT_NAME, this);
+ }
+
+ @Override
+ public void stop() {
+ Jmx.unregister(OBJECT_NAME);
+ }
+
+ @Override
+ public long getQueueSize() {
+ return asyncExecutionMonitoring.getQueueSize();
+ }
+
+ @Override
+ public long getWorkerCount() {
+ return asyncExecutionMonitoring.getWorkerCount();
+ }
+
+ @Override
+ public long getLargestWorkerCount() {
+ return asyncExecutionMonitoring.getLargestWorkerCount();
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionModule.java b/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionModule.java
index 1e5673c45ee..2d16d0bac76 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionModule.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionModule.java
@@ -25,6 +25,7 @@ public class AsyncExecutionModule extends Module {
@Override
protected void configureModule() {
add(
+ AsyncExecutionMBeanImpl.class,
AsyncExecutionExecutorServiceImpl.class,
AsyncExecutionImpl.class);
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionMonitoring.java b/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionMonitoring.java
new file mode 100644
index 00000000000..f65a5096f11
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/async/AsyncExecutionMonitoring.java
@@ -0,0 +1,28 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.async;
+
+public interface AsyncExecutionMonitoring {
+ int getQueueSize();
+
+ int getWorkerCount();
+
+ int getLargestWorkerCount();
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/async/AsyncExecutionMBeanImplTest.java b/server/sonar-server/src/test/java/org/sonar/server/async/AsyncExecutionMBeanImplTest.java
new file mode 100644
index 00000000000..d4cbeb34320
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/async/AsyncExecutionMBeanImplTest.java
@@ -0,0 +1,87 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.async;
+
+import java.lang.management.ManagementFactory;
+import javax.annotation.CheckForNull;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class AsyncExecutionMBeanImplTest {
+ private AsyncExecutionMonitoring asyncExecutionMonitoring = Mockito.mock(AsyncExecutionMonitoring.class);
+
+ private AsyncExecutionMBeanImpl underTest = new AsyncExecutionMBeanImpl(asyncExecutionMonitoring);
+
+ @Test
+ public void register_and_unregister() throws Exception {
+ assertThat(getMBean()).isNull();
+
+ underTest.start();
+ assertThat(getMBean()).isNotNull();
+
+ underTest.stop();
+ assertThat(getMBean()).isNull();
+ }
+
+ @Test
+ public void getQueueSize_delegates_to_AsyncExecutionMonitoring() {
+ when(asyncExecutionMonitoring.getQueueSize()).thenReturn(12);
+
+ assertThat(underTest.getQueueSize()).isEqualTo(12);
+
+ verify(asyncExecutionMonitoring).getQueueSize();
+ }
+
+ @Test
+ public void getWorkerCount_delegates_to_AsyncExecutionMonitoring() {
+ when(asyncExecutionMonitoring.getWorkerCount()).thenReturn(12);
+
+ assertThat(underTest.getWorkerCount()).isEqualTo(12);
+
+ verify(asyncExecutionMonitoring).getWorkerCount();
+ }
+
+ @Test
+ public void getLargestWorkerCount_delegates_to_AsyncExecutionMonitoring() {
+ when(asyncExecutionMonitoring.getLargestWorkerCount()).thenReturn(12);
+
+ assertThat(underTest.getLargestWorkerCount()).isEqualTo(12);
+
+ verify(asyncExecutionMonitoring).getLargestWorkerCount();
+ }
+
+ @CheckForNull
+ private ObjectInstance getMBean() throws Exception {
+ try {
+ return ManagementFactory.getPlatformMBeanServer().getObjectInstance(new ObjectName(AsyncExecutionMBean.OBJECT_NAME));
+ } catch (InstanceNotFoundException e) {
+ return null;
+ }
+ }
+
+
+}