aurora-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kevi...@apache.org
Subject incubator-aurora git commit: Service status endpoint.
Date Fri, 09 Jan 2015 18:58:48 GMT
Repository: incubator-aurora
Updated Branches:
  refs/heads/master c7afcf046 -> 74e54717a


Service status endpoint.

Service status endpoint for debugging.

Testing Done:
./gradlew -Pq build

Inspected output with ./gradlew run

```
% curl http://localhost:8081/services | python -m json.tool
[
    {
        "name": "TaskTimeout",
        "state": "RUNNING"
    },
    {
        "name": "JobUpdateHistoryPruner",
        "state": "RUNNING"
    },
    {
        "name": "TaskStatUpdaterService",
        "state": "RUNNING"
    },
    {
        "name": "SlotSizeCounterService",
        "state": "RUNNING"
    },
    {
        "name": "SlaUpdater",
        "state": "RUNNING"
    },
    {
        "name": "CronLifecycle",
        "state": "RUNNING"
    },
    {
        "name": "TaskVars",
        "state": "RUNNING"
    },
    {
        "name": "RegisterGauges",
        "state": "RUNNING"
    },
    {
        "name": "RegisterSubscribers",
        "state": "RUNNING"
    },
    {
        "name": "RedirectMonitor",
        "state": "RUNNING"
    }
]
```

Reviewed at https://reviews.apache.org/r/29731/


Project: http://git-wip-us.apache.org/repos/asf/incubator-aurora/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-aurora/commit/74e54717
Tree: http://git-wip-us.apache.org/repos/asf/incubator-aurora/tree/74e54717
Diff: http://git-wip-us.apache.org/repos/asf/incubator-aurora/diff/74e54717

Branch: refs/heads/master
Commit: 74e54717a6ac5a9376799763e499b91d8f93f6e4
Parents: c7afcf0
Author: Kevin Sweeney <kevints@apache.org>
Authored: Fri Jan 9 10:58:24 2015 -0800
Committer: Kevin Sweeney <kevints@apache.org>
Committed: Fri Jan 9 10:58:24 2015 -0800

----------------------------------------------------------------------
 src/main/java/org/apache/aurora/GuavaUtils.java | 10 +++
 .../aurora/scheduler/SchedulerLifecycle.java    |  2 +-
 .../scheduler/http/JettyServerModule.java       |  1 +
 .../apache/aurora/scheduler/http/Services.java  | 81 +++++++++++++++++++
 src/main/resources/scheduler/assets/index.html  |  1 +
 .../aurora/scheduler/http/ServicesTest.java     | 82 ++++++++++++++++++++
 6 files changed, 176 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/74e54717/src/main/java/org/apache/aurora/GuavaUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/GuavaUtils.java b/src/main/java/org/apache/aurora/GuavaUtils.java
index f3fa8cd..22104e6 100644
--- a/src/main/java/org/apache/aurora/GuavaUtils.java
+++ b/src/main/java/org/apache/aurora/GuavaUtils.java
@@ -16,6 +16,9 @@ package org.apache.aurora;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.util.concurrent.Service;
+import com.google.common.util.concurrent.Service.State;
 import com.google.common.util.concurrent.ServiceManager;
 
 /**
@@ -37,6 +40,8 @@ public final class GuavaUtils {
     ServiceManagerIface stopAsync();
 
     void awaitStopped(long timeout, TimeUnit unit) throws TimeoutException;
+
+    ImmutableMultimap<State, Service> servicesByState();
   }
 
   /**
@@ -68,6 +73,11 @@ public final class GuavaUtils {
       public void awaitStopped(long timeout, TimeUnit unit) throws TimeoutException {
         delegate.awaitStopped(timeout, unit);
       }
+
+      @Override
+      public ImmutableMultimap<State, Service> servicesByState() {
+        return delegate.servicesByState();
+      }
     };
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/74e54717/src/main/java/org/apache/aurora/scheduler/SchedulerLifecycle.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/SchedulerLifecycle.java b/src/main/java/org/apache/aurora/scheduler/SchedulerLifecycle.java
index e741913..b8830d1 100644
--- a/src/main/java/org/apache/aurora/scheduler/SchedulerLifecycle.java
+++ b/src/main/java/org/apache/aurora/scheduler/SchedulerLifecycle.java
@@ -476,5 +476,5 @@ public class SchedulerLifecycle implements EventSubscriber {
   @Qualifier
   @Retention(RetentionPolicy.RUNTIME)
   @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
-  static @interface SchedulerActive { }
+  public static @interface SchedulerActive { }
 }

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/74e54717/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java b/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java
index 8a7926b..8a59d89 100644
--- a/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/http/JettyServerModule.java
@@ -280,6 +280,7 @@ public class JettyServerModule extends AbstractModule {
               registerJerseyEndpoint("/offers", Offers.class);
               registerJerseyEndpoint("/pendingtasks", PendingTasks.class);
               registerJerseyEndpoint("/quotas", Quotas.class);
+              registerJerseyEndpoint("/services", Services.class);
               registerJerseyEndpoint("/slaves", Slaves.class);
               registerJerseyEndpoint("/structdump", StructDump.class);
               registerJerseyEndpoint("/utilization", Utilization.class);

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/74e54717/src/main/java/org/apache/aurora/scheduler/http/Services.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/http/Services.java b/src/main/java/org/apache/aurora/scheduler/http/Services.java
new file mode 100644
index 0000000..7183370
--- /dev/null
+++ b/src/main/java/org/apache/aurora/scheduler/http/Services.java
@@ -0,0 +1,81 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aurora.scheduler.http;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.util.concurrent.Service;
+import com.google.common.util.concurrent.Service.State;
+
+import org.apache.aurora.GuavaUtils.ServiceManagerIface;
+import org.apache.aurora.scheduler.AppStartup;
+import org.apache.aurora.scheduler.SchedulerLifecycle.SchedulerActive;
+
+/**
+ * Servlet to dump current status of services.
+ */
+@Path("/services")
+public final class Services {
+  private final ImmutableList<ServiceManagerIface> serviceManagers;
+
+  @Inject
+  Services(
+      @SchedulerActive ServiceManagerIface schedulerActiveServiceManager,
+      @AppStartup ServiceManagerIface appStartupServiceManager) {
+
+    serviceManagers = ImmutableList.of(schedulerActiveServiceManager, appStartupServiceManager);
+  }
+
+  private static final Function<Service, Map<String, Object>> SERVICE_TO_BEAN
=
+      new Function<Service, Map<String, Object>>() {
+        @Override
+        public Map<String, Object> apply(Service service) {
+          State state = service.state();
+          ImmutableMap.Builder<String, Object> bean = ImmutableMap.builder();
+          bean.put("name", service.getClass().getSimpleName());
+          bean.put("state", state);
+          if (state == State.FAILED) {
+            bean.put("failureCause", service.failureCause().toString());
+          }
+          return bean.build();
+        }
+      };
+
+  @GET
+  @Produces(MediaType.APPLICATION_JSON)
+  public Response getServices() {
+    return Response.ok()
+        .entity(FluentIterable.from(serviceManagers)
+            .transformAndConcat(new Function<ServiceManagerIface, Iterable<Service>>()
{
+              @Override
+              public Iterable<Service> apply(ServiceManagerIface input) {
+                return input.servicesByState().values();
+              }
+            })
+            .transform(SERVICE_TO_BEAN)
+            .toList())
+        .build();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/74e54717/src/main/resources/scheduler/assets/index.html
----------------------------------------------------------------------
diff --git a/src/main/resources/scheduler/assets/index.html b/src/main/resources/scheduler/assets/index.html
index 442f10b..d0bd897 100644
--- a/src/main/resources/scheduler/assets/index.html
+++ b/src/main/resources/scheduler/assets/index.html
@@ -24,6 +24,7 @@
   <a href='/pendingtasks'>/pendingtasks</a><br />
   <a href='/quotas'>/quotas</a><br />
   <a href='/scheduler'>/scheduler</a><br />
+  <a href='/services'>/services</a><br />
   <a href='/slaves'>/slaves</a><br />
   <a href='/structdump'>/structdump</a><br />
   <a href='/threads'>/threads</a><br />

http://git-wip-us.apache.org/repos/asf/incubator-aurora/blob/74e54717/src/test/java/org/apache/aurora/scheduler/http/ServicesTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/http/ServicesTest.java b/src/test/java/org/apache/aurora/scheduler/http/ServicesTest.java
new file mode 100644
index 0000000..006c2de
--- /dev/null
+++ b/src/test/java/org/apache/aurora/scheduler/http/ServicesTest.java
@@ -0,0 +1,82 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aurora.scheduler.http;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.util.concurrent.Service;
+import com.google.common.util.concurrent.Service.State;
+import com.twitter.common.testing.easymock.EasyMockTest;
+
+import org.apache.aurora.GuavaUtils.ServiceManagerIface;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.easymock.EasyMock.expect;
+import static org.junit.Assert.assertEquals;
+
+public class ServicesTest extends EasyMockTest {
+  private static final String FAILURE_CAUSE_REASON = "Fake failure";
+
+  private ServiceManagerIface startupServiceManager;
+  private ServiceManagerIface activeServicesManager;
+
+  private Services servicesServlet;
+
+  @Before
+  public void setUp() {
+    activeServicesManager = createMock(ServiceManagerIface.class);
+    startupServiceManager = createMock(ServiceManagerIface.class);
+
+    servicesServlet = new Services(activeServicesManager, startupServiceManager);
+  }
+
+  @Test
+  public void testGetServices() throws Exception {
+    Service newService = createMock(Service.class);
+    expect(newService.state()).andReturn(State.NEW);
+
+    Service failedService = createMock(Service.class);
+    expect(failedService.state()).andReturn(State.FAILED);
+    Exception failureCause = new Exception(FAILURE_CAUSE_REASON);
+    expect(failedService.failureCause()).andReturn(failureCause);
+
+    Service runningService = createMock(Service.class);
+    expect(runningService.state()).andReturn(State.RUNNING);
+
+    expect(startupServiceManager.servicesByState()).andReturn(
+        ImmutableMultimap.of(
+            State.RUNNING, runningService,
+            State.FAILED, failedService));
+    expect(activeServicesManager.servicesByState())
+        .andReturn(ImmutableMultimap.of(State.NEW, newService));
+
+    control.replay();
+
+    assertEquals(
+        ImmutableList.of(
+            ImmutableMap.of(
+                "name", newService.getClass().getSimpleName(),
+                "state", State.NEW),
+            ImmutableMap.of(
+                "name", failedService.getClass().getSimpleName(),
+                "state", State.RUNNING),
+            ImmutableMap.of(
+                "name", failedService.getClass().getSimpleName(),
+                "state", State.FAILED,
+                "failureCause", failureCause.toString())),
+        servicesServlet.getServices().getEntity());
+  }
+}


Mime
View raw message