aboutsummaryrefslogtreecommitdiffstats
path: root/service-monitor
diff options
context:
space:
mode:
authorHåkon Hallingstad <hakon@verizonmedia.com>2019-05-23 17:47:13 +0200
committerHåkon Hallingstad <hakon@verizonmedia.com>2019-05-23 17:47:13 +0200
commit5885fca5ec8eb841f7811d21aae62b0966607f3b (patch)
treed992db1a282413bda0584dd0a99c026caf7d998b /service-monitor
parent55a6c1026fa87f7c8fae110bccecb327727ea477 (diff)
Tenant hosts only have node-admin service
Tenant hosts are allocated to the zone (routing) app in the node-admin cluster. These hosts also have various other services like logd, config-sentinel, etc that do not run. The metricsproxy container is a new service that will be added to all hosts, and that will be Slobrok monitored. Except, it will not run on tenant hosts as above. To avoid having metrics cluster spanning the whole of the zone app, and have them DOWN on all tenant hosts, we'll filter those service away from the model when generating the ApplicationInstance of the service model.
Diffstat (limited to 'service-monitor')
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/model/ApplicationInstanceGenerator.java15
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/model/ApplicationInstanceGeneratorTest.java70
2 files changed, 85 insertions, 0 deletions
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 0a4e8e75adf..e535aff8b46 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
@@ -4,6 +4,7 @@ package com.yahoo.vespa.service.model;
import com.yahoo.config.model.api.ApplicationInfo;
import com.yahoo.config.model.api.HostInfo;
import com.yahoo.config.model.api.ServiceInfo;
+import com.yahoo.config.model.api.container.ContainerServiceType;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.applicationmodel.ApplicationInstance;
@@ -18,6 +19,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.duper.ZoneApplication;
import com.yahoo.vespa.service.monitor.ServiceId;
import com.yahoo.vespa.service.monitor.ServiceStatusProvider;
@@ -53,8 +55,21 @@ public class ApplicationInstanceGenerator {
for (HostInfo host : applicationInfo.getModel().getHosts()) {
HostName hostName = new HostName(host.getHostname());
+
+ boolean isTenantHost =
+ applicationInfo.getApplicationId().equals(ZoneApplication.getApplicationId()) &&
+ host.getServices().stream().anyMatch(serviceInfo ->
+ ZoneApplication.isNodeAdminServiceInfo(applicationInfo.getApplicationId(), serviceInfo));
+
for (ServiceInfo serviceInfo : host.getServices()) {
ServiceClusterKey serviceClusterKey = toServiceClusterKey(serviceInfo);
+
+ if (isTenantHost && !ZoneApplication.isNodeAdminServiceInfo(applicationInfo.getApplicationId(), serviceInfo)) {
+ // A tenant host only runs the host-admin service, even though the model contains a bunch of
+ // standard services like config-sentinel and metrics proxy.
+ continue;
+ }
+
ServiceInstance serviceInstance =
toServiceInstance(
applicationInfo.getApplicationId(),
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 7eba54977cc..e182c9d6468 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
@@ -2,20 +2,32 @@
package com.yahoo.vespa.service.model;
import com.yahoo.config.model.api.ApplicationInfo;
+import com.yahoo.config.model.api.HostInfo;
+import com.yahoo.config.model.api.Model;
+import com.yahoo.config.model.api.ServiceInfo;
+import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.HostName;
+import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.applicationmodel.ApplicationInstance;
+import com.yahoo.vespa.applicationmodel.ClusterId;
+import com.yahoo.vespa.applicationmodel.ServiceCluster;
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.ZoneApplication;
import com.yahoo.vespa.service.monitor.ServiceStatusProvider;
import org.junit.Test;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
@@ -73,4 +85,62 @@ public class ApplicationInstanceGeneratorTest {
.toString()));
}
+ @Test
+ public void verifyOnlyNodeAdminServiceIsLeft() {
+ when(statusProvider.getStatus(any(), any(), any(), any())).thenReturn(new ServiceStatusInfo(ServiceStatus.NOT_CHECKED));
+
+ String host1 = "host1";
+ String host2 = "host2";
+
+ List<ServiceInfo> serviceInfos1 = List.of(
+ makeServiceInfo("metrics", "metricsproxy-container", host1)
+ );
+
+ List<ServiceInfo> serviceInfos2 = List.of(
+ makeServiceInfo("metrics", "metricsproxy-container", host2),
+ makeServiceInfo(ZoneApplication.getNodeAdminClusterId().s(),
+ ZoneApplication.getNodeAdminServiceType().s(), host2)
+ );
+
+ List<HostInfo> hostInfos = List.of(
+ new HostInfo(host1, serviceInfos1),
+ new HostInfo(host2, serviceInfos2)
+ );
+
+ Model model = mock(Model.class);
+ when(model.getHosts()).thenReturn(hostInfos);
+
+ ApplicationInfo applicationInfo = new ApplicationInfo(ZoneApplication.getApplicationId(), 0, model);
+
+ Zone zone = mock(Zone.class);
+ when(zone.environment()).thenReturn(Environment.prod);
+ when(zone.region()).thenReturn(RegionName.from("us-east-1"));
+
+ ApplicationInstanceGenerator generator = new ApplicationInstanceGenerator(applicationInfo, zone);
+ ApplicationInstance applicationInstance = generator.makeApplicationInstance(statusProvider);
+
+ Map<ClusterId, List<ServiceCluster>> serviceClusters =
+ applicationInstance.serviceClusters().stream().collect(Collectors.groupingBy(ServiceCluster::clusterId));
+ assertEquals(2, serviceClusters.size());
+ List<ServiceCluster> nodeAdminClusters = serviceClusters.get(ZoneApplication.getNodeAdminClusterId());
+ assertNotNull(nodeAdminClusters);
+ assertEquals(1, nodeAdminClusters.size());
+ ServiceCluster nodeAdminCluster = nodeAdminClusters.iterator().next();
+ assertEquals(1, nodeAdminCluster.serviceInstances().size());
+ assertEquals(host2, nodeAdminCluster.serviceInstances().iterator().next().hostName().s());
+
+ List<ServiceCluster> metricsClusters = serviceClusters.get(new ClusterId("metrics"));
+ assertNotNull(metricsClusters);
+ assertEquals(1, metricsClusters.size());
+ ServiceCluster metricsCluster = metricsClusters.iterator().next();
+
+ // The metrics service on the node admin host is ignored
+ assertEquals(1, metricsCluster.serviceInstances().size());
+ assertEquals(host1, metricsCluster.serviceInstances().iterator().next().hostName().s());
+ }
+
+ private ServiceInfo makeServiceInfo(String clusterId, String serviceType, String hostname) {
+ var properties = Map.of(ApplicationInstanceGenerator.CLUSTER_ID_PROPERTY_NAME, clusterId);
+ return new ServiceInfo("servicename", serviceType, List.of(), properties, "configid", hostname);
+ }
} \ No newline at end of file