aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--application-model/src/main/java/com/yahoo/vespa/applicationmodel/ServiceInstance.java25
-rw-r--r--application-model/src/main/java/com/yahoo/vespa/applicationmodel/ServiceStatusInfo.java90
-rw-r--r--configserver/src/main/resources/configserver-app/services.xml1
-rw-r--r--orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/InstanceResource.java15
-rw-r--r--orchestrator/src/test/java/com/yahoo/vespa/orchestrator/model/ClusterApiImplTest.java9
-rw-r--r--orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/InstanceResourceTest.java16
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/health/ApplicationHealthMonitor.java11
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthInfo.java30
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthMonitor.java4
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthMonitorManager.java15
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthUpdater.java5
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthMonitor.java6
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthUpdater.java25
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/manager/UnionMonitorManager.java15
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/model/ApplicationInstanceGenerator.java9
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/model/ServiceMonitorImpl.java4
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceStatusProvider.java9
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/slobrok/SlobrokMonitorManagerImpl.java20
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/health/ApplicationHealthMonitorTest.java10
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/health/HealthMonitorManagerTest.java13
-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.java7
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/health/StateV1HealthUpdaterTest.java55
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/manager/UnionMonitorManagerTest.java7
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/model/ApplicationInstanceGeneratorTest.java3
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/model/ExampleModel.java3
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/model/ModelGeneratorTest.java3
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/slobrok/SlobrokMonitorManagerImplTest.java2
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/slobrok/SlobrokMonitorTest.java7
29 files changed, 265 insertions, 156 deletions
diff --git a/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ServiceInstance.java b/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ServiceInstance.java
index 80178f79bb1..b4fce878b0d 100644
--- a/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ServiceInstance.java
+++ b/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ServiceInstance.java
@@ -14,13 +14,17 @@ public class ServiceInstance {
private final ConfigId configId;
private final HostName hostName;
- private final ServiceStatus serviceStatus;
+ private final ServiceStatusInfo serviceStatusInfo;
private Optional<ServiceCluster> serviceCluster = Optional.empty();
public ServiceInstance(ConfigId configId, HostName hostName, ServiceStatus serviceStatus) {
+ this(configId, hostName, new ServiceStatusInfo(serviceStatus));
+ }
+
+ public ServiceInstance(ConfigId configId, HostName hostName, ServiceStatusInfo serviceStatusInfo) {
this.configId = configId;
this.hostName = hostName;
- this.serviceStatus = serviceStatus;
+ this.serviceStatusInfo = serviceStatusInfo;
}
@JsonProperty("configId")
@@ -33,9 +37,13 @@ public class ServiceInstance {
return hostName;
}
- @JsonProperty("serviceStatus")
public ServiceStatus serviceStatus() {
- return serviceStatus;
+ return serviceStatusInfo.serviceStatus();
+ }
+
+ @JsonProperty("serviceStatusInfo")
+ public ServiceStatusInfo serviceStatusInfo() {
+ return serviceStatusInfo;
}
@JsonIgnore
@@ -50,10 +58,11 @@ public class ServiceInstance {
@Override
public String toString() {
+ // serviceCluster omitted to avoid recursion
return "ServiceInstance{" +
"configId=" + configId +
", hostName=" + hostName +
- ", serviceStatus=" + serviceStatus +
+ ", serviceStatus=" + serviceStatusInfo +
'}';
}
@@ -62,13 +71,15 @@ public class ServiceInstance {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ServiceInstance that = (ServiceInstance) o;
+ // serviceCluster omitted to avoid recursion
return Objects.equals(configId, that.configId) &&
Objects.equals(hostName, that.hostName) &&
- serviceStatus == that.serviceStatus;
+ serviceStatusInfo == that.serviceStatusInfo;
}
@Override
public int hashCode() {
- return Objects.hash(configId, hostName, serviceStatus);
+ // serviceCluster omitted to avoid recursion
+ return Objects.hash(configId, hostName, serviceStatusInfo);
}
}
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
new file mode 100644
index 00000000000..da2b1bb6ad8
--- /dev/null
+++ b/application-model/src/main/java/com/yahoo/vespa/applicationmodel/ServiceStatusInfo.java
@@ -0,0 +1,90 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.applicationmodel;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.time.Instant;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * @author hakonhall
+ */
+@JsonInclude(value = JsonInclude.Include.NON_NULL)
+public class ServiceStatusInfo {
+ private final ServiceStatus status;
+ private final Optional<Instant> since;
+ private final Optional<Instant> lastChecked;
+ private final Optional<String> error;
+
+ public ServiceStatusInfo(ServiceStatus status) {
+ this(status, 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, Optional<Instant> since, Optional<Instant> lastChecked,
+ Optional<String> error) {
+ this.status = status;
+ this.since = since;
+ this.lastChecked = lastChecked;
+ this.error = error;
+ }
+
+ @JsonProperty("serviceStatus")
+ public ServiceStatus serviceStatus() {
+ return status;
+ }
+
+ /** The current service status was first seen at this time, and has since stayed constant. */
+ public Optional<Instant> since() {
+ return since;
+ }
+
+ @JsonProperty("since")
+ public Instant sinceOrNull() {
+ return since.orElse(null);
+ }
+
+ /** The last time the status was checked. */
+ public Optional<Instant> lastChecked() {
+ return lastChecked;
+ }
+
+ @JsonProperty("lastChecked")
+ public Instant lastCheckedOrNull() {
+ return lastChecked.orElse(null);
+ }
+
+ @JsonProperty("error")
+ public String errorOrNull() {
+ return error.orElse(null);
+ }
+
+ @Override
+ public String toString() {
+ return "ServiceStatusInfo{" +
+ "status=" + status +
+ ", since=" + since +
+ ", lastChecked=" + lastChecked +
+ '}';
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ServiceStatusInfo that = (ServiceStatusInfo) o;
+ return status == that.status &&
+ Objects.equals(since, that.since) &&
+ Objects.equals(lastChecked, that.lastChecked);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(status, since, lastChecked);
+ }
+}
diff --git a/configserver/src/main/resources/configserver-app/services.xml b/configserver/src/main/resources/configserver-app/services.xml
index c3f3e7b6fff..f22d3fe213f 100644
--- a/configserver/src/main/resources/configserver-app/services.xml
+++ b/configserver/src/main/resources/configserver-app/services.xml
@@ -64,6 +64,7 @@
<preprocess:include file='controller/container.xml' required='false' />
<component id="com.yahoo.vespa.service.slobrok.SlobrokMonitorManagerImpl" bundle="service-monitor" />
<component id="com.yahoo.vespa.service.health.HealthMonitorManager" bundle="service-monitor" />
+ <component id="com.yahoo.vespa.service.manager.UnionMonitorManager" bundle="service-monitor" />
<component id="com.yahoo.vespa.service.model.ServiceMonitorImpl" bundle="service-monitor" />
<component id="com.yahoo.vespa.service.duper.DuperModelManager" bundle="service-monitor" />
<component id="com.yahoo.vespa.orchestrator.ServiceMonitorInstanceLookupService" bundle="orchestrator" />
diff --git a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/InstanceResource.java b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/InstanceResource.java
index 6984389b688..cd20a01f6af 100644
--- a/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/InstanceResource.java
+++ b/orchestrator/src/main/java/com/yahoo/vespa/orchestrator/resources/InstanceResource.java
@@ -9,13 +9,15 @@ import com.yahoo.vespa.applicationmodel.ApplicationInstanceReference;
import com.yahoo.vespa.applicationmodel.ClusterId;
import com.yahoo.vespa.applicationmodel.ConfigId;
import com.yahoo.vespa.applicationmodel.HostName;
-import com.yahoo.vespa.applicationmodel.ServiceStatus;
+import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
import com.yahoo.vespa.applicationmodel.ServiceType;
import com.yahoo.vespa.orchestrator.InstanceLookupService;
import com.yahoo.vespa.orchestrator.OrchestratorUtil;
import com.yahoo.vespa.orchestrator.restapi.wire.SlobrokEntryResponse;
import com.yahoo.vespa.orchestrator.status.HostStatus;
import com.yahoo.vespa.orchestrator.status.StatusService;
+import com.yahoo.vespa.service.manager.MonitorManager;
+import com.yahoo.vespa.service.manager.UnionMonitorManager;
import com.yahoo.vespa.service.monitor.SlobrokApi;
import javax.inject.Inject;
@@ -50,15 +52,18 @@ public class InstanceResource {
private final StatusService statusService;
private final SlobrokApi slobrokApi;
+ private final MonitorManager rootManager;
private final InstanceLookupService instanceLookupService;
@Inject
public InstanceResource(@Component InstanceLookupService instanceLookupService,
@Component StatusService statusService,
- @Component SlobrokApi slobrokApi) {
+ @Component SlobrokApi slobrokApi,
+ @Component UnionMonitorManager rootManager) {
this.instanceLookupService = instanceLookupService;
this.statusService = statusService;
this.slobrokApi = slobrokApi;
+ this.rootManager = rootManager;
}
@GET
@@ -104,9 +109,9 @@ public class InstanceResource {
}
@GET
- @Path("/{instanceId}/serviceStatus")
+ @Path("/{instanceId}/serviceStatusInfo")
@Produces(MediaType.APPLICATION_JSON)
- public ServiceStatus getServiceStatus(
+ public ServiceStatusInfo getServiceStatus(
@PathParam("instanceId") String instanceId,
@QueryParam("clusterId") String clusterIdString,
@QueryParam("serviceType") String serviceTypeString,
@@ -130,7 +135,7 @@ public class InstanceResource {
ServiceType serviceType = new ServiceType(serviceTypeString);
ConfigId configId = new ConfigId(configIdString);
- return slobrokApi.getStatus(applicationId, clusterId, serviceType, configId);
+ return rootManager.getStatus(applicationId, clusterId, serviceType, configId);
}
static ApplicationInstanceReference parseInstanceId(String instanceIdString) {
diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/model/ClusterApiImplTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/model/ClusterApiImplTest.java
index ad1ce647a7c..8e11b85241f 100644
--- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/model/ClusterApiImplTest.java
+++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/model/ClusterApiImplTest.java
@@ -52,9 +52,12 @@ public class ClusterApiImplTest {
assertEquals("{ clusterId=cluster, serviceType=service-type }", clusterApi.clusterInfo());
assertFalse(clusterApi.isStorageCluster());
- assertEquals("[ServiceInstance{configId=service-2, hostName=host2, serviceStatus=DOWN}, "
- + "ServiceInstance{configId=service-3, hostName=host3, serviceStatus=UP}, "
- + "ServiceInstance{configId=service-4, hostName=host4, serviceStatus=DOWN}]",
+ assertEquals("[ServiceInstance{configId=service-2, hostName=host2, serviceStatus=" +
+ "ServiceStatusInfo{status=DOWN, since=Optional.empty, lastChecked=Optional.empty}}, "
+ + "ServiceInstance{configId=service-3, hostName=host3, serviceStatus=" +
+ "ServiceStatusInfo{status=UP, since=Optional.empty, lastChecked=Optional.empty}}, "
+ + "ServiceInstance{configId=service-4, hostName=host4, serviceStatus=" +
+ "ServiceStatusInfo{status=DOWN, since=Optional.empty, lastChecked=Optional.empty}}]",
clusterApi.servicesDownAndNotInGroupDescription());
assertEquals("[host3, host4]",
clusterApi.nodesAllowedToBeDownNotInGroupDescription());
diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/InstanceResourceTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/InstanceResourceTest.java
index d7255327ba6..61102461bf0 100644
--- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/InstanceResourceTest.java
+++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/InstanceResourceTest.java
@@ -7,8 +7,10 @@ import com.yahoo.jrt.slobrok.api.Mirror;
import com.yahoo.vespa.applicationmodel.ClusterId;
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.orchestrator.restapi.wire.SlobrokEntryResponse;
+import com.yahoo.vespa.service.manager.UnionMonitorManager;
import com.yahoo.vespa.service.monitor.SlobrokApi;
import org.junit.Test;
@@ -31,10 +33,12 @@ public class InstanceResourceTest {
private static final ClusterId CLUSTER_ID = new ClusterId("cluster-id");
private final SlobrokApi slobrokApi = mock(SlobrokApi.class);
+ private final UnionMonitorManager rootManager = mock(UnionMonitorManager.class);
private final InstanceResource resource = new InstanceResource(
null,
null,
- slobrokApi);
+ slobrokApi,
+ rootManager);
@Test
public void testGetSlobrokEntries() throws Exception {
@@ -47,18 +51,18 @@ public class InstanceResourceTest {
}
@Test
- public void testGetServiceStatus() {
+ public void testGetServiceStatusInfo() {
ServiceType serviceType = new ServiceType("serviceType");
ConfigId configId = new ConfigId("configId");
ServiceStatus serviceStatus = ServiceStatus.UP;
- when(slobrokApi.getStatus(APPLICATION_ID, CLUSTER_ID, serviceType, configId))
- .thenReturn(serviceStatus);
+ when(rootManager.getStatus(APPLICATION_ID, CLUSTER_ID, serviceType, configId))
+ .thenReturn(new ServiceStatusInfo(serviceStatus));
ServiceStatus actualServiceStatus = resource.getServiceStatus(
APPLICATION_INSTANCE_REFERENCE,
CLUSTER_ID.s(),
serviceType.s(),
- configId.s());
- verify(slobrokApi).getStatus(APPLICATION_ID, CLUSTER_ID, serviceType, configId);
+ configId.s()).serviceStatus();
+ verify(rootManager).getStatus(APPLICATION_ID, CLUSTER_ID, serviceType, configId);
assertEquals(serviceStatus, actualServiceStatus);
}
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 5eac6fbb000..e728d1ea914 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
@@ -6,6 +6,7 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.vespa.applicationmodel.ClusterId;
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.ServiceStatusProvider;
@@ -47,14 +48,14 @@ class ApplicationHealthMonitor implements ServiceStatusProvider, AutoCloseable {
}
@Override
- public ServiceStatus getStatus(ApplicationId applicationId,
- ClusterId clusterId,
- ServiceType serviceType,
- ConfigId configId) {
+ public ServiceStatusInfo getStatus(ApplicationId applicationId,
+ ClusterId clusterId,
+ ServiceType serviceType,
+ ConfigId configId) {
ServiceId serviceId = new ServiceId(applicationId, clusterId, serviceType, configId);
HealthMonitor monitor = monitors.get(serviceId);
if (monitor == null) {
- return ServiceStatus.NOT_CHECKED;
+ return new ServiceStatusInfo(ServiceStatus.NOT_CHECKED);
}
return monitor.getStatus();
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthInfo.java b/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthInfo.java
index 17d9e6b7b49..17670c705d8 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthInfo.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthInfo.java
@@ -1,10 +1,8 @@
// 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.applicationmodel.ServiceStatus;
import com.yahoo.yolean.Exceptions;
-import java.time.Instant;
import java.util.Optional;
import java.util.OptionalInt;
@@ -19,7 +17,6 @@ public class HealthInfo {
private final Optional<Exception> exception;
private final OptionalInt httpStatusCode;
private final Optional<String> healthStatusCode;
- private final Instant time;
static HealthInfo fromException(Exception exception) {
return new HealthInfo(Optional.of(exception), OptionalInt.empty(), Optional.empty());
@@ -33,39 +30,18 @@ public class HealthInfo {
return new HealthInfo(Optional.empty(), OptionalInt.empty(), Optional.of(healthStatusCode));
}
- static HealthInfo empty() {
- return new HealthInfo(Optional.empty(), OptionalInt.empty(), Optional.empty());
- }
-
- private HealthInfo(Optional<Exception> exception,
- OptionalInt httpStatusCode,
- Optional<String> healthStatusCode) {
+ private HealthInfo(Optional<Exception> exception, OptionalInt httpStatusCode, Optional<String> healthStatusCode) {
this.exception = exception;
this.httpStatusCode = httpStatusCode;
this.healthStatusCode = healthStatusCode;
- this.time = Instant.now();
}
public boolean isHealthy() {
return healthStatusCode.map(UP_STATUS_CODE::equals).orElse(false);
}
- public ServiceStatus toServiceStatus() {
- // Bootstrapping ServiceStatus: To avoid thundering herd problem at startup,
- // the clients will not fetch the health immediately. What should the ServiceStatus
- // be before the first health has been fetched?
- //
- // NOT_CHECKED: Logically the right thing, but if an Orchestrator gets a suspend request
- // in this window, and another service within the cluster is down, it ends up allowing
- // suspension when it shouldn't have done so.
- //
- // DOWN: Only safe initial value, possibly except if the first initial delay is long,
- // as that could indicate it has been down for too long.
- return isHealthy() ? ServiceStatus.UP : ServiceStatus.DOWN;
- }
-
- public Instant time() {
- return time;
+ public Optional<String> getErrorDescription() {
+ return isHealthy() ? Optional.empty() : Optional.of(toString());
}
@Override
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthMonitor.java b/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthMonitor.java
index f0e13548f58..14ec977c98c 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthMonitor.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthMonitor.java
@@ -1,13 +1,13 @@
// 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.applicationmodel.ServiceStatus;
+import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
/**
* @author hakonhall
*/
interface HealthMonitor extends AutoCloseable {
- ServiceStatus getStatus();
+ ServiceStatusInfo getStatus();
@Override
void close();
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 ddfbdf59b3c..b802c6c5413 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
@@ -7,6 +7,7 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.vespa.applicationmodel.ClusterId;
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.flags.FlagSource;
import com.yahoo.vespa.flags.Flags;
@@ -97,20 +98,20 @@ public class HealthMonitorManager implements MonitorManager {
}
@Override
- public ServiceStatus getStatus(ApplicationId applicationId,
- ClusterId clusterId,
- ServiceType serviceType,
- ConfigId configId) {
+ public ServiceStatusInfo getStatus(ApplicationId applicationId,
+ ClusterId clusterId,
+ ServiceType serviceType,
+ ConfigId configId) {
ApplicationHealthMonitor monitor = healthMonitors.get(applicationId);
if (!monitorTenantHostHealth && ZoneApplication.isNodeAdminService(applicationId, clusterId, serviceType)) {
// Legacy: The zone app is not health monitored (monitor == null), but the node-admin cluster's services
// are hard-coded to be UP
- return ServiceStatus.UP;
+ return new ServiceStatusInfo(ServiceStatus.UP);
}
if (monitor == null) {
- return ServiceStatus.NOT_CHECKED;
+ return new ServiceStatusInfo(ServiceStatus.NOT_CHECKED);
}
if (monitorTenantHostHealth && applicationId.equals(ZoneApplication.getApplicationId())) {
@@ -120,7 +121,7 @@ public class HealthMonitorManager implements MonitorManager {
if (ZoneApplication.isNodeAdminService(applicationId, clusterId, serviceType)) {
return monitor.getStatus(applicationId, clusterId, serviceType, configId);
} else {
- return ServiceStatus.NOT_CHECKED;
+ return new ServiceStatusInfo(ServiceStatus.NOT_CHECKED);
}
}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthUpdater.java b/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthUpdater.java
index 4ed49e17e9f..8101336c638 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthUpdater.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/health/HealthUpdater.java
@@ -1,14 +1,15 @@
// 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.applicationmodel.ServiceStatusInfo;
import com.yahoo.vespa.service.executor.Runlet;
/**
* A {@link HealthUpdater} will probe the health with {@link #run()}, whose result can be fetched with the
- * thread-safe method {@link #getLatestHealthInfo()}.
+ * thread-safe method {@link #getServiceStatusInfo()}.
*
* @author hakonhall
*/
interface HealthUpdater extends Runlet {
- HealthInfo getLatestHealthInfo();
+ ServiceStatusInfo getServiceStatusInfo();
}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthMonitor.java b/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthMonitor.java
index d37797c7be9..7a6494e0122 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthMonitor.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/health/StateV1HealthMonitor.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.applicationmodel.ServiceStatus;
+import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
import com.yahoo.vespa.service.executor.Cancellable;
import com.yahoo.vespa.service.executor.RunletExecutor;
@@ -22,8 +22,8 @@ class StateV1HealthMonitor implements HealthMonitor {
}
@Override
- public ServiceStatus getStatus() {
- return updater.getLatestHealthInfo().toServiceStatus();
+ public ServiceStatusInfo getStatus() {
+ return updater.getServiceStatusInfo();
}
@Override
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 011ec3b3212..972e81ce822 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
@@ -1,8 +1,13 @@
// 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.applicationmodel.ServiceStatus;
+import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
+
import java.net.URL;
import java.time.Duration;
+import java.time.Instant;
+import java.util.Optional;
/**
* @author hakonhall
@@ -10,7 +15,7 @@ import java.time.Duration;
class StateV1HealthUpdater implements HealthUpdater {
private final StateV1HealthClient healthClient;
- private volatile HealthInfo lastHealthInfo = HealthInfo.empty();
+ private volatile ServiceStatusInfo serviceStatusInfo = new ServiceStatusInfo(ServiceStatus.NOT_CHECKED);
StateV1HealthUpdater(URL url, Duration requestTimeout, Duration connectionKeepAlive) {
this(new StateV1HealthClient(url, requestTimeout, connectionKeepAlive));
@@ -21,17 +26,27 @@ class StateV1HealthUpdater implements HealthUpdater {
}
@Override
- public HealthInfo getLatestHealthInfo() {
- return lastHealthInfo;
+ public ServiceStatusInfo getServiceStatusInfo() {
+ return serviceStatusInfo;
}
@Override
public void run() {
+ // Get time before fetching rather than after, to make the resulting age be an upper limit.
+ Instant now = Instant.now();
+
+ HealthInfo healthInfo;
try {
- lastHealthInfo = healthClient.get();
+ healthInfo = healthClient.get();
} catch (Exception e) {
- lastHealthInfo = HealthInfo.fromException(e);
+ healthInfo = HealthInfo.fromException(e);
}
+
+ ServiceStatus newServiceStatus = healthInfo.isHealthy() ? ServiceStatus.UP : ServiceStatus.DOWN;
+ Optional<Instant> newSince = newServiceStatus == serviceStatusInfo.serviceStatus() ?
+ serviceStatusInfo.since() : Optional.of(now);
+
+ serviceStatusInfo = new ServiceStatusInfo(newServiceStatus, newSince, Optional.of(now), healthInfo.getErrorDescription());
}
@Override
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/manager/UnionMonitorManager.java b/service-monitor/src/main/java/com/yahoo/vespa/service/manager/UnionMonitorManager.java
index cfd9269d9c4..3490ad4a5d2 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/manager/UnionMonitorManager.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/manager/UnionMonitorManager.java
@@ -1,11 +1,13 @@
// 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.manager;
+import com.google.inject.Inject;
import com.yahoo.config.model.api.ApplicationInfo;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.vespa.applicationmodel.ClusterId;
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.health.HealthMonitorManager;
import com.yahoo.vespa.service.slobrok.SlobrokMonitorManagerImpl;
@@ -17,19 +19,20 @@ public class UnionMonitorManager implements MonitorManager {
private final SlobrokMonitorManagerImpl slobrokMonitorManager;
private final HealthMonitorManager healthMonitorManager;
+ @Inject
public UnionMonitorManager(SlobrokMonitorManagerImpl slobrokMonitorManager, HealthMonitorManager healthMonitorManager) {
this.slobrokMonitorManager = slobrokMonitorManager;
this.healthMonitorManager = healthMonitorManager;
}
@Override
- public ServiceStatus getStatus(ApplicationId applicationId,
- ClusterId clusterId,
- ServiceType serviceType,
- ConfigId configId) {
+ public ServiceStatusInfo getStatus(ApplicationId applicationId,
+ ClusterId clusterId,
+ ServiceType serviceType,
+ ConfigId configId) {
// Trust the new health monitoring status if it actually monitors the particular service.
- ServiceStatus status = healthMonitorManager.getStatus(applicationId, clusterId, serviceType, configId);
- if (status != ServiceStatus.NOT_CHECKED) {
+ ServiceStatusInfo status = healthMonitorManager.getStatus(applicationId, clusterId, serviceType, configId);
+ if (status.serviceStatus() != ServiceStatus.NOT_CHECKED) {
return status;
}
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 3ca9446df26..9e6b64f0c91 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
@@ -14,7 +14,7 @@ import com.yahoo.vespa.applicationmodel.HostName;
import com.yahoo.vespa.applicationmodel.ServiceCluster;
import com.yahoo.vespa.applicationmodel.ServiceClusterKey;
import com.yahoo.vespa.applicationmodel.ServiceInstance;
-import com.yahoo.vespa.applicationmodel.ServiceStatus;
+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;
@@ -99,11 +99,8 @@ public class ApplicationInstanceGenerator {
HostName hostName,
ServiceStatusProvider serviceStatusProvider) {
ConfigId configId = toConfigId(serviceInfo);
-
- ServiceStatus status = serviceStatusProvider.getStatus(
- applicationId,
- clusterId,
- toServiceType(serviceInfo), configId);
+ ServiceType serviceType = toServiceType(serviceInfo);
+ ServiceStatusInfo status = serviceStatusProvider.getStatus(applicationId, clusterId, serviceType, configId);
return new ServiceInstance(configId, hostName, status);
}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/model/ServiceMonitorImpl.java b/service-monitor/src/main/java/com/yahoo/vespa/service/model/ServiceMonitorImpl.java
index cff98957590..50ea31eb9c4 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/model/ServiceMonitorImpl.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/model/ServiceMonitorImpl.java
@@ -21,12 +21,10 @@ public class ServiceMonitorImpl implements ServiceMonitor {
@Inject
public ServiceMonitorImpl(DuperModelManager duperModelManager,
- SlobrokMonitorManagerImpl slobrokMonitorManager,
- HealthMonitorManager healthMonitorManager,
+ UnionMonitorManager monitorManager,
Metric metric,
Timer timer,
Zone zone) {
- UnionMonitorManager monitorManager = new UnionMonitorManager(slobrokMonitorManager, healthMonitorManager);
duperModelManager.registerListener(monitorManager);
ServiceModelProvider uncachedServiceModelProvider = new ServiceModelProvider(
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceStatusProvider.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceStatusProvider.java
index 30a20cf9980..9486bf505ab 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceStatusProvider.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceStatusProvider.java
@@ -5,6 +5,7 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.vespa.applicationmodel.ClusterId;
import com.yahoo.vespa.applicationmodel.ConfigId;
import com.yahoo.vespa.applicationmodel.ServiceStatus;
+import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
import com.yahoo.vespa.applicationmodel.ServiceType;
/**
@@ -19,9 +20,9 @@ public interface ServiceStatusProvider {
* service status provider does does not monitor the service status for
* the particular application, cluster, service type, and config id.
*/
- ServiceStatus getStatus(ApplicationId applicationId,
- ClusterId clusterId,
- ServiceType serviceType,
- ConfigId configId);
+ ServiceStatusInfo getStatus(ApplicationId applicationId,
+ ClusterId clusterId,
+ ServiceType serviceType,
+ ConfigId configId);
}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/slobrok/SlobrokMonitorManagerImpl.java b/service-monitor/src/main/java/com/yahoo/vespa/service/slobrok/SlobrokMonitorManagerImpl.java
index 4e47bf010d7..203ad7266db 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/slobrok/SlobrokMonitorManagerImpl.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/slobrok/SlobrokMonitorManagerImpl.java
@@ -9,6 +9,7 @@ import com.yahoo.log.LogLevel;
import com.yahoo.vespa.applicationmodel.ClusterId;
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.duper.DuperModelManager;
import com.yahoo.vespa.service.manager.MonitorManager;
@@ -84,27 +85,26 @@ public class SlobrokMonitorManagerImpl implements SlobrokApi, MonitorManager {
}
@Override
- public ServiceStatus getStatus(ApplicationId applicationId,
- ClusterId clusterId,
- ServiceType serviceType,
- ConfigId configId) {
+ public ServiceStatusInfo getStatus(ApplicationId applicationId,
+ ClusterId clusterId,
+ ServiceType serviceType,
+ ConfigId configId) {
if (!wouldMonitor(applicationId)) {
- return ServiceStatus.NOT_CHECKED;
+ return new ServiceStatusInfo(ServiceStatus.NOT_CHECKED);
}
Optional<String> slobrokServiceName = findSlobrokServiceName(serviceType, configId);
if (slobrokServiceName.isPresent()) {
synchronized (monitor) {
SlobrokMonitor slobrokMonitor = slobrokMonitors.get(applicationId);
- if (slobrokMonitor != null &&
- slobrokMonitor.registeredInSlobrok(slobrokServiceName.get())) {
- return ServiceStatus.UP;
+ if (slobrokMonitor != null && slobrokMonitor.registeredInSlobrok(slobrokServiceName.get())) {
+ return new ServiceStatusInfo(ServiceStatus.UP);
} else {
- return ServiceStatus.DOWN;
+ return new ServiceStatusInfo(ServiceStatus.DOWN);
}
}
} else {
- return ServiceStatus.NOT_CHECKED;
+ return new ServiceStatusInfo(ServiceStatus.NOT_CHECKED);
}
}
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 821f5282998..8861fa7db9f 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
@@ -4,6 +4,7 @@ package com.yahoo.vespa.service.health;
import com.yahoo.config.model.api.ApplicationInfo;
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.ConfigserverUtil;
@@ -47,9 +48,9 @@ public class ApplicationHealthMonitorTest {
verify(endpoint1, times(1)).startMonitoring();
verify(endpoint2, times(1)).startMonitoring();
- when(monitor1.getStatus()).thenReturn(ServiceStatus.UP);
- when(monitor2.getStatus()).thenReturn(ServiceStatus.DOWN);
- when(monitor3.getStatus()).thenReturn(ServiceStatus.UP);
+ when(monitor1.getStatus()).thenReturn(new ServiceStatusInfo(ServiceStatus.UP));
+ when(monitor2.getStatus()).thenReturn(new ServiceStatusInfo(ServiceStatus.DOWN));
+ when(monitor3.getStatus()).thenReturn(new ServiceStatusInfo(ServiceStatus.UP));
assertEquals(ServiceStatus.UP, getStatus(applicationMonitor, "cfg1"));
assertEquals(ServiceStatus.DOWN, getStatus(applicationMonitor, "cfg2"));
@@ -94,6 +95,7 @@ public class ApplicationHealthMonitorTest {
configServerApplication.getApplicationId(),
configServerApplication.getClusterId(),
configServerApplication.getServiceType(),
- configServerApplication.configIdFor(HostName.from(hostname)));
+ configServerApplication.configIdFor(HostName.from(hostname)))
+ .serviceStatus();
}
} \ No newline at end of file
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/health/HealthMonitorManagerTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/health/HealthMonitorManagerTest.java
index 6e18bebf791..0c0a644165d 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/health/HealthMonitorManagerTest.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/health/HealthMonitorManagerTest.java
@@ -5,6 +5,7 @@ import com.yahoo.config.model.api.ApplicationInfo;
import com.yahoo.config.provision.HostName;
import com.yahoo.vespa.applicationmodel.ConfigId;
import com.yahoo.vespa.applicationmodel.ServiceStatus;
+import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
import com.yahoo.vespa.service.duper.ConfigServerApplication;
import com.yahoo.vespa.service.duper.ControllerHostApplication;
import com.yahoo.vespa.service.duper.DuperModelManager;
@@ -62,7 +63,7 @@ public class HealthMonitorManagerTest {
ZoneApplication.getApplicationId(),
ZoneApplication.getNodeAdminClusterId(),
ZoneApplication.getNodeAdminServiceType(),
- new ConfigId("config-id-1"));
+ new ConfigId("config-id-1")).serviceStatus();
assertEquals(ServiceStatus.UP, status);
}
@@ -91,7 +92,7 @@ public class HealthMonitorManagerTest {
verify(monitorFactory, times(isMonitored ? 1 : 0)).create(zoneApplicationInfo.getApplicationId());
verify(monitor, times(isMonitored ? 1 : 0)).monitor(any());
- when(monitor.getStatus(any(), any(), any(), any())).thenReturn(ServiceStatus.DOWN);
+ when(monitor.getStatus(any(), any(), any(), any())).thenReturn(new ServiceStatusInfo(ServiceStatus.DOWN));
verifyNodeAdminGetStatus(0);
if (isMonitored) {
assertEquals(ServiceStatus.DOWN, getNodeAdminStatus());
@@ -127,7 +128,7 @@ public class HealthMonitorManagerTest {
ZoneApplication.getApplicationId(),
ZoneApplication.getNodeAdminClusterId(),
ZoneApplication.getNodeAdminServiceType(),
- new ConfigId("foo"));
+ new ConfigId("foo")).serviceStatus();
}
private ServiceStatus getRoutingStatus() {
@@ -135,7 +136,7 @@ public class HealthMonitorManagerTest {
ZoneApplication.getApplicationId(),
ZoneApplication.getRoutingClusterId(),
ZoneApplication.getRoutingServiceType(),
- new ConfigId("bar"));
+ new ConfigId("bar")).serviceStatus();
}
@Test
@@ -149,7 +150,7 @@ public class HealthMonitorManagerTest {
manager.applicationActivated(proxyHostApplicationInfo);
verify(monitorFactory, times(1)).create(proxyHostApplicationInfo.getApplicationId());
- when(monitor.getStatus(any(), any(), any(), any())).thenReturn(ServiceStatus.UP);
+ when(monitor.getStatus(any(), any(), any(), any())).thenReturn(new ServiceStatusInfo(ServiceStatus.UP));
assertStatus(ServiceStatus.UP, 1, proxyHostApplication, "proxyhost1");
ControllerHostApplication controllerHostApplication = new ControllerHostApplication();
@@ -168,7 +169,7 @@ public class HealthMonitorManagerTest {
infraApplication.getApplicationId(),
infraApplication.getClusterId(),
infraApplication.getServiceType(),
- infraApplication.configIdFor(HostName.from(hostname)));
+ infraApplication.configIdFor(HostName.from(hostname))).serviceStatus();
assertEquals(expected, actual);
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 e38589b6f81..b6b88b0c0d3 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
@@ -66,7 +66,7 @@ public class StateV1HealthModelTest {
Cancellable cancellable = mock(Cancellable.class);
when(executor.scheduleWithFixedDelay(any(), any())).thenReturn(cancellable);
try (HealthMonitor healthMonitor = endpoint1.startMonitoring()) {
- assertEquals(ServiceStatus.DOWN, healthMonitor.getStatus());
+ assertEquals(ServiceStatus.NOT_CHECKED, healthMonitor.getStatus().serviceStatus());
}
}
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 c892118990f..533e5173ccc 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
@@ -16,20 +16,19 @@ public class StateV1HealthMonitorTest {
@Test
public void downThenUpThenDown() throws Exception {
StateV1HealthClient client = mock(StateV1HealthClient.class);
- when(client.get()).thenReturn(HealthInfo.empty());
StateV1HealthUpdater updater = new StateV1HealthUpdater(client);
RunletExecutor executor = new RunletExecutorImpl(2);
try (StateV1HealthMonitor monitor = new StateV1HealthMonitor(updater, executor, Duration.ofMillis(10))) {
- assertEquals(ServiceStatus.DOWN, monitor.getStatus());
+ assertEquals(ServiceStatus.NOT_CHECKED, monitor.getStatus().serviceStatus());
when(client.get()).thenReturn(HealthInfo.fromHealthStatusCode(HealthInfo.UP_STATUS_CODE));
- while (monitor.getStatus() != ServiceStatus.UP) {
+ while (monitor.getStatus().serviceStatus() != ServiceStatus.UP) {
try { Thread.sleep(2); } catch (InterruptedException ignored) { }
}
when(client.get()).thenReturn(HealthInfo.fromException(new IllegalStateException("foo")));
- while (monitor.getStatus() != ServiceStatus.DOWN) {
+ while (monitor.getStatus().serviceStatus() != ServiceStatus.DOWN) {
try { Thread.sleep(2); } catch (InterruptedException ignored) { }
}
}
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 e7b7a829dac..b8f108a480e 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
@@ -2,6 +2,7 @@
package com.yahoo.vespa.service.health;
import com.yahoo.vespa.applicationmodel.ServiceStatus;
+import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
import org.apache.http.HttpEntity;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.CloseableHttpResponse;
@@ -15,7 +16,7 @@ import java.net.URL;
import java.util.function.Function;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
@@ -31,7 +32,7 @@ public class StateV1HealthUpdaterTest {
@Test
public void successfulRequestResponse() throws IOException {
- HealthInfo info = getHealthInfoFromJsonResponse("{\n" +
+ ServiceStatusInfo info = getServiceStatusInfoFromJsonResponse("{\n" +
" \"metrics\": {\n" +
" \"snapshot\": {\n" +
" \"from\": 1.528789829249E9,\n" +
@@ -41,13 +42,13 @@ public class StateV1HealthUpdaterTest {
" \"status\": {\"code\": \"up\"},\n" +
" \"time\": 1528789889364\n" +
"}");
- assertTrue(info.isHealthy());
- assertEquals(ServiceStatus.UP, info.toServiceStatus());
+ assertEquals(ServiceStatus.UP, info.serviceStatus());
+ assertNull(info.errorOrNull());
}
@Test
public void notUpResponse() throws IOException {
- HealthInfo info = getHealthInfoFromJsonResponse("{\n" +
+ ServiceStatusInfo info = getServiceStatusInfoFromJsonResponse("{\n" +
" \"metrics\": {\n" +
" \"snapshot\": {\n" +
" \"from\": 1.528789829249E9,\n" +
@@ -57,14 +58,13 @@ public class StateV1HealthUpdaterTest {
" \"status\": {\"code\": \"initializing\"},\n" +
" \"time\": 1528789889364\n" +
"}");
- assertFalse(info.isHealthy());
- assertEquals(ServiceStatus.DOWN, info.toServiceStatus());
- assertEquals("Bad health status code 'initializing'", info.toString());
+ assertEquals(ServiceStatus.DOWN, info.serviceStatus());
+ assertEquals("Bad health status code 'initializing'", info.errorOrNull());
}
@Test
public void noCodeInResponse() throws IOException {
- HealthInfo info = getHealthInfoFromJsonResponse("{\n" +
+ ServiceStatusInfo info = getServiceStatusInfoFromJsonResponse("{\n" +
" \"metrics\": {\n" +
" \"snapshot\": {\n" +
" \"from\": 1.528789829249E9,\n" +
@@ -74,14 +74,13 @@ public class StateV1HealthUpdaterTest {
" \"status\": {\"foo\": \"bar\"},\n" +
" \"time\": 1528789889364\n" +
"}");
- assertFalse(info.isHealthy());
- assertEquals(ServiceStatus.DOWN, info.toServiceStatus());
- assertEquals("Bad health status code 'down'", info.toString());
+ assertEquals(ServiceStatus.DOWN, info.serviceStatus());
+ assertEquals("Bad health status code 'down'", info.errorOrNull());
}
@Test
public void noStatusInResponse() throws IOException {
- HealthInfo info = getHealthInfoFromJsonResponse("{\n" +
+ ServiceStatusInfo info = getServiceStatusInfoFromJsonResponse("{\n" +
" \"metrics\": {\n" +
" \"snapshot\": {\n" +
" \"from\": 1.528789829249E9,\n" +
@@ -90,20 +89,18 @@ public class StateV1HealthUpdaterTest {
" },\n" +
" \"time\": 1528789889364\n" +
"}");
- assertFalse(info.isHealthy());
- assertEquals(ServiceStatus.DOWN, info.toServiceStatus());
- assertEquals("Bad health status code 'down'", info.toString());
+ assertEquals(ServiceStatus.DOWN, info.serviceStatus());
+ assertEquals("Bad health status code 'down'", info.errorOrNull());
}
@Test
public void badJson() throws IOException {
- HealthInfo info = getHealthInfoFromJsonResponse("} foo bar");
- assertFalse(info.isHealthy());
- assertEquals(ServiceStatus.DOWN, info.toServiceStatus());
- assertTrue(info.toString().startsWith("Exception: Unexpected close marker '}': "));
+ ServiceStatusInfo info = getServiceStatusInfoFromJsonResponse("} foo bar");
+ assertEquals(ServiceStatus.DOWN, info.serviceStatus());
+ assertTrue(info.errorOrNull().startsWith("Exception: Unexpected close marker '}': "));
}
- private HealthInfo getHealthInfoFromJsonResponse(String content)
+ private ServiceStatusInfo getServiceStatusInfoFromJsonResponse(String content)
throws IOException {
CloseableHttpClient client = mock(CloseableHttpClient.class);
@@ -121,7 +118,7 @@ public class StateV1HealthUpdaterTest {
try (StateV1HealthUpdater updater = makeUpdater(client, entry -> content)) {
when(httpEntity.getContentLength()).thenReturn((long) content.length());
updater.run();
- return updater.getLatestHealthInfo();
+ return updater.getServiceStatusInfo();
}
}
@@ -133,10 +130,9 @@ public class StateV1HealthUpdaterTest {
try (StateV1HealthUpdater updater = makeUpdater(client, entry -> "")) {
updater.run();
- HealthInfo info = updater.getLatestHealthInfo();
- assertFalse(info.isHealthy());
- assertEquals(ServiceStatus.DOWN, info.toServiceStatus());
- assertEquals("Exception: exception string", info.toString());
+ ServiceStatusInfo info = updater.getServiceStatusInfo();
+ assertEquals(ServiceStatus.DOWN, info.serviceStatus());
+ assertEquals("Exception: exception string", info.errorOrNull());
}
}
@@ -160,10 +156,9 @@ public class StateV1HealthUpdaterTest {
try (HealthUpdater updater = makeUpdater(client, entry -> content)) {
when(httpEntity.getContentLength()).thenReturn((long) content.length());
updater.run();
- HealthInfo info = updater.getLatestHealthInfo();
- assertFalse(info.isHealthy());
- assertEquals(ServiceStatus.DOWN, info.toServiceStatus());
- assertEquals("Bad HTTP response status code 500", info.toString());
+ ServiceStatusInfo info = updater.getServiceStatusInfo();
+ assertEquals(ServiceStatus.DOWN, info.serviceStatus());
+ assertEquals("Bad HTTP response status code 500", info.errorOrNull());
}
}
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/manager/UnionMonitorManagerTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/manager/UnionMonitorManagerTest.java
index b97fd6c64a5..5cfe70fae5f 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/manager/UnionMonitorManagerTest.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/manager/UnionMonitorManagerTest.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.service.manager;
import com.yahoo.vespa.applicationmodel.ConfigId;
import com.yahoo.vespa.applicationmodel.ServiceStatus;
+import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
import com.yahoo.vespa.service.duper.ZoneApplication;
import com.yahoo.vespa.service.health.HealthMonitorManager;
import com.yahoo.vespa.service.slobrok.SlobrokMonitorManagerImpl;
@@ -34,12 +35,12 @@ public class UnionMonitorManagerTest {
private void testWith(ServiceStatus healthStatus,
ServiceStatus slobrokStatus,
ServiceStatus expectedStatus) {
- when(healthMonitorManager.getStatus(any(), any(), any(), any())).thenReturn(healthStatus);
- when(slobrokMonitorManager.getStatus(any(), any(), any(), any())).thenReturn(slobrokStatus);
+ when(healthMonitorManager.getStatus(any(), any(), any(), any())).thenReturn(new ServiceStatusInfo(healthStatus));
+ when(slobrokMonitorManager.getStatus(any(), any(), any(), any())).thenReturn(new ServiceStatusInfo(slobrokStatus));
ServiceStatus status = manager.getStatus(
ZoneApplication.getApplicationId(),
ZoneApplication.getNodeAdminClusterId(),
- ZoneApplication.getNodeAdminServiceType(), new ConfigId("config-id"));
+ ZoneApplication.getNodeAdminServiceType(), new ConfigId("config-id")).serviceStatus();
assertSame(expectedStatus, status);
}
} \ No newline at end of file
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/model/ApplicationInstanceGeneratorTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/model/ApplicationInstanceGeneratorTest.java
index 68f5aa8c451..7eba54977cc 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/model/ApplicationInstanceGeneratorTest.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/model/ApplicationInstanceGeneratorTest.java
@@ -6,6 +6,7 @@ import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.applicationmodel.ApplicationInstance;
import com.yahoo.vespa.applicationmodel.ServiceStatus;
+import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
import com.yahoo.vespa.service.duper.ConfigServerApplication;
import com.yahoo.vespa.service.monitor.ServiceStatusProvider;
import org.junit.Test;
@@ -34,7 +35,7 @@ public class ApplicationInstanceGeneratorTest {
@Test
public void toApplicationInstance() {
- when(statusProvider.getStatus(any(), any(), any(), any())).thenReturn(ServiceStatus.NOT_CHECKED);
+ when(statusProvider.getStatus(any(), any(), any(), any())).thenReturn(new ServiceStatusInfo(ServiceStatus.NOT_CHECKED));
Zone zone = mock(Zone.class);
ApplicationInfo configServer = configServerApplication.makeApplicationInfo(
configServerList.stream().map(HostName::from).collect(Collectors.toList()));
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/model/ExampleModel.java b/service-monitor/src/test/java/com/yahoo/vespa/service/model/ExampleModel.java
index 96e69f3cb69..0f7c0dde357 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/model/ExampleModel.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/model/ExampleModel.java
@@ -32,8 +32,9 @@ public class ExampleModel {
static final String TENANT = "tenant";
static final String APPLICATION_NAME = "application";
public static final String INSTANCE_NAME = "default";
+ public static final ApplicationId APPLICATION_ID = ApplicationId.from(TENANT, APPLICATION_NAME, INSTANCE_NAME);
- static SuperModel createExampleSuperModelWithOneRpcPort(String hostname, int rpcPort) {
+ public static SuperModel createExampleSuperModelWithOneRpcPort(String hostname, int rpcPort) {
List<String> hosts = Stream.of(hostname).collect(Collectors.toList());
ApplicationInfo applicationInfo = ExampleModel
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/model/ModelGeneratorTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/model/ModelGeneratorTest.java
index b77bdb4e54e..37da0611d53 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/model/ModelGeneratorTest.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/model/ModelGeneratorTest.java
@@ -11,6 +11,7 @@ import com.yahoo.vespa.applicationmodel.ApplicationInstanceReference;
import com.yahoo.vespa.applicationmodel.ServiceCluster;
import com.yahoo.vespa.applicationmodel.ServiceInstance;
import com.yahoo.vespa.applicationmodel.ServiceStatus;
+import com.yahoo.vespa.applicationmodel.ServiceStatusInfo;
import com.yahoo.vespa.service.monitor.ServiceModel;
import com.yahoo.vespa.service.monitor.ConfigserverUtil;
import com.yahoo.vespa.service.duper.ConfigServerApplication;
@@ -43,7 +44,7 @@ public class ModelGeneratorTest {
SlobrokMonitorManagerImpl slobrokMonitorManager = mock(SlobrokMonitorManagerImpl.class);
when(slobrokMonitorManager.getStatus(any(), any(), any(), any()))
- .thenReturn(ServiceStatus.UP);
+ .thenReturn(new ServiceStatusInfo(ServiceStatus.UP));
ServiceModel serviceModel =
modelGenerator.toServiceModel(
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/slobrok/SlobrokMonitorManagerImplTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/slobrok/SlobrokMonitorManagerImplTest.java
index bc6bff6fba8..0b8a13a8869 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/slobrok/SlobrokMonitorManagerImplTest.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/slobrok/SlobrokMonitorManagerImplTest.java
@@ -79,7 +79,7 @@ public class SlobrokMonitorManagerImplTest {
return slobrokMonitorManager.getStatus(
application.getApplicationId(),
clusterId,
- new ServiceType(serviceType), new ConfigId("config.id"));
+ new ServiceType(serviceType), new ConfigId("config.id")).serviceStatus();
}
@Test
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/slobrok/SlobrokMonitorTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/slobrok/SlobrokMonitorTest.java
index 907e52298bf..8bec3bf6cd8 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/slobrok/SlobrokMonitorTest.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/slobrok/SlobrokMonitorTest.java
@@ -2,12 +2,14 @@
package com.yahoo.vespa.service.slobrok;
import com.yahoo.config.model.api.ApplicationInfo;
+import com.yahoo.config.model.api.SuperModel;
import com.yahoo.jrt.slobrok.api.Mirror;
import com.yahoo.jrt.slobrok.api.SlobrokList;
import com.yahoo.vespa.service.model.ExampleModel;
import org.junit.Test;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
public class SlobrokMonitorTest {
private final SlobrokList slobrokList = mock(SlobrokList.class);
@@ -24,14 +26,13 @@ public class SlobrokMonitorTest {
@Test
public void testUpdateSlobrokList2() {
- /*
final String hostname = "hostname";
final int port = 1;
SuperModel superModel = ExampleModel.createExampleSuperModelWithOneRpcPort(hostname, port);
- slobrokMonitor.updateSlobrokList(superModel.getApplicationInfo());
+ slobrokMonitor.updateSlobrokList(superModel.getApplicationInfo(ExampleModel.APPLICATION_ID).get());
String[] expectedSpecs = new String[] {"tcp/" + hostname + ":" + port};
- verify(slobrokList).setup(expectedSpecs); */
+ verify(slobrokList).setup(expectedSpecs);
}
}