aboutsummaryrefslogtreecommitdiffstats
path: root/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/DuperModel.java
diff options
context:
space:
mode:
Diffstat (limited to 'service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/DuperModel.java')
-rw-r--r--service-monitor/src/main/java/com/yahoo/vespa/service/monitor/application/DuperModel.java140
1 files changed, 140 insertions, 0 deletions
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..b28b37006ed
--- /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.
+ // 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;
+ }
+}