summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--application-model/src/main/java/com/yahoo/vespa/applicationmodel/ServiceStatusInfo.java16
-rw-r--r--orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/ApplicationReferenceList.java21
-rw-r--r--orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/UrlReference.java18
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/ApplicationServices.java16
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/HealthResource.java84
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/ServiceResource.java25
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/health/ApplicationHealthMonitor.java40
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthEndpoint.java2
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthMonitorManager.java22
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthEndpoint.java2
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthModel.java21
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthUpdater.java9
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/manager/HealthMonitorApi.java21
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/model/ApplicationInstanceGenerator.java1
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceId.java (renamed from service-monitor/src/main/java/com/yahoo/vespa/service/model/ServiceId.java)2
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/health/ApplicationHealthMonitorTest.java2
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthModelTest.java2
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthMonitorTest.java2
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthUpdaterTest.java2
19 files changed, 275 insertions, 33 deletions
diff --git a/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ServiceStatusInfo.java b/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ServiceStatusInfo.java
index da2b1bb6ad8..e781195eb2a 100644
--- a/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ServiceStatusInfo.java
+++ b/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ServiceStatusInfo.java
@@ -17,21 +17,29 @@ public class ServiceStatusInfo {
private final Optional<Instant> since;
private final Optional<Instant> lastChecked;
private final Optional<String> error;
+ private final Optional<String> endpoint;
public ServiceStatusInfo(ServiceStatus status) {
- this(status, Optional.empty(), Optional.empty(), Optional.empty());
+ this(status, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty());
}
- public ServiceStatusInfo(ServiceStatus status, Instant since, Instant lastChecked, Optional<String> error) {
- this(status, Optional.of(since), Optional.of(lastChecked), error);
+ public ServiceStatusInfo(ServiceStatus status, Instant since, Instant lastChecked, Optional<String> error,
+ Optional<String> endpoint) {
+ this(status, Optional.of(since), Optional.of(lastChecked), error, endpoint);
}
public ServiceStatusInfo(ServiceStatus status, Optional<Instant> since, Optional<Instant> lastChecked,
- Optional<String> error) {
+ Optional<String> error, Optional<String> endpoint) {
this.status = status;
this.since = since;
this.lastChecked = lastChecked;
this.error = error;
+ this.endpoint = endpoint;
+ }
+
+ @JsonProperty("endpoint")
+ public String endpointOrNull() {
+ return endpoint.orElse(null);
}
@JsonProperty("serviceStatus")
diff --git a/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/ApplicationReferenceList.java b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/ApplicationReferenceList.java
new file mode 100644
index 00000000000..c0d7af89bd5
--- /dev/null
+++ b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/ApplicationReferenceList.java
@@ -0,0 +1,21 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.orchestrator.restapi.wire;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * A list of references to applications.
+ *
+ * @author hakonhall
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ApplicationReferenceList {
+ @JsonProperty("applications")
+ public List<UrlReference> applicationList = Collections.emptyList();
+}
diff --git a/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/UrlReference.java b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/UrlReference.java
new file mode 100644
index 00000000000..6d59b48a1fe
--- /dev/null
+++ b/orchestrator-restapi/src/main/java/com/yahoo/vespa/orchestrator/restapi/wire/UrlReference.java
@@ -0,0 +1,18 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.orchestrator.restapi.wire;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * A reference to a REST resource.
+ *
+ * @author hakonhall
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class UrlReference {
+ @JsonProperty("url")
+ public String url;
+}
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/ApplicationServices.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/ApplicationServices.java
new file mode 100644
index 00000000000..0601291d853
--- /dev/null
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/ApplicationServices.java
@@ -0,0 +1,16 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.orchestrator.resources;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.List;
+
+/**
+ * @author hakonhall
+ */
+@JsonInclude(value = JsonInclude.Include.NON_NULL)
+public class ApplicationServices {
+ @JsonProperty("services")
+ public List<ServiceResource> services;
+}
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/HealthResource.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/HealthResource.java
new file mode 100644
index 00000000000..47f2f063540
--- /dev/null
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/HealthResource.java
@@ -0,0 +1,84 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.orchestrator.resources;
+
+import com.google.inject.Inject;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.container.jaxrs.annotation.Component;
+import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
+import com.yahoo.vespa.orchestrator.restapi.wire.ApplicationReferenceList;
+import com.yahoo.vespa.orchestrator.restapi.wire.UrlReference;
+import com.yahoo.vespa.service.manager.HealthMonitorApi;
+import com.yahoo.vespa.service.monitor.ServiceId;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriInfo;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * @author hakonhall
+ */
+@Path("/v1/health")
+public class HealthResource {
+ private final UriInfo uriInfo;
+ private final HealthMonitorApi healthMonitorApi;
+
+ @Inject
+ public HealthResource(@Context UriInfo uriInfo, @Component HealthMonitorApi healthMonitorApi) {
+ this.uriInfo = uriInfo;
+ this.healthMonitorApi = healthMonitorApi;
+ }
+
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ public ApplicationReferenceList getAllInstances() {
+ List<ApplicationId> applications = new ArrayList<>(healthMonitorApi.getMonitoredApplicationIds());
+ applications.sort(Comparator.comparing(ApplicationId::serializedForm));
+
+ ApplicationReferenceList list = new ApplicationReferenceList();
+ list.applicationList = applications.stream().map(applicationId -> {
+ UrlReference reference = new UrlReference();
+ reference.url = uriInfo.getBaseUriBuilder()
+ .path(HealthResource.class)
+ .path(applicationId.serializedForm())
+ .build()
+ .toString();
+ return reference;
+ }).collect(Collectors.toList());
+
+ return list;
+ }
+
+ @GET
+ @Path("/{applicationId}")
+ @Produces(MediaType.APPLICATION_JSON)
+ public ApplicationServices getInstance(@PathParam("applicationId") String applicationIdString) {
+ ApplicationId applicationId = ApplicationId.fromSerializedForm(applicationIdString);
+
+ Map<ServiceId, ServiceStatusInfo> services = healthMonitorApi.getServices(applicationId);
+
+ List<ServiceResource> serviceResources = services.entrySet().stream().map(entry -> {
+ ServiceResource serviceResource = new ServiceResource();
+ serviceResource.clusterId = entry.getKey().getClusterId();
+ serviceResource.serviceType = entry.getKey().getServiceType();
+ serviceResource.configId = entry.getKey().getConfigId();
+ serviceResource.serviceStatusInfo = entry.getValue();
+ return serviceResource;
+ })
+ .sorted(Comparator.comparing(resource -> resource.serviceType.s()))
+ .collect(Collectors.toList());
+
+ ApplicationServices applicationServices = new ApplicationServices();
+ applicationServices.services = serviceResources;
+ return applicationServices;
+ }
+
+}
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/ServiceResource.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/ServiceResource.java
new file mode 100644
index 00000000000..7823f3ca6cd
--- /dev/null
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/ServiceResource.java
@@ -0,0 +1,25 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.orchestrator.resources;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.yahoo.vespa.applicationmodel.ClusterId;
+import com.yahoo.vespa.applicationmodel.ConfigId;
+import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
+import com.yahoo.vespa.applicationmodel.ServiceType;
+
+/**
+ * @author hakonhall
+ */
+public class ServiceResource {
+ @JsonProperty("clusterId")
+ public ClusterId clusterId;
+
+ @JsonProperty("serviceType")
+ public ServiceType serviceType;
+
+ @JsonProperty("configId")
+ public ConfigId configId;
+
+ @JsonProperty("status")
+ public ServiceStatusInfo serviceStatusInfo;
+}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/health/ApplicationHealthMonitor.java b/service-monitor/src/main/java/com/yahoo/vespa/service/health/ApplicationHealthMonitor.java
index e728d1ea914..873baeae710 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/health/ApplicationHealthMonitor.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/health/ApplicationHealthMonitor.java
@@ -8,13 +8,14 @@ import com.yahoo.vespa.applicationmodel.ConfigId;
import com.yahoo.vespa.applicationmodel.ServiceStatus;
import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
import com.yahoo.vespa.applicationmodel.ServiceType;
-import com.yahoo.vespa.service.model.ServiceId;
+import com.yahoo.vespa.service.monitor.ServiceId;
import com.yahoo.vespa.service.monitor.ServiceStatusProvider;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
/**
* Responsible for monitoring a whole application using /state/v1/health.
@@ -24,6 +25,10 @@ import java.util.Set;
class ApplicationHealthMonitor implements ServiceStatusProvider, AutoCloseable {
private final ApplicationId applicationId;
private final StateV1HealthModel healthModel;
+
+ // Guards against concurrent access to monitors field w/objects in 1. monitor() (called from e.g. DuperModel),
+ // 2. getStatus() called from caching layer and Orchestrator above, and 3. REST calls to getAllServiceStatuses().
+ private final Object guard = new Object();
private final Map<ServiceId, HealthMonitor> monitors = new HashMap<>();
ApplicationHealthMonitor(ApplicationId applicationId, StateV1HealthModel healthModel) {
@@ -38,13 +43,15 @@ class ApplicationHealthMonitor implements ServiceStatusProvider, AutoCloseable {
Map<ServiceId, HealthEndpoint> endpoints = healthModel.extractHealthEndpoints(applicationInfo);
- // Remove obsolete monitors
- Set<ServiceId> removed = new HashSet<>(monitors.keySet());
- removed.removeAll(endpoints.keySet());
- removed.stream().map(monitors::remove).forEach(HealthMonitor::close);
+ synchronized (guard) {
+ // Remove obsolete monitors
+ Set<ServiceId> removed = new HashSet<>(monitors.keySet());
+ removed.removeAll(endpoints.keySet());
+ removed.stream().map(monitors::remove).forEach(HealthMonitor::close);
- // Add new monitors.
- endpoints.forEach((serviceId, endpoint) -> monitors.computeIfAbsent(serviceId, ignoredId -> endpoint.startMonitoring()));
+ // Add new monitors.
+ endpoints.forEach((serviceId, endpoint) -> monitors.computeIfAbsent(serviceId, ignoredId -> endpoint.startMonitoring()));
+ }
}
@Override
@@ -53,12 +60,23 @@ class ApplicationHealthMonitor implements ServiceStatusProvider, AutoCloseable {
ServiceType serviceType,
ConfigId configId) {
ServiceId serviceId = new ServiceId(applicationId, clusterId, serviceType, configId);
- HealthMonitor monitor = monitors.get(serviceId);
- if (monitor == null) {
- return new ServiceStatusInfo(ServiceStatus.NOT_CHECKED);
+
+ synchronized (guard) {
+ HealthMonitor monitor = monitors.get(serviceId);
+ if (monitor == null) {
+ return new ServiceStatusInfo(ServiceStatus.NOT_CHECKED);
+ }
+
+ return monitor.getStatus();
}
+ }
- return monitor.getStatus();
+ public Map<ServiceId, ServiceStatusInfo> getAllServiceStatuses() {
+ synchronized (guard) {
+ return monitors.entrySet().stream().collect(Collectors.toMap(
+ entry -> entry.getKey(),
+ entry -> entry.getValue().getStatus()));
+ }
}
@Override
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthEndpoint.java b/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthEndpoint.java
index 8c4997634a0..eae5ef3f284 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthEndpoint.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthEndpoint.java
@@ -1,7 +1,7 @@
// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.service.health;
-import com.yahoo.vespa.service.model.ServiceId;
+import com.yahoo.vespa.service.monitor.ServiceId;
/**
* An endpoint 1-1 with a service and that can be health monitored.
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthMonitorManager.java b/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthMonitorManager.java
index b802c6c5413..ad9a50f8127 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthMonitorManager.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthMonitorManager.java
@@ -14,9 +14,14 @@ import com.yahoo.vespa.flags.Flags;
import com.yahoo.vespa.service.duper.DuperModelManager;
import com.yahoo.vespa.service.duper.ZoneApplication;
import com.yahoo.vespa.service.executor.RunletExecutorImpl;
+import com.yahoo.vespa.service.manager.HealthMonitorApi;
import com.yahoo.vespa.service.manager.MonitorManager;
+import com.yahoo.vespa.service.monitor.ServiceId;
import java.time.Duration;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
@@ -24,7 +29,7 @@ import java.util.concurrent.ConcurrentHashMap;
*
* @author hakon
*/
-public class HealthMonitorManager implements MonitorManager {
+public class HealthMonitorManager implements MonitorManager, HealthMonitorApi {
// Weight the following against each other:
// - The number of threads N working on health checking
// - The health request timeout T
@@ -139,4 +144,19 @@ public class HealthMonitorManager implements MonitorManager {
return false;
}
+
+ @Override
+ public List<ApplicationId> getMonitoredApplicationIds() {
+ return Collections.list(healthMonitors.keys());
+ }
+
+ @Override
+ public Map<ServiceId, ServiceStatusInfo> getServices(ApplicationId applicationId) {
+ ApplicationHealthMonitor applicationHealthMonitor = healthMonitors.get(applicationId);
+ if (applicationHealthMonitor == null) {
+ return Collections.emptyMap();
+ }
+
+ return applicationHealthMonitor.getAllServiceStatuses();
+ }
}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthEndpoint.java b/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthEndpoint.java
index 8eca03c616f..73f0480bf96 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthEndpoint.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthEndpoint.java
@@ -3,7 +3,7 @@ package com.yahoo.vespa.service.health;
import com.yahoo.config.provision.HostName;
import com.yahoo.vespa.service.executor.RunletExecutor;
-import com.yahoo.vespa.service.model.ServiceId;
+import com.yahoo.vespa.service.monitor.ServiceId;
import java.net.URL;
import java.time.Duration;
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthModel.java b/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthModel.java
index 04943f81478..f015ecadbfc 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthModel.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthModel.java
@@ -6,10 +6,11 @@ import com.yahoo.config.model.api.HostInfo;
import com.yahoo.config.model.api.PortInfo;
import com.yahoo.config.model.api.ServiceInfo;
import com.yahoo.config.provision.HostName;
+import com.yahoo.vespa.service.duper.HostAdminApplication;
import com.yahoo.vespa.service.duper.ZoneApplication;
import com.yahoo.vespa.service.executor.RunletExecutor;
import com.yahoo.vespa.service.model.ApplicationInstanceGenerator;
-import com.yahoo.vespa.service.model.ServiceId;
+import com.yahoo.vespa.service.monitor.ServiceId;
import java.time.Duration;
import java.util.Arrays;
@@ -53,20 +54,26 @@ public class StateV1HealthModel implements AutoCloseable {
HostName hostname = HostName.from(hostInfo.getHostname());
for (ServiceInfo serviceInfo : hostInfo.getServices()) {
- if (monitorTenantHostHealth && isZoneApplication &&
- !ZoneApplication.isNodeAdminServiceInfo(application.getApplicationId(), serviceInfo)) {
- // Only the node admin/host admin cluster of the zone application should be monitored
- // TODO: Move the node admin cluster out to a separate infrastructure application
- continue;
+ boolean isNodeAdmin = false;
+ if (monitorTenantHostHealth && isZoneApplication) {
+ if (ZoneApplication.isNodeAdminServiceInfo(application.getApplicationId(), serviceInfo)) {
+ isNodeAdmin = true;
+ } else {
+ // Only the node admin/host admin cluster of the zone application should be monitored
+ // TODO: Move the node admin cluster out to a separate infrastructure application
+ continue;
+ }
}
ServiceId serviceId = ApplicationInstanceGenerator.getServiceId(application, serviceInfo);
for (PortInfo portInfo : serviceInfo.getPorts()) {
if (portInfo.getTags().containsAll(HTTP_HEALTH_PORT_TAGS)) {
+ // The host-admin-in-zone-application is one big hack.
+ int port = isNodeAdmin ? HostAdminApplication.HOST_ADMIN_HEALT_PORT : portInfo.getPort();
StateV1HealthEndpoint endpoint = new StateV1HealthEndpoint(
serviceId,
hostname,
- portInfo.getPort(),
+ port,
targetHealthStaleness,
requestTimeout,
connectionKeepAlive,
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthUpdater.java b/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthUpdater.java
index 972e81ce822..6a6768aa78b 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthUpdater.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthUpdater.java
@@ -13,15 +13,17 @@ import java.util.Optional;
* @author hakonhall
*/
class StateV1HealthUpdater implements HealthUpdater {
+ private final String endpoint;
private final StateV1HealthClient healthClient;
private volatile ServiceStatusInfo serviceStatusInfo = new ServiceStatusInfo(ServiceStatus.NOT_CHECKED);
StateV1HealthUpdater(URL url, Duration requestTimeout, Duration connectionKeepAlive) {
- this(new StateV1HealthClient(url, requestTimeout, connectionKeepAlive));
+ this(url.toString(), new StateV1HealthClient(url, requestTimeout, connectionKeepAlive));
}
- StateV1HealthUpdater(StateV1HealthClient healthClient) {
+ StateV1HealthUpdater(String endpoint, StateV1HealthClient healthClient) {
+ this.endpoint = endpoint;
this.healthClient = healthClient;
}
@@ -46,7 +48,8 @@ class StateV1HealthUpdater implements HealthUpdater {
Optional<Instant> newSince = newServiceStatus == serviceStatusInfo.serviceStatus() ?
serviceStatusInfo.since() : Optional.of(now);
- serviceStatusInfo = new ServiceStatusInfo(newServiceStatus, newSince, Optional.of(now), healthInfo.getErrorDescription());
+ serviceStatusInfo = new ServiceStatusInfo(newServiceStatus, newSince, Optional.of(now),
+ healthInfo.getErrorDescription(), Optional.of(endpoint));
}
@Override
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/manager/HealthMonitorApi.java b/service-monitor/src/main/java/com/yahoo/vespa/service/manager/HealthMonitorApi.java
new file mode 100644
index 00000000000..7bc22db93cd
--- /dev/null
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/manager/HealthMonitorApi.java
@@ -0,0 +1,21 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.service.manager;
+
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
+import com.yahoo.vespa.service.health.HealthMonitorManager;
+import com.yahoo.vespa.service.monitor.ServiceId;
+import com.yahoo.vespa.service.monitor.ServiceStatusProvider;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The API of {@link HealthMonitorManager} which is exported to other bundles (typically for REST).
+ *
+ * @author hakonhall
+ */
+public interface HealthMonitorApi extends ServiceStatusProvider {
+ List<ApplicationId> getMonitoredApplicationIds();
+ Map<ServiceId, ServiceStatusInfo> getServices(ApplicationId applicationId);
+}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/model/ApplicationInstanceGenerator.java b/service-monitor/src/main/java/com/yahoo/vespa/service/model/ApplicationInstanceGenerator.java
index 9e6b64f0c91..0a4e8e75adf 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/model/ApplicationInstanceGenerator.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/model/ApplicationInstanceGenerator.java
@@ -18,6 +18,7 @@ import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
import com.yahoo.vespa.applicationmodel.ServiceType;
import com.yahoo.vespa.applicationmodel.TenantId;
import com.yahoo.vespa.service.duper.ConfigServerApplication;
+import com.yahoo.vespa.service.monitor.ServiceId;
import com.yahoo.vespa.service.monitor.ServiceStatusProvider;
import java.util.HashMap;
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/model/ServiceId.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceId.java
index c0bcff7284c..a97cb1812c1 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/model/ServiceId.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceId.java
@@ -1,5 +1,5 @@
// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
-package com.yahoo.vespa.service.model;
+package com.yahoo.vespa.service.monitor;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.vespa.applicationmodel.ClusterId;
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/health/ApplicationHealthMonitorTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/health/ApplicationHealthMonitorTest.java
index 8861fa7db9f..2ad0eb8f67d 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/health/ApplicationHealthMonitorTest.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/health/ApplicationHealthMonitorTest.java
@@ -6,7 +6,7 @@ import com.yahoo.config.provision.HostName;
import com.yahoo.vespa.applicationmodel.ServiceStatus;
import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
import com.yahoo.vespa.service.duper.ConfigServerApplication;
-import com.yahoo.vespa.service.model.ServiceId;
+import com.yahoo.vespa.service.monitor.ServiceId;
import com.yahoo.vespa.service.monitor.ConfigserverUtil;
import org.junit.Test;
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthModelTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthModelTest.java
index b6b88b0c0d3..fcbc3cd9b9f 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthModelTest.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthModelTest.java
@@ -13,7 +13,7 @@ import com.yahoo.vespa.service.duper.TestZoneApplication;
import com.yahoo.vespa.service.duper.ZoneApplication;
import com.yahoo.vespa.service.executor.Cancellable;
import com.yahoo.vespa.service.executor.RunletExecutor;
-import com.yahoo.vespa.service.model.ServiceId;
+import com.yahoo.vespa.service.monitor.ServiceId;
import org.junit.Test;
import java.time.Duration;
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthMonitorTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthMonitorTest.java
index 533e5173ccc..e3fb7d08d93 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthMonitorTest.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthMonitorTest.java
@@ -17,7 +17,7 @@ public class StateV1HealthMonitorTest {
public void downThenUpThenDown() throws Exception {
StateV1HealthClient client = mock(StateV1HealthClient.class);
- StateV1HealthUpdater updater = new StateV1HealthUpdater(client);
+ StateV1HealthUpdater updater = new StateV1HealthUpdater("https://foo/state/v1/health", client);
RunletExecutor executor = new RunletExecutorImpl(2);
try (StateV1HealthMonitor monitor = new StateV1HealthMonitor(updater, executor, Duration.ofMillis(10))) {
assertEquals(ServiceStatus.NOT_CHECKED, monitor.getStatus().serviceStatus());
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthUpdaterTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthUpdaterTest.java
index b8f108a480e..a491307d6dc 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthUpdaterTest.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthUpdaterTest.java
@@ -165,6 +165,6 @@ public class StateV1HealthUpdaterTest {
private StateV1HealthUpdater makeUpdater(CloseableHttpClient client, Function<HttpEntity, String> getContentFunction) {
ApacheHttpClient apacheHttpClient = new ApacheHttpClient(url, client);
StateV1HealthClient healthClient = new StateV1HealthClient(apacheHttpClient, getContentFunction);
- return new StateV1HealthUpdater(healthClient);
+ return new StateV1HealthUpdater(url.toString(), healthClient);
}
} \ No newline at end of file