summaryrefslogtreecommitdiffstats
path: root/service-monitor
diff options
context:
space:
mode:
authorHåkon Hallingstad <hakon@oath.com>2018-11-30 15:13:32 +0100
committerHåkon Hallingstad <hakon@oath.com>2018-11-30 15:13:32 +0100
commit72cc2930e964eea0969b7f8bcea7fe6b4f0872f0 (patch)
tree403dda89422340efee18b0a796c56bd1fa3ad007 /service-monitor
parent1b2ccec2d8f5ad05a7a718b62f256b4fd19bda74 (diff)
Add infrastructure applications to DuperModel
DuperModel is (will be) responsible for both active tenant applications (through SuperModel) and infrastructure applications. This PR is one step in that direction: - All infrastructure applications (config, confighost, controller, controllerhost, and proxyhost) are owned and managed by DuperModel. - The InfrastructureProvisioner retrieves all possible infra apps from the DuperModel (through a reduced API), and "activates" each of them if target is set and there are any nodes etc. - The InfrastructureProvisioner then notifies the DuperModel which apps have been activated, and with which hosts. - The DuperModel can then build delegate artificially create ApplicationInfo, which gets translated into the application model, and finally the service model. - The resulting service model has NOT_CHECKED for each hostadmin service instance. This is sufficient for goal 1 of this sprint. - The config server application currently has health, so that's kept as-is for now. - Feature flags have been tried and works and allows 1. to disable adding the infra apps in the DuperModel, and 2. to enable the infra configserver instead of the currently created configserver w/health.
Diffstat (limited to 'service-monitor')
-rw-r--r--service-monitor/pom.xml6
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ConfigServerApplication.java8
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ConfigServerHostApplication.java11
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ControllerApplication.java11
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ControllerHostApplication.java12
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/DuperModel.java140
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/DuperModelInfraApi.java26
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/DuperModelListener.java (renamed from service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/DuperModelListener.java)2
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/HostedVespaApplication.java69
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/InfraApplication.java142
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/InfraApplicationApi.java22
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ProxyHostApplication.java11
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/TenantHostApplication.java14
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ZoneApplication.java4
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/DuperModel.java42
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/MonitorManager.java1
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/ServiceMonitorImpl.java8
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/SuperModelListenerImpl.java1
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/monitor/application/ApplicationInstanceGeneratorTest.java2
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/monitor/application/DuperModelTest.java95
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/ConfigserverUtil.java2
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/DuperModelTest.java53
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/ModelGeneratorTest.java5
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/SuperModelListenerImplTest.java1
-rw-r--r--service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/health/ApplicationHealthMonitorTest.java3
25 files changed, 474 insertions, 217 deletions
diff --git a/service-monitor/pom.xml b/service-monitor/pom.xml
index b8065ed3636..168af826b40 100644
--- a/service-monitor/pom.xml
+++ b/service-monitor/pom.xml
@@ -36,6 +36,12 @@
</dependency>
<dependency>
<groupId>com.yahoo.vespa</groupId>
+ <artifactId>flags</artifactId>
+ <version>${project.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.yahoo.vespa</groupId>
<artifactId>component</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ConfigServerApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ConfigServerApplication.java
index 5ad38cebcfc..f1041835a39 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ConfigServerApplication.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ConfigServerApplication.java
@@ -25,7 +25,7 @@ import java.util.Map;
/**
* A service/application model of the config server with health status.
*/
-public class ConfigServerApplication extends HostedVespaApplication {
+public class ConfigServerApplication extends InfraApplication {
public static final ConfigServerApplication CONFIG_SERVER_APPLICATION = new ConfigServerApplication();
public static final TenantId TENANT_ID = new TenantId(CONFIG_SERVER_APPLICATION.getApplicationId().tenant().value());
@@ -39,12 +39,12 @@ public class ConfigServerApplication extends HostedVespaApplication {
return new ConfigId(CONFIG_ID_PREFIX + index);
}
- private ConfigServerApplication() {
+ public ConfigServerApplication() {
super("zone-config-servers", NodeType.config,
- ClusterSpec.Type.admin, ClusterSpec.Id.from("zone-config-servers"));
+ ClusterSpec.Type.admin, ClusterSpec.Id.from("zone-config-servers"), ServiceType.CONFIG_SERVER);
}
- public ApplicationInfo makeApplicationInfo(ConfigserverConfig config) {
+ public ApplicationInfo makeApplicationInfoFromConfig(ConfigserverConfig config) {
List<HostInfo> hostInfos = new ArrayList<>();
List<ConfigserverConfig.Zookeeperserver> zooKeeperServers = config.zookeeperserver();
for (int index = 0; index < zooKeeperServers.size(); ++index) {
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ConfigServerHostApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ConfigServerHostApplication.java
index 18420fe64a1..9925e2ac69b 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ConfigServerHostApplication.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ConfigServerHostApplication.java
@@ -3,13 +3,12 @@ package com.yahoo.vespa.service.monitor.application;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.NodeType;
+import com.yahoo.vespa.applicationmodel.ServiceType;
-public class ConfigServerHostApplication extends HostedVespaApplication {
-
- public static final ConfigServerHostApplication CONFIG_SERVER_HOST_APPLICATION = new ConfigServerHostApplication();
-
- private ConfigServerHostApplication() {
+public class ConfigServerHostApplication extends InfraApplication {
+ public ConfigServerHostApplication() {
super("configserver-host", NodeType.confighost,
- ClusterSpec.Type.container, ClusterSpec.Id.from("configserver-host"));
+ ClusterSpec.Type.container, ClusterSpec.Id.from("configserver-host"),
+ ServiceType.HOST_ADMIN);
}
}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ControllerApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ControllerApplication.java
index c1bc303e792..ec4cb73383e 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ControllerApplication.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ControllerApplication.java
@@ -3,16 +3,15 @@ package com.yahoo.vespa.service.monitor.application;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.NodeType;
+import com.yahoo.vespa.applicationmodel.ServiceType;
/**
* @author mpolden
*/
-public class ControllerApplication extends HostedVespaApplication {
-
- public static final ControllerApplication CONTROLLER_APPLICATION = new ControllerApplication();
-
- private ControllerApplication() {
- super("controller", NodeType.controller, ClusterSpec.Type.container, ClusterSpec.Id.from("controller"));
+public class ControllerApplication extends InfraApplication {
+ public ControllerApplication() {
+ super("controller", NodeType.controller, ClusterSpec.Type.container,
+ ClusterSpec.Id.from("controller"), ServiceType.CONTROLLER);
}
}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ControllerHostApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ControllerHostApplication.java
index 8311919d570..c23794b3835 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ControllerHostApplication.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ControllerHostApplication.java
@@ -3,16 +3,14 @@ package com.yahoo.vespa.service.monitor.application;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.NodeType;
+import com.yahoo.vespa.applicationmodel.ServiceType;
/**
* @author mpolden
*/
-public class ControllerHostApplication extends HostedVespaApplication {
-
- public static final ControllerHostApplication CONTROLLER_HOST_APPLICATION = new ControllerHostApplication();
-
- protected ControllerHostApplication() {
- super("controller-host", NodeType.controllerhost, ClusterSpec.Type.container, ClusterSpec.Id.from("controller-host"));
+public class ControllerHostApplication extends InfraApplication {
+ public ControllerHostApplication() {
+ super("controller-host", NodeType.controllerhost, ClusterSpec.Type.container,
+ ClusterSpec.Id.from("controller-host"), ServiceType.HOST_ADMIN);
}
-
}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/DuperModel.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/DuperModel.java
new file mode 100644
index 00000000000..eecd1a73cf9
--- /dev/null
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/DuperModel.java
@@ -0,0 +1,140 @@
+// 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.monitor.application;
+
+import com.google.inject.Inject;
+import com.yahoo.cloud.config.ConfigserverConfig;
+import com.yahoo.config.model.api.ApplicationInfo;
+import com.yahoo.config.model.api.SuperModel;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.HostName;
+import com.yahoo.vespa.flags.FeatureFlag;
+import com.yahoo.vespa.flags.FlagSource;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * The {@code DuperModel} unites the {@link com.yahoo.config.model.api.SuperModel SuperModel}
+ * with synthetic applications like the config server application.
+ *
+ * @author hakon
+ */
+public class DuperModel implements DuperModelInfraApi {
+ // Infrastructure applications
+ private static final ConfigServerApplication configServerApplication = new ConfigServerApplication();
+ private static final ConfigServerHostApplication configServerHostApplication = new ConfigServerHostApplication();
+ private static final ProxyHostApplication proxyHostApplication = new ProxyHostApplication();
+ private static final ControllerApplication controllerApplication = new ControllerApplication();
+ private static final ControllerHostApplication controllerHostApplication = new ControllerHostApplication();
+
+ private static final Map<ApplicationId, InfraApplication> supportedInfraApplications = Stream.of(
+ configServerApplication,
+ configServerHostApplication,
+ proxyHostApplication,
+ controllerApplication,
+ controllerHostApplication)
+ .collect(Collectors.toMap(InfraApplication::getApplicationId, Function.identity()));
+
+ private final boolean containsInfra;
+ private final boolean useConfigserverConfig;
+
+ // Each of the above infrastructure applications may be active, in case their ApplicationInfo is present here
+ private final ConcurrentHashMap<ApplicationId, ApplicationInfo> infraInfos =
+ new ConcurrentHashMap<>(2 * supportedInfraApplications.size());
+
+ // ApplicationInfo known at construction time
+ private final List<ApplicationInfo> staticInfos = new ArrayList<>();
+
+ @Inject
+ public DuperModel(ConfigserverConfig configServerConfig, FlagSource flagSource) {
+ this(
+ // Whether to include activate infrastructure applications in the DuperModel.
+ new FeatureFlag("dupermodel-contains-infra", true, flagSource).value(),
+
+ // Whether to base the ApplicationInfo for the config server on ConfigserverConfig or InfrastructureProvisioner:
+ // - ConfigserverConfig: The list of config servers comes from VESPA_CONFIGSERVERS environment variable.
+ // - InfrastructureProvisioner: The list of config servers comes from the node repository.
+ //
+ // The goal is to use InfrastructureProvisioner like other infrastructure applications.
+ new FeatureFlag("dupermodel-use-configserverconfig", true, flagSource).value(),
+ configServerConfig.multitenant(),
+ configServerApplication.makeApplicationInfoFromConfig(configServerConfig));
+ }
+
+ /** For testing */
+ public DuperModel(boolean containsInfra,
+ boolean useConfigserverConfig,
+ boolean multitenant,
+ ApplicationInfo configServerApplicationInfo) {
+ this.containsInfra = containsInfra;
+ this.useConfigserverConfig = useConfigserverConfig;
+
+ // Single-tenant applications have the config server as part of the application model, conflicting and would have conflicting.
+ // TODO: Add health monitoring for config server when part of application model.
+ if (useConfigserverConfig && multitenant) {
+ staticInfos.add(configServerApplicationInfo);
+ }
+ }
+
+ public ConfigServerApplication getConfigServerApplication() {
+ return configServerApplication;
+ }
+
+ public ConfigServerHostApplication getConfigServerHostApplication() {
+ return configServerHostApplication;
+ }
+
+ public ProxyHostApplication getProxyHostApplication() {
+ return proxyHostApplication;
+ }
+
+ public ControllerApplication getControllerApplication() {
+ return controllerApplication;
+ }
+
+ public ControllerHostApplication getControllerHostApplication() {
+ return controllerHostApplication;
+ }
+
+ @Override
+ public List<InfraApplicationApi> getSupportedInfraApplications() {
+ return new ArrayList<>(supportedInfraApplications.values());
+ }
+
+ @Override
+ public boolean infraApplicationIsActive(ApplicationId applicationId) {
+ return infraInfos.containsKey(applicationId);
+ }
+
+ @Override
+ public void infraApplicationActivated(ApplicationId applicationId, List<HostName> hostnames) {
+ InfraApplication application = supportedInfraApplications.get(applicationId);
+ if (application == null) {
+ throw new IllegalArgumentException("There is no infrastructure application with ID '" + applicationId + "'");
+ }
+
+ if (useConfigserverConfig && application.equals(configServerApplication)) {
+ return;
+ }
+
+ infraInfos.put(application.getApplicationId(), application.makeApplicationInfo(hostnames));
+ }
+
+ @Override
+ public void infraApplicationRemoved(ApplicationId applicationId) {
+ infraInfos.remove(applicationId);
+ }
+
+ public List<ApplicationInfo> getApplicationInfos(SuperModel superModelSnapshot) {
+ List<ApplicationInfo> allApplicationInfos = new ArrayList<>();
+ allApplicationInfos.addAll(staticInfos);
+ if (containsInfra) allApplicationInfos.addAll(infraInfos.values());
+ allApplicationInfos.addAll(superModelSnapshot.getAllApplicationInfos());
+ return allApplicationInfos;
+ }
+}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/DuperModelInfraApi.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/DuperModelInfraApi.java
new file mode 100644
index 00000000000..2faeca55fa4
--- /dev/null
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/DuperModelInfraApi.java
@@ -0,0 +1,26 @@
+// 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.monitor.application;
+
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.HostName;
+
+import java.util.List;
+
+/**
+ * The DuperModel's API for infrastructure applications.
+ *
+ * @author hakonhall
+ */
+public interface DuperModelInfraApi {
+ /** Returns the list of supported infrastructure applications. */
+ List<InfraApplicationApi> getSupportedInfraApplications();
+
+ /** Returns true if the DuperModel has registered the infrastructure application as active. */
+ boolean infraApplicationIsActive(ApplicationId applicationId);
+
+ /** Update the DuperModel: A supported infrastructure application has been activated or is active. */
+ void infraApplicationActivated(ApplicationId applicationId, List<HostName> hostnames);
+
+ /** Update the DuperModel: A supported infrastructure application has been removed or is not active. */
+ void infraApplicationRemoved(ApplicationId applicationId);
+}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/DuperModelListener.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/DuperModelListener.java
index 235c7db5c36..34b8109ce53 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/DuperModelListener.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/DuperModelListener.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.monitor.internal;
+package com.yahoo.vespa.service.monitor.application;
import com.yahoo.config.model.api.ApplicationInfo;
import com.yahoo.config.model.api.SuperModel;
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/HostedVespaApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/HostedVespaApplication.java
deleted file mode 100644
index 23fafa701d9..00000000000
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/HostedVespaApplication.java
+++ /dev/null
@@ -1,69 +0,0 @@
-// 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.monitor.application;
-
-import com.yahoo.config.provision.ApplicationId;
-import com.yahoo.config.provision.Capacity;
-import com.yahoo.config.provision.ClusterSpec;
-import com.yahoo.config.provision.NodeType;
-import com.yahoo.config.provision.TenantName;
-import com.yahoo.component.Version;
-
-/**
- * @author freva
- */
-public abstract class HostedVespaApplication {
-
- public static final TenantName TENANT_NAME = TenantName.from("hosted-vespa");
-
- private final ApplicationId applicationId;
- private final Capacity capacity;
- private final ClusterSpec.Type clusterType;
- private final ClusterSpec.Id clusterId;
-
- protected HostedVespaApplication(String applicationName, NodeType nodeType,
- ClusterSpec.Type clusterType, ClusterSpec.Id clusterId) {
- this(createHostedVespaApplicationId(applicationName), Capacity.fromRequiredNodeType(nodeType),
- clusterType, clusterId);
- }
-
- protected HostedVespaApplication(ApplicationId applicationId, Capacity capacity,
- ClusterSpec.Type clusterType, ClusterSpec.Id clusterId) {
- this.applicationId = applicationId;
- this.capacity = capacity;
- this.clusterType = clusterType;
- this.clusterId = clusterId;
- }
-
- public ApplicationId getApplicationId() {
- return applicationId;
- }
-
- public Capacity getCapacity() {
- return capacity;
- }
-
- public ClusterSpec getClusterSpecWithVersion(Version version) {
- return ClusterSpec.request(clusterType, clusterId, version, true);
- }
-
- public ClusterSpec.Type getClusterType() {
- return clusterType;
- }
-
- public ClusterSpec.Id getClusterId() {
- return clusterId;
- }
-
- public static ApplicationId createHostedVespaApplicationId(String applicationName) {
- return new ApplicationId.Builder()
- .tenant(TENANT_NAME)
- .applicationName(applicationName)
- .build();
- }
-
- @Override
- public String toString() {
- return applicationId.toString();
- }
-
-}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/InfraApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/InfraApplication.java
new file mode 100644
index 00000000000..1c4f6ea3d2a
--- /dev/null
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/InfraApplication.java
@@ -0,0 +1,142 @@
+// 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.monitor.application;
+
+import com.yahoo.config.model.api.ApplicationInfo;
+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.ApplicationId;
+import com.yahoo.config.provision.Capacity;
+import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.HostName;
+import com.yahoo.config.provision.NodeType;
+import com.yahoo.config.provision.TenantName;
+import com.yahoo.component.Version;
+import com.yahoo.vespa.applicationmodel.ConfigId;
+import com.yahoo.vespa.applicationmodel.ServiceType;
+import com.yahoo.vespa.service.monitor.internal.ModelGenerator;
+import com.yahoo.vespa.service.monitor.internal.health.ApplicationHealthMonitor;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * @author freva
+ */
+public abstract class InfraApplication implements InfraApplicationApi {
+ static final int HEALTH_PORT = 8080;
+
+ private static final TenantName TENANT_NAME = TenantName.from("hosted-vespa");
+ private static final String CONFIG_ID_PREFIX = "configid.";
+
+ private final ApplicationId applicationId;
+ private final Capacity capacity;
+ private final ClusterSpec.Type clusterType;
+ private final ClusterSpec.Id clusterId;
+ private final ServiceType serviceType;
+
+ public static ApplicationId createHostedVespaApplicationId(String applicationName) {
+ return new ApplicationId.Builder()
+ .tenant(TENANT_NAME)
+ .applicationName(applicationName)
+ .build();
+ }
+
+ protected InfraApplication(String applicationName,
+ NodeType nodeType,
+ ClusterSpec.Type clusterType,
+ ClusterSpec.Id clusterId,
+ ServiceType serviceType) {
+ this.applicationId = createHostedVespaApplicationId(applicationName);
+ this.capacity = Capacity.fromRequiredNodeType(nodeType);
+ this.clusterType = clusterType;
+ this.clusterId = clusterId;
+ this.serviceType = serviceType;
+ }
+
+ @Override
+ public ApplicationId getApplicationId() {
+ return applicationId;
+ }
+
+ @Override
+ public Capacity getCapacity() {
+ return capacity;
+ }
+
+ @Override
+ public ClusterSpec getClusterSpecWithVersion(Version version) {
+ return ClusterSpec.request(clusterType, clusterId, version, true);
+ }
+
+ public ClusterSpec.Type getClusterType() {
+ return clusterType;
+ }
+
+ public ClusterSpec.Id getClusterId() {
+ return clusterId;
+ }
+
+ public ApplicationInfo makeApplicationInfo(List<HostName> hostnames) {
+ List<HostInfo> hostInfos = new ArrayList<>();
+ for (int index = 0; index < hostnames.size(); ++index) {
+ hostInfos.add(makeHostInfo(hostnames.get(index), HEALTH_PORT, index, serviceType, clusterId));
+ }
+
+ return new ApplicationInfo(applicationId, 0, new HostsModel(hostInfos));
+ }
+
+ private static HostInfo makeHostInfo(HostName hostname, int port, int configIndex, ServiceType serviceType, ClusterSpec.Id clusterId) {
+ PortInfo portInfo = new PortInfo(port, ApplicationHealthMonitor.PORT_TAGS_HEALTH);
+
+ Map<String, String> properties = new HashMap<>();
+ properties.put(ModelGenerator.CLUSTER_ID_PROPERTY_NAME, clusterId.value());
+
+ ServiceInfo serviceInfo = new ServiceInfo(
+ // service name == service type for the first service of each type on each host
+ serviceType.s(),
+ serviceType.s(),
+ Collections.singletonList(portInfo),
+ properties,
+ configIdFrom(configIndex).s(),
+ hostname.value());
+
+ return new HostInfo(hostname.value(), Collections.singletonList(serviceInfo));
+ }
+
+ private static ConfigId configIdFrom(int index) {
+ return new ConfigId(CONFIG_ID_PREFIX + index);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ InfraApplication that = (InfraApplication) o;
+ return Objects.equals(applicationId, that.applicationId) &&
+ Objects.equals(capacity, that.capacity) &&
+ clusterType == that.clusterType &&
+ Objects.equals(clusterId, that.clusterId) &&
+ Objects.equals(serviceType, that.serviceType);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(applicationId, capacity, clusterType, clusterId, serviceType);
+ }
+
+ @Override
+ public String toString() {
+ return "InfraApplication{" +
+ "applicationId=" + applicationId +
+ ", capacity=" + capacity +
+ ", clusterType=" + clusterType +
+ ", clusterId=" + clusterId +
+ ", serviceType=" + serviceType +
+ '}';
+ }
+}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/InfraApplicationApi.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/InfraApplicationApi.java
new file mode 100644
index 00000000000..3777a50b531
--- /dev/null
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/InfraApplicationApi.java
@@ -0,0 +1,22 @@
+// 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.monitor.application;
+
+import com.yahoo.component.Version;
+import com.yahoo.config.model.api.ApplicationInfo;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.Capacity;
+import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.HostName;
+
+import java.util.List;
+
+/**
+ * API of infrastructure application that is accessible via DuperModelInfraApi.
+ *
+ * @author hakonhall
+ */
+public interface InfraApplicationApi {
+ ApplicationId getApplicationId();
+ Capacity getCapacity();
+ ClusterSpec getClusterSpecWithVersion(Version version);
+}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ProxyHostApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ProxyHostApplication.java
index c1af7a0977e..2debec5d299 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ProxyHostApplication.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ProxyHostApplication.java
@@ -3,12 +3,11 @@ package com.yahoo.vespa.service.monitor.application;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.NodeType;
+import com.yahoo.vespa.applicationmodel.ServiceType;
-public class ProxyHostApplication extends HostedVespaApplication {
-
- public static final ProxyHostApplication PROXY_HOST_APPLICATION = new ProxyHostApplication();
-
- private ProxyHostApplication() {
- super("proxy-host", NodeType.proxyhost, ClusterSpec.Type.container, ClusterSpec.Id.from("proxy-host"));
+public class ProxyHostApplication extends InfraApplication {
+ public ProxyHostApplication() {
+ super("proxy-host", NodeType.proxyhost, ClusterSpec.Type.container,
+ ClusterSpec.Id.from("proxy-host"), ServiceType.HOST_ADMIN);
}
}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/TenantHostApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/TenantHostApplication.java
deleted file mode 100644
index 27879a03c08..00000000000
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/TenantHostApplication.java
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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.monitor.application;
-
-import com.yahoo.config.provision.ClusterSpec;
-import com.yahoo.config.provision.NodeType;
-
-public class TenantHostApplication extends HostedVespaApplication {
-
- public static final TenantHostApplication TENANT_HOST_APPLICATION = new TenantHostApplication();
-
- private TenantHostApplication() {
- super("tenant-host", NodeType.host, ClusterSpec.Type.container, ClusterSpec.Id.from("tenant-host"));
- }
-}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ZoneApplication.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ZoneApplication.java
index c10015d3bfa..4a4189cddd7 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ZoneApplication.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/ZoneApplication.java
@@ -10,14 +10,14 @@ import java.util.Objects;
/**
* @author hakon
*
- * TODO: This does not extend HostedVespaApplication because
+ * TODO: This does not extend InfraApplication because
* 1) It is not deployed same as the other HostedVespaApplications
* 2) ZoneApplication has multiple clusters
*/
public class ZoneApplication {
private ZoneApplication() {}
- public static final ApplicationId ZONE_APPLICATION_ID = HostedVespaApplication
+ public static final ApplicationId ZONE_APPLICATION_ID = InfraApplication
.createHostedVespaApplicationId("routing");
public static boolean isNodeAdminService(ApplicationId applicationId,
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/DuperModel.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/DuperModel.java
deleted file mode 100644
index 80e0bfd2710..00000000000
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/DuperModel.java
+++ /dev/null
@@ -1,42 +0,0 @@
-// 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.monitor.internal;
-
-import com.yahoo.cloud.config.ConfigserverConfig;
-import com.yahoo.config.model.api.ApplicationInfo;
-import com.yahoo.config.model.api.SuperModel;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import static com.yahoo.vespa.service.monitor.application.ConfigServerApplication.CONFIG_SERVER_APPLICATION;
-
-/**
- * The {@code DuperModel} unites the {@link com.yahoo.config.model.api.SuperModel SuperModel}
- * with the synthetically produced applications like the config server application.
- *
- * @author hakon
- */
-public class DuperModel {
- private final List<ApplicationInfo> staticApplicationInfos = new ArrayList<>();
-
- public DuperModel(ConfigserverConfig configServerConfig) {
- // Single-tenant applications have the config server as part of the application model.
- // TODO: Add health monitoring for config server when part of application model.
- if (configServerConfig.multitenant()) {
- staticApplicationInfos.add(CONFIG_SERVER_APPLICATION.makeApplicationInfo(configServerConfig));
- }
- }
-
- /** For testing. */
- DuperModel(ApplicationInfo... staticApplicationInfos) {
- this.staticApplicationInfos.addAll(Arrays.asList(staticApplicationInfos));
- }
-
- public List<ApplicationInfo> getApplicationInfos(SuperModel superModelSnapshot) {
- List<ApplicationInfo> allApplicationInfos = new ArrayList<>();
- allApplicationInfos.addAll(staticApplicationInfos);
- allApplicationInfos.addAll(superModelSnapshot.getAllApplicationInfos());
- return allApplicationInfos;
- }
-}
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/MonitorManager.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/MonitorManager.java
index 1edf3a18215..965c425b91e 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/MonitorManager.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/MonitorManager.java
@@ -1,6 +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.monitor.internal;
+import com.yahoo.vespa.service.monitor.application.DuperModelListener;
import com.yahoo.vespa.service.monitor.ServiceStatusProvider;
/**
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/ServiceMonitorImpl.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/ServiceMonitorImpl.java
index eb346cf40c1..728c761c71d 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/ServiceMonitorImpl.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/ServiceMonitorImpl.java
@@ -9,6 +9,7 @@ import com.yahoo.jdisc.Metric;
import com.yahoo.jdisc.Timer;
import com.yahoo.vespa.applicationmodel.ApplicationInstance;
import com.yahoo.vespa.applicationmodel.ApplicationInstanceReference;
+import com.yahoo.vespa.service.monitor.application.DuperModel;
import com.yahoo.vespa.service.monitor.ServiceModel;
import com.yahoo.vespa.service.monitor.ServiceMonitor;
import com.yahoo.vespa.service.monitor.internal.health.HealthMonitorManager;
@@ -26,12 +27,11 @@ public class ServiceMonitorImpl implements ServiceMonitor {
HealthMonitorManager healthMonitorManager,
Metric metric,
Timer timer,
- Zone zone) {
+ Zone zone,
+ DuperModel duperModel) {
ServiceMonitorMetrics metrics = new ServiceMonitorMetrics(metric, timer);
- DuperModel duperModel = new DuperModel(configserverConfig);
- UnionMonitorManager monitorManager =
- new UnionMonitorManager(slobrokMonitorManager, healthMonitorManager);
+ UnionMonitorManager monitorManager = new UnionMonitorManager(slobrokMonitorManager, healthMonitorManager);
SuperModelListenerImpl superModelListener = new SuperModelListenerImpl(
monitorManager,
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/SuperModelListenerImpl.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/SuperModelListenerImpl.java
index f509809c33d..7e2b61af090 100644
--- a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/SuperModelListenerImpl.java
+++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/internal/SuperModelListenerImpl.java
@@ -7,6 +7,7 @@ import com.yahoo.config.model.api.SuperModelListener;
import com.yahoo.config.model.api.SuperModelProvider;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Zone;
+import com.yahoo.vespa.service.monitor.application.DuperModel;
import com.yahoo.vespa.service.monitor.ServiceModel;
import com.yahoo.vespa.service.monitor.ServiceStatusProvider;
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/application/ApplicationInstanceGeneratorTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/application/ApplicationInstanceGeneratorTest.java
index 899cc59bb34..4608e8b0aa8 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/application/ApplicationInstanceGeneratorTest.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/application/ApplicationInstanceGeneratorTest.java
@@ -42,7 +42,7 @@ public class ApplicationInstanceGeneratorTest {
configServer2,
configServer3);
Zone zone = mock(Zone.class);
- ApplicationInfo configServer = CONFIG_SERVER_APPLICATION.makeApplicationInfo(config);
+ ApplicationInfo configServer = CONFIG_SERVER_APPLICATION.makeApplicationInfoFromConfig(config);
ApplicationInstance applicationInstance = new ApplicationInstanceGenerator(configServer, zone)
.makeApplicationInstance(statusProvider);
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/application/DuperModelTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/application/DuperModelTest.java
new file mode 100644
index 00000000000..40204c0de8e
--- /dev/null
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/application/DuperModelTest.java
@@ -0,0 +1,95 @@
+// 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.monitor.application;
+
+import com.yahoo.cloud.config.ConfigserverConfig;
+import com.yahoo.config.model.api.ApplicationInfo;
+import com.yahoo.config.model.api.SuperModel;
+import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.HostName;
+import com.yahoo.vespa.applicationmodel.ServiceStatus;
+import com.yahoo.vespa.service.monitor.ServiceStatusProvider;
+import com.yahoo.vespa.service.monitor.internal.ConfigserverUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+/**
+ * @author hakon
+ */
+public class DuperModelTest {
+ private final ServiceStatusProvider statusProvider = mock(ServiceStatusProvider.class);
+ private final ConfigserverConfig configserverConfig = ConfigserverUtil.createExampleConfigserverConfig();
+ private final ApplicationInfo configServerApplicationInfo = new ConfigServerApplication().makeApplicationInfoFromConfig(configserverConfig);
+ private final SuperModel superModel = mock(SuperModel.class);
+
+ @Before
+ public void setUp() {
+ when(statusProvider.getStatus(any(), any(), any(), any())).thenReturn(ServiceStatus.NOT_CHECKED);
+ }
+
+ @Test
+ public void toApplicationInstance() {
+ DuperModel duperModel = new DuperModel(false, true, true, configServerApplicationInfo);
+ ApplicationInfo superModelApplicationInfo = mock(ApplicationInfo.class);
+ when(superModel.getAllApplicationInfos()).thenReturn(Collections.singletonList(superModelApplicationInfo));
+ List<ApplicationInfo> applicationInfos = duperModel.getApplicationInfos(superModel);
+ assertEquals(2, applicationInfos.size());
+ assertEquals(ConfigServerApplication.CONFIG_SERVER_APPLICATION.getApplicationId(), applicationInfos.get(0).getApplicationId());
+ assertSame(superModelApplicationInfo, applicationInfos.get(1));
+ }
+
+ @Test
+ public void toApplicationInstanceInSingleTenantMode() {
+ DuperModel duperModel = new DuperModel(false, true, false, configServerApplicationInfo);
+ ApplicationInfo superModelApplicationInfo = mock(ApplicationInfo.class);
+ when(superModel.getAllApplicationInfos()).thenReturn(Collections.singletonList(superModelApplicationInfo));
+ List<ApplicationInfo> applicationInfos = duperModel.getApplicationInfos(superModel);
+ assertEquals(1, applicationInfos.size());
+ assertSame(superModelApplicationInfo, applicationInfos.get(0));
+ }
+
+ @Test
+ public void testInfraApplications() {
+ DuperModel duperModel = new DuperModel(true, true, true, configServerApplicationInfo);
+ ApplicationInfo infraApplicationInfo = mock(ApplicationInfo.class);
+ when(superModel.getAllApplicationInfos()).thenReturn(Collections.emptyList());
+
+ List<ApplicationInfo> applicationInfos = duperModel.getApplicationInfos(superModel);
+ assertEquals(1, applicationInfos.size());
+ assertEquals(duperModel.getConfigServerApplication().getApplicationId(), applicationInfos.get(0).getApplicationId());
+
+ List<InfraApplicationApi> infraApis = duperModel.getSupportedInfraApplications();
+ assertEquals(5, infraApis.size());
+
+ InfraApplication proxyHostApp = duperModel.getProxyHostApplication();
+ assertFalse(duperModel.infraApplicationIsActive(proxyHostApp.getApplicationId()));
+
+ List<HostName> hostnames = Stream.of("host1").map(HostName::from).collect(Collectors.toList());
+ duperModel.infraApplicationActivated(proxyHostApp.getApplicationId(), hostnames);
+
+ assertTrue(duperModel.infraApplicationIsActive(proxyHostApp.getApplicationId()));
+ applicationInfos = duperModel.getApplicationInfos(superModel);
+ assertEquals(2, applicationInfos.size());
+ List<ApplicationId> applicationIds = applicationInfos.stream()
+ .map(ApplicationInfo::getApplicationId)
+ .collect(Collectors.toList());
+ assertThat(applicationIds, hasItem(proxyHostApp.getApplicationId()));
+
+ duperModel.infraApplicationRemoved(proxyHostApp.getApplicationId());
+ assertFalse(duperModel.infraApplicationIsActive(proxyHostApp.getApplicationId()));
+ }
+}
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/ConfigserverUtil.java b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/ConfigserverUtil.java
index 85df02949a6..16963797ac8 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/ConfigserverUtil.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/ConfigserverUtil.java
@@ -38,7 +38,7 @@ public class ConfigserverUtil {
String configServerHostname1,
String configServerHostname2,
String configServerHostname3) {
- return ConfigServerApplication.CONFIG_SERVER_APPLICATION.makeApplicationInfo(create(
+ return ConfigServerApplication.CONFIG_SERVER_APPLICATION.makeApplicationInfoFromConfig(create(
true,
true,
configServerHostname1,
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/DuperModelTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/DuperModelTest.java
deleted file mode 100644
index c9d19d0ccd9..00000000000
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/DuperModelTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// 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.monitor.internal;
-
-import com.yahoo.cloud.config.ConfigserverConfig;
-import com.yahoo.config.model.api.ApplicationInfo;
-import com.yahoo.config.model.api.SuperModel;
-import com.yahoo.vespa.applicationmodel.ServiceStatus;
-import com.yahoo.vespa.service.monitor.ServiceStatusProvider;
-import com.yahoo.vespa.service.monitor.application.ConfigServerApplication;
-import org.junit.Test;
-
-import java.util.Collections;
-import java.util.List;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-/**
- * @author hakon
- */
-public class DuperModelTest {
- private final ServiceStatusProvider statusProvider = mock(ServiceStatusProvider.class);
-
- @Test
- public void toApplicationInstance() {
- when(statusProvider.getStatus(any(), any(), any(), any())).thenReturn(ServiceStatus.NOT_CHECKED);
- ConfigserverConfig config = ConfigserverUtil.createExampleConfigserverConfig();
- DuperModel duperModel = new DuperModel(config);
- SuperModel superModel = mock(SuperModel.class);
- ApplicationInfo superModelApplicationInfo = mock(ApplicationInfo.class);
- when(superModel.getAllApplicationInfos()).thenReturn(Collections.singletonList(superModelApplicationInfo));
- List<ApplicationInfo> applicationInfos = duperModel.getApplicationInfos(superModel);
- assertEquals(2, applicationInfos.size());
- assertEquals(ConfigServerApplication.CONFIG_SERVER_APPLICATION.getApplicationId(), applicationInfos.get(0).getApplicationId());
- assertSame(superModelApplicationInfo, applicationInfos.get(1));
- }
-
- @Test
- public void toApplicationInstanceInSingleTenantMode() {
- when(statusProvider.getStatus(any(), any(), any(), any())).thenReturn(ServiceStatus.NOT_CHECKED);
- ConfigserverConfig config = ConfigserverUtil.createExampleConfigserverConfig(true, false);
- DuperModel duperModel = new DuperModel(config);
- SuperModel superModel = mock(SuperModel.class);
- ApplicationInfo superModelApplicationInfo = mock(ApplicationInfo.class);
- when(superModel.getAllApplicationInfos()).thenReturn(Collections.singletonList(superModelApplicationInfo));
- List<ApplicationInfo> applicationInfos = duperModel.getApplicationInfos(superModel);
- assertEquals(1, applicationInfos.size());
- assertSame(superModelApplicationInfo, applicationInfos.get(0));
- }
-}
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/ModelGeneratorTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/ModelGeneratorTest.java
index 5a57451a298..275fa8568c2 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/ModelGeneratorTest.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/ModelGeneratorTest.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.service.monitor.internal;
import com.yahoo.cloud.config.ConfigserverConfig;
+import com.yahoo.config.model.api.ApplicationInfo;
import com.yahoo.config.model.api.SuperModel;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.RegionName;
@@ -11,6 +12,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.service.monitor.application.DuperModel;
import com.yahoo.vespa.service.monitor.ServiceModel;
import com.yahoo.vespa.service.monitor.application.ConfigServerApplication;
import com.yahoo.vespa.service.monitor.internal.slobrok.SlobrokMonitorManagerImpl;
@@ -36,7 +38,8 @@ public class ModelGeneratorTest {
SuperModel superModel = ExampleModel.createExampleSuperModelWithOneRpcPort(HOSTNAME, PORT);
ConfigserverConfig config = ConfigserverUtil.createExampleConfigserverConfig();
- DuperModel duperModel = new DuperModel(config);
+ ApplicationInfo configServerInfo = new ConfigServerApplication().makeApplicationInfoFromConfig(config);
+ DuperModel duperModel = new DuperModel(false, true, true, configServerInfo);
ModelGenerator modelGenerator = new ModelGenerator();
Zone zone = new Zone(Environment.from(ENVIRONMENT), RegionName.from(REGION));
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/SuperModelListenerImplTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/SuperModelListenerImplTest.java
index eb6d6d583f7..e2da7b98f56 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/SuperModelListenerImplTest.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/SuperModelListenerImplTest.java
@@ -5,6 +5,7 @@ import com.yahoo.config.model.api.ApplicationInfo;
import com.yahoo.config.model.api.SuperModel;
import com.yahoo.config.model.api.SuperModelProvider;
import com.yahoo.config.provision.Zone;
+import com.yahoo.vespa.service.monitor.application.DuperModel;
import com.yahoo.vespa.service.monitor.ServiceModel;
import com.yahoo.vespa.service.monitor.internal.slobrok.SlobrokMonitorManagerImpl;
import org.junit.Test;
diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/health/ApplicationHealthMonitorTest.java b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/health/ApplicationHealthMonitorTest.java
index b0fdb14726f..945d6c633af 100644
--- a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/health/ApplicationHealthMonitorTest.java
+++ b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/health/ApplicationHealthMonitorTest.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.service.monitor.internal.health;
import com.yahoo.vespa.applicationmodel.ServiceStatus;
import com.yahoo.vespa.service.monitor.application.ConfigServerApplication;
+import com.yahoo.vespa.service.monitor.application.DuperModel;
import com.yahoo.vespa.service.monitor.internal.ConfigserverUtil;
import org.junit.Test;
@@ -36,6 +37,8 @@ public class ApplicationHealthMonitorTest {
ConfigserverUtil.makeExampleConfigServer(),
monitorFactory);
+ ConfigServerApplication configServerApplication = new ConfigServerApplication();
+
ServiceStatus status1 = applicationMonitor.getStatus(
ConfigServerApplication.CONFIG_SERVER_APPLICATION.getApplicationId(),
ConfigServerApplication.CLUSTER_ID,