diff options
13 files changed, 244 insertions, 161 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/SuperModel.java b/config-model-api/src/main/java/com/yahoo/config/model/api/SuperModel.java new file mode 100644 index 00000000000..d03824120d8 --- /dev/null +++ b/config-model-api/src/main/java/com/yahoo/config/model/api/SuperModel.java @@ -0,0 +1,91 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.config.model.api; + +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.TenantName; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +public class SuperModel { + private final Map<TenantName, Map<ApplicationId, ApplicationInfo>> models; + + public SuperModel() { + this.models = Collections.emptyMap(); + } + + public SuperModel(Map<TenantName, Map<ApplicationId, ApplicationInfo>> models) { + this.models = models; + } + + /** + * Do NOT mutate the returned map. + * TODO: Make the returned map immutable (and type to Map<ApplicationId, ApplicationInfo>) + */ + public Map<TenantName, Map<ApplicationId, ApplicationInfo>> getAllModels() { + return models; + } + + public List<ApplicationInfo> getAllApplicationInfos() { + return models.values().stream().flatMap(entry -> entry.values().stream()).collect(Collectors.toList()); + } + + public Optional<ApplicationInfo> getApplicationInfo(ApplicationId applicationId) { + Map<ApplicationId, ApplicationInfo> tenantInfo = models.get(applicationId.tenant()); + if (tenantInfo == null) { + return Optional.empty(); + } + + ApplicationInfo applicationInfo = tenantInfo.get(applicationId); + if (applicationInfo == null) { + return Optional.empty(); + } + + return Optional.of(applicationInfo); + } + + public SuperModel cloneAndSetApplication(ApplicationInfo application) { + TenantName tenant = application.getApplicationId().tenant(); + Map<TenantName, Map<ApplicationId, ApplicationInfo>> newModels = cloneModels(models); + if (!newModels.containsKey(tenant)) { + // New application has been activated + newModels.put(tenant, new LinkedHashMap<>()); + } else { + // Application has been redeployed + } + + newModels.get(tenant).put(application.getApplicationId(), application); + + return new SuperModel(newModels); + } + + public SuperModel cloneAndRemoveApplication(ApplicationId applicationId) { + Map<TenantName, Map<ApplicationId, ApplicationInfo>> newModels = cloneModels(models); + if (newModels.containsKey(applicationId.tenant())) { + newModels.get(applicationId.tenant()).remove(applicationId); + if (newModels.get(applicationId.tenant()).isEmpty()) { + newModels.remove(applicationId.tenant()); + } + } + + return new SuperModel(newModels); + } + + private static Map<TenantName, Map<ApplicationId, ApplicationInfo>> cloneModels( + Map<TenantName, Map<ApplicationId, ApplicationInfo>> models) { + Map<TenantName, Map<ApplicationId, ApplicationInfo>> newModels = new LinkedHashMap<>(); + for (Map.Entry<TenantName, Map<ApplicationId, ApplicationInfo>> entry : models.entrySet()) { + Map<ApplicationId, ApplicationInfo> appMap = new LinkedHashMap<>(); + newModels.put(entry.getKey(), appMap); + for (Map.Entry<ApplicationId, ApplicationInfo> appEntry : entry.getValue().entrySet()) { + appMap.put(appEntry.getKey(), appEntry.getValue()); + } + } + + return newModels; + } +} diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/SuperModelListener.java b/config-model-api/src/main/java/com/yahoo/config/model/api/SuperModelListener.java index 16580c9e9f6..043e23902b2 100644 --- a/config-model-api/src/main/java/com/yahoo/config/model/api/SuperModelListener.java +++ b/config-model-api/src/main/java/com/yahoo/config/model/api/SuperModelListener.java @@ -11,10 +11,10 @@ public interface SuperModelListener { * Application has been activated: Either deployed the first time, * internally redeployed, or externally triggered redeploy. */ - void applicationActivated(ApplicationInfo application); + void applicationActivated(SuperModel superModel, ApplicationId id); /** * Application has been removed. */ - void applicationRemoved(ApplicationId id); + void applicationRemoved(SuperModel superModel, ApplicationId id); } diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/SuperModelProvider.java b/config-model-api/src/main/java/com/yahoo/config/model/api/SuperModelProvider.java index 42437b20b83..4c7f15143ec 100644 --- a/config-model-api/src/main/java/com/yahoo/config/model/api/SuperModelProvider.java +++ b/config-model-api/src/main/java/com/yahoo/config/model/api/SuperModelProvider.java @@ -1,13 +1,18 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.model.api; -import java.util.List; +import com.yahoo.config.provision.Zone; public interface SuperModelProvider { + SuperModel getSuperModel(); + /** - * Returns all applications in the SuperModel. All changes to the SuperModel + * Returns the current SuperModel. All changes to the SuperModel * following that snapshot will be published to the listener. Warning: The listener * methods may have been invoked before (or concurrently with) this method returning. */ - List<ApplicationInfo> snapshot(SuperModelListener listener); + SuperModel snapshot(SuperModelListener listener); + + // TODO: Remove - clients of SuperModel should get zone from elsewhere. + Zone getZone(); } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelController.java b/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelController.java index 1532c05a56b..8e865f96db3 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelController.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelController.java @@ -13,7 +13,7 @@ import com.yahoo.vespa.config.GetConfigRequest; import com.yahoo.vespa.config.buildergen.ConfigDefinition; import com.yahoo.vespa.config.protocol.ConfigResponse; import com.yahoo.vespa.config.protocol.DefContent; -import com.yahoo.vespa.config.server.model.SuperModel; +import com.yahoo.vespa.config.server.model.SuperModelConfigProvider; import com.yahoo.vespa.config.server.rpc.ConfigResponseFactory; import java.io.IOException; @@ -28,12 +28,12 @@ import java.io.StringReader; */ public class SuperModelController { - private final SuperModel model; + private final SuperModelConfigProvider model; private final long generation; private final ConfigDefinitionRepo configDefinitionRepo; private final ConfigResponseFactory responseFactory; - public SuperModelController(SuperModel model, ConfigDefinitionRepo configDefinitionRepo, long generation, ConfigResponseFactory responseFactory) { + public SuperModelController(SuperModelConfigProvider model, ConfigDefinitionRepo configDefinitionRepo, long generation, ConfigResponseFactory responseFactory) { this.model = model; this.configDefinitionRepo = configDefinitionRepo; this.generation = generation; @@ -68,7 +68,7 @@ public class SuperModelController { } } - public SuperModel getSuperModel() { + public SuperModelConfigProvider getSuperModel() { return model; } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelManager.java b/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelManager.java index 06f7ffa66c4..0ee95ab7e08 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelManager.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelManager.java @@ -5,6 +5,7 @@ package com.yahoo.vespa.config.server; 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.model.api.SuperModelListener; import com.yahoo.config.model.api.SuperModelProvider; import com.yahoo.config.provision.ApplicationId; @@ -12,18 +13,13 @@ import com.yahoo.config.provision.NodeFlavors; import com.yahoo.config.provision.TenantName; import com.yahoo.config.provision.Zone; import com.yahoo.vespa.config.GenerationCounter; -import com.yahoo.vespa.config.server.application.Application; import com.yahoo.vespa.config.server.application.ApplicationSet; -import com.yahoo.vespa.config.server.model.SuperModel; +import com.yahoo.vespa.config.server.model.SuperModelConfigProvider; import java.time.Instant; import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; /** * Provides a SuperModel - a model of all application instances, and makes it stays @@ -31,7 +27,7 @@ import java.util.stream.Collectors; */ public class SuperModelManager implements SuperModelProvider { private final Zone zone; - private SuperModel superModel; // Guarded by 'this' monitor + private SuperModelConfigProvider superModelConfigProvider; // Guarded by 'this' monitor private final List<SuperModelListener> listeners = new ArrayList<>(); // Guarded by 'this' monitor // Generation of the super model @@ -46,11 +42,16 @@ public class SuperModelManager implements SuperModelProvider { this.zone = new Zone(configserverConfig, nodeFlavors); this.generationCounter = generationCounter; this.masterGeneration = configserverConfig.masterGeneration(); - makeNewSuperModel(new HashMap<>()); + makeNewSuperModelConfigProvider(new SuperModel()); } + @Override public synchronized SuperModel getSuperModel() { - return superModel; + return superModelConfigProvider.getSuperModel(); + } + + public synchronized SuperModelConfigProvider getSuperModelConfigProvider() { + return superModelConfigProvider; } public synchronized long getGeneration() { @@ -58,60 +59,41 @@ public class SuperModelManager implements SuperModelProvider { } @Override - public synchronized List<ApplicationInfo> snapshot(SuperModelListener listener) { + public synchronized SuperModel snapshot(SuperModelListener listener) { listeners.add(listener); - return superModel.applicationModels().values().stream() - .flatMap(applications -> applications.values().stream()) - .map(Application::toApplicationInfo) - .collect(Collectors.toList()); + return superModelConfigProvider.getSuperModel(); } - public synchronized void configActivated(TenantName tenant, ApplicationSet applicationSet) { - Map<TenantName, Map<ApplicationId, Application>> newModels = createModelCopy(); - if (!newModels.containsKey(tenant)) { - // New application has been activated - newModels.put(tenant, new LinkedHashMap<>()); - } else { - // Application has been redeployed - } + @Override + public Zone getZone() { + return zone; + } + public synchronized void configActivated(TenantName tenant, ApplicationSet applicationSet) { // TODO: Should supermodel care about multiple versions? - Application application = applicationSet.getForVersionOrLatest(Optional.empty(), Instant.now()); - newModels.get(tenant).put(applicationSet.getId(), application); - - makeNewSuperModel(newModels); - listeners.stream().forEach(listener -> listener.applicationActivated(application.toApplicationInfo())); + ApplicationInfo applicationInfo = applicationSet + .getForVersionOrLatest(Optional.empty(), Instant.now()) + .toApplicationInfo(); + + SuperModel newSuperModel = this.superModelConfigProvider + .getSuperModel() + .cloneAndSetApplication(applicationInfo); + makeNewSuperModelConfigProvider(newSuperModel); + listeners.stream().forEach(listener -> + listener.applicationActivated(newSuperModel, applicationInfo.getApplicationId())); } public synchronized void applicationRemoved(ApplicationId applicationId) { - Map<TenantName, Map<ApplicationId, Application>> newModels = createModelCopy(); - if (newModels.containsKey(applicationId.tenant())) { - newModels.get(applicationId.tenant()).remove(applicationId); - if (newModels.get(applicationId.tenant()).isEmpty()) { - newModels.remove(applicationId.tenant()); - } - } - - makeNewSuperModel(newModels); - listeners.stream().forEach(listener -> listener.applicationRemoved(applicationId)); + SuperModel newSuperModel = this.superModelConfigProvider + .getSuperModel() + .cloneAndRemoveApplication(applicationId); + makeNewSuperModelConfigProvider(newSuperModel); + listeners.stream().forEach(listener -> + listener.applicationRemoved(newSuperModel, applicationId)); } - private void makeNewSuperModel(Map<TenantName, Map<ApplicationId, Application>> newModels) { + private void makeNewSuperModelConfigProvider(SuperModel newSuperModel) { generation = masterGeneration + generationCounter.get(); - superModel = new SuperModel(newModels, zone); - } - - private Map<TenantName, Map<ApplicationId, Application>> createModelCopy() { - Map<TenantName, Map<ApplicationId, Application>> currentModels = superModel.applicationModels(); - Map<TenantName, Map<ApplicationId, Application>> newModels = new LinkedHashMap<>(); - for (Map.Entry<TenantName, Map<ApplicationId, Application>> entry : currentModels.entrySet()) { - Map<ApplicationId, Application> appMap = new LinkedHashMap<>(); - newModels.put(entry.getKey(), appMap); - for (Map.Entry<ApplicationId, Application> appEntry : entry.getValue().entrySet()) { - appMap.put(appEntry.getKey(), appEntry.getValue()); - } - } - - return newModels; + superModelConfigProvider = new SuperModelConfigProvider(newSuperModel, zone); } } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelRequestHandler.java b/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelRequestHandler.java index 95f16a7c1e7..8db7ee9ffc3 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelRequestHandler.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/SuperModelRequestHandler.java @@ -5,14 +5,11 @@ import com.google.inject.Inject; import com.yahoo.cloud.config.ConfigserverConfig; import com.yahoo.config.ConfigInstance; import com.yahoo.config.model.api.ConfigDefinitionRepo; -import com.yahoo.config.provision.NodeFlavors; import com.yahoo.config.provision.Version; import com.yahoo.log.LogLevel; import com.yahoo.vespa.config.ConfigKey; -import com.yahoo.vespa.config.GenerationCounter; import com.yahoo.vespa.config.GetConfigRequest; import com.yahoo.vespa.config.protocol.ConfigResponse; -import com.yahoo.vespa.config.server.application.Application; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.TenantName; import com.yahoo.vespa.config.server.application.ApplicationSet; @@ -20,8 +17,6 @@ import com.yahoo.vespa.config.server.rpc.ConfigResponseFactory; import com.yahoo.vespa.config.server.rpc.ConfigResponseFactoryFactory; import java.io.IOException; -import java.util.LinkedHashMap; -import java.util.Map; import java.util.Optional; import java.util.Set; @@ -72,7 +67,7 @@ public class SuperModelRequestHandler implements RequestHandler { private void updateHandler() { handler = new SuperModelController( - superModelManager.getSuperModel(), + superModelManager.getSuperModelConfigProvider(), configDefinitionRepo, superModelManager.getGeneration(), responseFactory); diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/model/LbServicesProducer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/model/LbServicesProducer.java index f9665262d76..1806414f510 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/model/LbServicesProducer.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/model/LbServicesProducer.java @@ -1,20 +1,21 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.config.server.model; +import com.google.common.base.Joiner; +import com.yahoo.cloud.config.LbServicesConfig; +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.provision.ApplicationId; +import com.yahoo.config.provision.TenantName; +import com.yahoo.config.provision.Zone; + import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; -import com.google.common.base.Joiner; -import com.yahoo.config.model.api.HostInfo; -import com.yahoo.config.model.api.ServiceInfo; -import com.yahoo.cloud.config.LbServicesConfig; -import com.yahoo.config.provision.Zone; -import com.yahoo.vespa.config.server.application.Application; -import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.TenantName; /** * Produces lb-services cfg @@ -24,10 +25,10 @@ import com.yahoo.config.provision.TenantName; */ public class LbServicesProducer implements LbServicesConfig.Producer { - private final Map<TenantName, Map<ApplicationId, Application>> models; + private final Map<TenantName, Map<ApplicationId, ApplicationInfo>> models; private final Zone zone; - public LbServicesProducer(Map<TenantName, Map<ApplicationId, Application>> models, Zone zone) { + public LbServicesProducer(Map<TenantName, Map<ApplicationId, ApplicationInfo>> models, Zone zone) { this.models = models; this.zone = zone; } @@ -41,7 +42,7 @@ public class LbServicesProducer implements LbServicesConfig.Producer { }); } - private LbServicesConfig.Tenants.Builder getTenantConfig(Map<ApplicationId, Application> apps) { + private LbServicesConfig.Tenants.Builder getTenantConfig(Map<ApplicationId, ApplicationInfo> apps) { LbServicesConfig.Tenants.Builder tb = new LbServicesConfig.Tenants.Builder(); apps.keySet().stream() .sorted() @@ -55,7 +56,7 @@ public class LbServicesProducer implements LbServicesConfig.Producer { return applicationId.application().value() + ":" + zone.environment().value() + ":" + zone.region().value() + ":" + applicationId.instance().value(); } - private LbServicesConfig.Tenants.Applications.Builder getAppConfig(Application app) { + private LbServicesConfig.Tenants.Applications.Builder getAppConfig(ApplicationInfo app) { LbServicesConfig.Tenants.Applications.Builder ab = new LbServicesConfig.Tenants.Applications.Builder(); ab.activeRotation(getActiveRotation(app)); app.getModel().getHosts().stream() @@ -66,7 +67,7 @@ public class LbServicesProducer implements LbServicesConfig.Producer { return ab; } - private boolean getActiveRotation(Application app) { + private boolean getActiveRotation(ApplicationInfo app) { boolean activeRotation = false; for (HostInfo hostInfo : app.getModel().getHosts()) { final Optional<ServiceInfo> container = hostInfo.getServices().stream().filter( diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/model/RoutingProducer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/model/RoutingProducer.java index c8d94235abc..850b3f99d16 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/model/RoutingProducer.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/model/RoutingProducer.java @@ -2,11 +2,11 @@ package com.yahoo.vespa.config.server.model; import com.yahoo.cloud.config.RoutingConfig; +import com.yahoo.config.model.api.ApplicationInfo; import com.yahoo.config.model.api.HostInfo; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ApplicationName; import com.yahoo.config.provision.TenantName; -import com.yahoo.vespa.config.server.application.Application; import com.yahoo.vespa.config.server.tenant.Tenants; import java.util.Map; @@ -20,20 +20,22 @@ import java.util.Map; public class RoutingProducer implements RoutingConfig.Producer { static final ApplicationName ROUTING_APPLICATION = ApplicationName.from("routing"); - private final Map<TenantName, Map<ApplicationId, Application>> models; + private final Map<TenantName, Map<ApplicationId, ApplicationInfo>> models; - public RoutingProducer(Map<TenantName, Map<ApplicationId, Application>> models) { + public RoutingProducer(Map<TenantName, Map<ApplicationId, ApplicationInfo>> models) { this.models = models; } @Override public void getConfig(RoutingConfig.Builder builder) { - for (Map<ApplicationId, Application> model : models.values()) { - model.values().stream().filter(application -> isHostedVespaRoutingApplication(application.getId())).forEach(application -> { - for (HostInfo host : application.getModel().getHosts()) { - builder.hosts(host.getHostname()); - } - }); + for (Map<ApplicationId, ApplicationInfo> model : models.values()) { + model.values().stream() + .filter(application -> isHostedVespaRoutingApplication(application.getApplicationId())) + .forEach(application -> { + for (HostInfo host : application.getModel().getHosts()) { + builder.hosts(host.getHostname()); + } + }); } } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/model/SuperModel.java b/configserver/src/main/java/com/yahoo/vespa/config/server/model/SuperModelConfigProvider.java index eb41373aab8..e087ef64ae3 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/model/SuperModel.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/model/SuperModelConfigProvider.java @@ -5,15 +5,15 @@ import com.yahoo.cloud.config.LbServicesConfig; import com.yahoo.cloud.config.RoutingConfig; import com.yahoo.config.ConfigInstance; import com.yahoo.config.ConfigurationRuntimeException; +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.TenantName; import com.yahoo.config.provision.Zone; import com.yahoo.vespa.config.ConfigKey; import com.yahoo.vespa.config.ConfigPayload; -import com.yahoo.vespa.config.server.application.Application; import java.util.Collections; -import java.util.LinkedHashMap; import java.util.Map; /** @@ -22,16 +22,20 @@ import java.util.Map; * @author vegardh * @since 5.9 */ -public class SuperModel implements LbServicesConfig.Producer, RoutingConfig.Producer { +public class SuperModelConfigProvider implements LbServicesConfig.Producer, RoutingConfig.Producer { - private final Map<TenantName, Map<ApplicationId, Application>> models; + private final SuperModel superModel; private final LbServicesProducer lbProd; private final RoutingProducer zoneProd; - public SuperModel(Map<TenantName, Map<ApplicationId, Application>> models, Zone zone) { - this.models = models; - this.lbProd = new LbServicesProducer(Collections.unmodifiableMap(models), zone); - this.zoneProd = new RoutingProducer(Collections.unmodifiableMap(models)); + public SuperModelConfigProvider(SuperModel superModel, Zone zone) { + this.superModel = superModel; + this.lbProd = new LbServicesProducer(Collections.unmodifiableMap(superModel.getAllModels()), zone); + this.zoneProd = new RoutingProducer(Collections.unmodifiableMap(superModel.getAllModels())); + } + + public SuperModel getSuperModel() { + return superModel; } public ConfigPayload getConfig(ConfigKey<?> configKey) { @@ -49,7 +53,7 @@ public class SuperModel implements LbServicesConfig.Producer, RoutingConfig.Prod } } - public Map<TenantName, Map<ApplicationId, Application>> applicationModels() { return models; } + public Map<TenantName, Map<ApplicationId, ApplicationInfo>> applicationModels() { return superModel.getAllModels(); } @Override public void getConfig(LbServicesConfig.Builder builder) { @@ -65,14 +69,14 @@ public class SuperModel implements LbServicesConfig.Producer, RoutingConfig.Prod ApplicationId applicationId, String configId) { TenantName tenant = applicationId.tenant(); - if (!models.containsKey(tenant)) { + if (!superModel.getAllModels().containsKey(tenant)) { throw new IllegalArgumentException("Tenant " + tenant + " not found"); } - Map<ApplicationId, Application> applications = models.get(tenant); + Map<ApplicationId, ApplicationInfo> applications = superModel.getAllModels().get(tenant); if (!applications.containsKey(applicationId)) { throw new IllegalArgumentException("Application id " + applicationId + " not found"); } - Application application = applications.get(applicationId); + ApplicationInfo application = applications.get(applicationId); ConfigKey<CONFIGTYPE> key = new ConfigKey<>(configClass, configId); ConfigPayload payload = application.getModel().getConfig(key, null); return payload.toInstance(configClass, configId); diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelControllerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelControllerTest.java index e4835f47e48..c10d5123ea7 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelControllerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelControllerTest.java @@ -2,22 +2,26 @@ package com.yahoo.vespa.config.server; import com.yahoo.cloud.config.LbServicesConfig; +import com.yahoo.cloud.config.LbServicesConfig.Tenants.Applications; +import com.yahoo.config.model.api.ApplicationInfo; +import com.yahoo.config.model.api.SuperModel; import com.yahoo.config.model.application.provider.FilesApplicationPackage; -import com.yahoo.config.provision.*; +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.ApplicationName; +import com.yahoo.config.provision.InstanceName; +import com.yahoo.config.provision.TenantName; +import com.yahoo.config.provision.Version; +import com.yahoo.config.provision.Zone; import com.yahoo.jrt.Request; import com.yahoo.vespa.config.ConfigKey; -import com.yahoo.cloud.config.LbServicesConfig.Tenants.Applications; import com.yahoo.vespa.config.protocol.CompressionType; import com.yahoo.vespa.config.protocol.DefContent; import com.yahoo.vespa.config.protocol.JRTClientConfigRequestV3; import com.yahoo.vespa.config.protocol.JRTServerConfigRequestV3; import com.yahoo.vespa.config.protocol.Trace; -import com.yahoo.vespa.config.server.application.Application; -import com.yahoo.vespa.config.server.model.SuperModel; -import com.yahoo.vespa.config.server.monitoring.MetricUpdater; +import com.yahoo.vespa.config.server.model.SuperModelConfigProvider; import com.yahoo.vespa.config.server.rpc.UncompressedConfigResponseFactory; import com.yahoo.vespa.model.VespaModel; - import org.junit.Before; import org.junit.Test; import org.xml.sax.SAXException; @@ -43,13 +47,14 @@ public class SuperModelControllerTest { @Before public void setupHandler() throws IOException, SAXException { - Map<TenantName, Map<ApplicationId, Application>> models = new LinkedHashMap<>(); + Map<TenantName, Map<ApplicationId, ApplicationInfo>> models = new LinkedHashMap<>(); models.put(TenantName.from("a"), new LinkedHashMap<>()); File testApp = new File("src/test/resources/deploy/app"); ApplicationId app = ApplicationId.from(TenantName.from("a"), ApplicationName.from("foo"), InstanceName.defaultName()); - models.get(app.tenant()).put(app, new Application(new VespaModel(FilesApplicationPackage.fromFile(testApp)), new ServerCache(), 4l, Version.fromIntValues(1, 2, 3), MetricUpdater.createTestUpdater(), app)); - handler = new SuperModelController(new SuperModel(models, Zone.defaultZone()), new TestConfigDefinitionRepo(), 2, new UncompressedConfigResponseFactory()); + models.get(app.tenant()).put(app, new ApplicationInfo(app, 4l, new VespaModel(FilesApplicationPackage.fromFile(testApp)))); + SuperModel superModel = new SuperModel(models); + handler = new SuperModelController(new SuperModelConfigProvider(superModel, Zone.defaultZone()), new TestConfigDefinitionRepo(), 2, new UncompressedConfigResponseFactory()); } @Test @@ -77,7 +82,7 @@ public class SuperModelControllerTest { @Test public void test_lb_config_multiple_apps() throws IOException, SAXException { - Map<TenantName, Map<ApplicationId, Application>> models = new LinkedHashMap<>(); + Map<TenantName, Map<ApplicationId, ApplicationInfo>> models = new LinkedHashMap<>(); models.put(TenantName.from("t1"), new LinkedHashMap<>()); models.put(TenantName.from("t2"), new LinkedHashMap<>()); File testApp1 = new File("src/test/resources/deploy/app"); @@ -86,13 +91,13 @@ public class SuperModelControllerTest { // TODO must fix equals, hashCode on Tenant Version vespaVersion = Version.fromIntValues(1, 2, 3); models.get(TenantName.from("t1")).put(applicationId("mysimpleapp"), - new Application(new VespaModel(FilesApplicationPackage.fromFile(testApp1)), new ServerCache(), 4l, vespaVersion, MetricUpdater.createTestUpdater(), applicationId("mysimpleapp"))); + new ApplicationInfo(applicationId("mysimpleapp"), 4l, new VespaModel(FilesApplicationPackage.fromFile(testApp1)))); models.get(TenantName.from("t1")).put(applicationId("myadvancedapp"), - new Application(new VespaModel(FilesApplicationPackage.fromFile(testApp2)), new ServerCache(), 4l, vespaVersion, MetricUpdater.createTestUpdater(), applicationId("myadvancedapp"))); + new ApplicationInfo(applicationId("myadvancedapp"), 4l, new VespaModel(FilesApplicationPackage.fromFile(testApp2)))); models.get(TenantName.from("t2")).put(applicationId("minetooadvancedapp"), - new Application(new VespaModel(FilesApplicationPackage.fromFile(testApp3)), new ServerCache(), 4l, vespaVersion, MetricUpdater.createTestUpdater(), applicationId("minetooadvancedapp"))); - - SuperModelController han = new SuperModelController(new SuperModel(models, Zone.defaultZone()), new TestConfigDefinitionRepo(), 2, new UncompressedConfigResponseFactory()); + new ApplicationInfo(applicationId("minetooadvancedapp"), 4l, new VespaModel(FilesApplicationPackage.fromFile(testApp3)))); + SuperModel superModel = new SuperModel(models); + SuperModelController han = new SuperModelController(new SuperModelConfigProvider(superModel, Zone.defaultZone()), new TestConfigDefinitionRepo(), 2, new UncompressedConfigResponseFactory()); LbServicesConfig.Builder lb = new LbServicesConfig.Builder(); han.getSuperModel().getConfig(lb); LbServicesConfig lbc = new LbServicesConfig(lb); diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelRequestHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelRequestHandlerTest.java index 4c746eba64e..bc07ac7d79c 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelRequestHandlerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/SuperModelRequestHandlerTest.java @@ -61,7 +61,7 @@ public class SuperModelRequestHandlerTest { assertThat(controller.getHandler().getGeneration(), is(gen)); // Test that a new app is used when there already exist an application with the same id ApplicationId appId = new ApplicationId.Builder().tenant(tenantA).applicationName("foo").build(); - assertThat(((TestApplication) controller.getHandler().getSuperModel().applicationModels().get(tenantA).get(appId)).version, is(2l)); + assertThat(controller.getHandler().getSuperModel().applicationModels().get(tenantA).get(appId).getGeneration(), is(4l)); gen = counter.increment(); controller.reloadConfig(tenantA, createApp(tenantA, "bar", 2l, 3)); assertThat(controller.getHandler().getGeneration(), is(gen)); diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/model/LbServicesProducerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/model/LbServicesProducerTest.java index 4d7f33e6ef9..474b93f6972 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/model/LbServicesProducerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/model/LbServicesProducerTest.java @@ -4,6 +4,7 @@ package com.yahoo.vespa.config.server.model; import com.yahoo.cloud.config.LbServicesConfig; import com.yahoo.config.application.api.ApplicationPackage; import com.yahoo.config.model.NullConfigModelRegistry; +import com.yahoo.config.model.api.ApplicationInfo; import com.yahoo.config.model.api.Model; import com.yahoo.config.model.deploy.DeployProperties; import com.yahoo.config.model.deploy.DeployState; @@ -13,18 +14,20 @@ import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.RegionName; import com.yahoo.config.provision.Rotation; import com.yahoo.config.provision.TenantName; -import com.yahoo.config.provision.Version; import com.yahoo.config.provision.Zone; import com.yahoo.vespa.config.ConfigPayload; -import com.yahoo.vespa.config.server.ServerCache; -import com.yahoo.vespa.config.server.application.Application; -import com.yahoo.vespa.config.server.monitoring.MetricUpdater; import com.yahoo.vespa.model.VespaModel; import org.junit.Test; import org.xml.sax.SAXException; import java.io.IOException; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.Set; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertFalse; @@ -43,7 +46,7 @@ public class LbServicesProducerTest { @Test public void testDeterministicGetConfig() throws IOException, SAXException { - Map<TenantName, Map<ApplicationId, Application>> testModel = createTestModel(new DeployState.Builder().rotations(rotations)); + Map<TenantName, Map<ApplicationId, ApplicationInfo>> testModel = createTestModel(new DeployState.Builder().rotations(rotations)); LbServicesConfig last = null; for (int i = 0; i < 100; i++) { testModel = randomizeTenant(testModel, i); @@ -57,7 +60,7 @@ public class LbServicesProducerTest { @Test public void testConfigAliases() throws IOException, SAXException { - Map<TenantName, Map<ApplicationId, Application>> testModel = createTestModel(new DeployState.Builder()); + Map<TenantName, Map<ApplicationId, ApplicationInfo>> testModel = createTestModel(new DeployState.Builder()); LbServicesConfig conf = getLbServicesConfig(Zone.defaultZone(), testModel); final LbServicesConfig.Tenants.Applications.Hosts.Services services = conf.tenants("foo").applications("foo:prod:default:default").hosts("foo.foo.yahoo.com").services("qrserver"); assertThat(services.servicealiases().size(), is(1)); @@ -85,12 +88,12 @@ public class LbServicesProducerTest { private LbServicesConfig createModelAndGetLbServicesConfig(RegionName regionName) throws IOException, SAXException { final Zone zone = new Zone(Environment.prod, regionName); - Map<TenantName, Map<ApplicationId, Application>> testModel = createTestModel(new DeployState.Builder(). + Map<TenantName, Map<ApplicationId, ApplicationInfo>> testModel = createTestModel(new DeployState.Builder(). properties(new DeployProperties.Builder().zone(zone).build())); return getLbServicesConfig(new Zone(Environment.prod, regionName), testModel); } - private LbServicesConfig getLbServicesConfig(Zone zone, Map<TenantName, Map<ApplicationId, Application>> testModel) { + private LbServicesConfig getLbServicesConfig(Zone zone, Map<TenantName, Map<ApplicationId, ApplicationInfo>> testModel) { LbServicesProducer producer = new LbServicesProducer(testModel, zone); LbServicesConfig.Builder builder = new LbServicesConfig.Builder(); producer.getConfig(builder); @@ -99,7 +102,7 @@ public class LbServicesProducerTest { @Test public void testConfigAliasesWithRotations() throws IOException, SAXException { - Map<TenantName, Map<ApplicationId, Application>> testModel = createTestModel(new DeployState.Builder().rotations(rotations)); + Map<TenantName, Map<ApplicationId, ApplicationInfo>> testModel = createTestModel(new DeployState.Builder().rotations(rotations)); RegionName regionName = RegionName.from("us-east-1"); LbServicesConfig conf = getLbServicesConfig(new Zone(Environment.prod, regionName), testModel); final LbServicesConfig.Tenants.Applications.Hosts.Services services = conf.tenants("foo").applications("foo:prod:" + regionName.value() + ":default").hosts("foo.foo.yahoo.com").services("qrserver"); @@ -113,8 +116,8 @@ public class LbServicesProducerTest { assertThat(services.endpointaliases(3), is(rotation2)); } - private Map<TenantName, Map<ApplicationId, Application>> randomizeTenant(Map<TenantName, Map<ApplicationId, Application>> testModel, int seed) { - Map<TenantName, Map<ApplicationId, Application>> randomizedTenants = new LinkedHashMap<>(); + private Map<TenantName, Map<ApplicationId, ApplicationInfo>> randomizeTenant(Map<TenantName, Map<ApplicationId, ApplicationInfo>> testModel, int seed) { + Map<TenantName, Map<ApplicationId, ApplicationInfo>> randomizedTenants = new LinkedHashMap<>(); List<TenantName> keys = new ArrayList<>(testModel.keySet()); Collections.shuffle(keys, new Random(seed)); for (TenantName key : keys) { @@ -123,8 +126,8 @@ public class LbServicesProducerTest { return randomizedTenants; } - private Map<ApplicationId, Application> randomizeApplications(Map<ApplicationId, Application> applicationIdApplicationMap, int seed) { - Map<ApplicationId, Application> randomizedApplications = new LinkedHashMap<>(); + private Map<ApplicationId, ApplicationInfo> randomizeApplications(Map<ApplicationId, ApplicationInfo> applicationIdApplicationMap, int seed) { + Map<ApplicationId, ApplicationInfo> randomizedApplications = new LinkedHashMap<>(); List<ApplicationId> keys = new ArrayList<>(applicationIdApplicationMap.keySet()); Collections.shuffle(keys, new Random(seed)); for (ApplicationId key : keys) { @@ -133,8 +136,8 @@ public class LbServicesProducerTest { return randomizedApplications; } - private Map<TenantName, Map<ApplicationId, Application>> createTestModel(DeployState.Builder deployStateBuilder) throws IOException, SAXException { - Map<TenantName, Map<ApplicationId, Application>> tMap = new LinkedHashMap<>(); + private Map<TenantName, Map<ApplicationId, ApplicationInfo>> createTestModel(DeployState.Builder deployStateBuilder) throws IOException, SAXException { + Map<TenantName, Map<ApplicationId, ApplicationInfo>> tMap = new LinkedHashMap<>(); TenantName foo = TenantName.from("foo"); TenantName bar = TenantName.from("bar"); TenantName baz = TenantName.from("baz"); @@ -144,8 +147,8 @@ public class LbServicesProducerTest { return tMap; } - private Map<ApplicationId, Application> createTestApplications(TenantName tenant, DeployState.Builder deploystateBuilder) throws IOException, SAXException { - Map<ApplicationId, Application> aMap = new LinkedHashMap<>(); + private Map<ApplicationId, ApplicationInfo> createTestApplications(TenantName tenant, DeployState.Builder deploystateBuilder) throws IOException, SAXException { + Map<ApplicationId, ApplicationInfo> aMap = new LinkedHashMap<>(); ApplicationId fooApp = new ApplicationId.Builder().tenant(tenant).applicationName("foo").build(); ApplicationId barApp = new ApplicationId.Builder().tenant(tenant).applicationName("bar").build(); ApplicationId bazApp = new ApplicationId.Builder().tenant(tenant).applicationName("baz").build(); @@ -155,15 +158,13 @@ public class LbServicesProducerTest { return aMap; } - private Application createApplication(ApplicationId appId, DeployState.Builder deploystateBuilder) throws IOException, SAXException { - return new Application(createVespaModel(createApplicationPackage( - appId.tenant() + "." + appId.application() + ".yahoo.com", appId.tenant().value() + "." + appId.application().value() + "2.yahoo.com"), - deploystateBuilder), - new ServerCache(), + private ApplicationInfo createApplication(ApplicationId appId, DeployState.Builder deploystateBuilder) throws IOException, SAXException { + return new ApplicationInfo( + appId, 3l, - Version.fromIntValues(1, 2, 3), - MetricUpdater.createTestUpdater(), - appId); + createVespaModel(createApplicationPackage( + appId.tenant() + "." + appId.application() + ".yahoo.com", appId.tenant().value() + "." + appId.application().value() + "2.yahoo.com"), + deploystateBuilder)); } private ApplicationPackage createApplicationPackage(String host1, String host2) { diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/model/RoutingProducerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/model/RoutingProducerTest.java index f50dc7828b0..25030332664 100755 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/model/RoutingProducerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/model/RoutingProducerTest.java @@ -4,15 +4,12 @@ package com.yahoo.vespa.config.server.model; import com.yahoo.cloud.config.RoutingConfig; import com.yahoo.config.application.api.ApplicationPackage; import com.yahoo.config.model.NullConfigModelRegistry; +import com.yahoo.config.model.api.ApplicationInfo; import com.yahoo.config.model.api.Model; import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.test.MockApplicationPackage; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.TenantName; -import com.yahoo.config.provision.Version; -import com.yahoo.vespa.config.server.ServerCache; -import com.yahoo.vespa.config.server.application.Application; -import com.yahoo.vespa.config.server.monitoring.MetricUpdater; import com.yahoo.vespa.config.server.tenant.Tenants; import com.yahoo.vespa.model.VespaModel; import org.junit.Test; @@ -31,7 +28,7 @@ import static org.junit.Assert.assertThat; public class RoutingProducerTest { @Test public void testNodesFromRoutingAppOnly() throws Exception { - Map<TenantName, Map<ApplicationId, Application>> testModel = createTestModel(new DeployState.Builder()); + Map<TenantName, Map<ApplicationId, ApplicationInfo>> testModel = createTestModel(new DeployState.Builder()); RoutingProducer producer = new RoutingProducer(testModel); RoutingConfig.Builder builder = new RoutingConfig.Builder(); producer.getConfig(builder); @@ -41,8 +38,8 @@ public class RoutingProducerTest { assertThat(config.hosts(1), is("hosted-vespa.routing2.yahoo.com")); } - private Map<TenantName, Map<ApplicationId, Application>> createTestModel(DeployState.Builder deployStateBuilder) throws IOException, SAXException { - Map<TenantName, Map<ApplicationId, Application>> tMap = new LinkedHashMap<>(); + private Map<TenantName, Map<ApplicationId, ApplicationInfo>> createTestModel(DeployState.Builder deployStateBuilder) throws IOException, SAXException { + Map<TenantName, Map<ApplicationId, ApplicationInfo>> tMap = new LinkedHashMap<>(); TenantName foo = TenantName.from("foo"); TenantName bar = TenantName.from("bar"); TenantName routing = TenantName.from(Tenants.HOSTED_VESPA_TENANT.value()); @@ -52,8 +49,8 @@ public class RoutingProducerTest { return tMap; } - private Map<ApplicationId, Application> createTestApplications(TenantName tenant, DeployState.Builder deploystateBuilder) throws IOException, SAXException { - Map<ApplicationId, Application> aMap = new LinkedHashMap<>(); + private Map<ApplicationId, ApplicationInfo> createTestApplications(TenantName tenant, DeployState.Builder deploystateBuilder) throws IOException, SAXException { + Map<ApplicationId, ApplicationInfo> aMap = new LinkedHashMap<>(); ApplicationId fooApp = new ApplicationId.Builder().tenant(tenant).applicationName("foo").build(); ApplicationId barApp = new ApplicationId.Builder().tenant(tenant).applicationName("bar").build(); ApplicationId routingApp = new ApplicationId.Builder().tenant(tenant).applicationName(RoutingProducer.ROUTING_APPLICATION.value()).build(); @@ -63,15 +60,15 @@ public class RoutingProducerTest { return aMap; } - private Application createApplication(ApplicationId appId, DeployState.Builder deploystateBuilder) throws IOException, SAXException { - return new Application(createVespaModel(createApplicationPackage( - appId.tenant() + "." + appId.application() + ".yahoo.com", appId.tenant().value() + "." + appId.application().value() + "2.yahoo.com"), - deploystateBuilder), - new ServerCache(), + private ApplicationInfo createApplication(ApplicationId appId, DeployState.Builder deploystateBuilder) throws IOException, SAXException { + return new ApplicationInfo( + appId, 3l, - Version.fromIntValues(1, 2, 3), - MetricUpdater.createTestUpdater(), - appId); + createVespaModel( + createApplicationPackage( + appId.tenant() + "." + appId.application() + ".yahoo.com", + appId.tenant().value() + "." + appId.application().value() + "2.yahoo.com"), + deploystateBuilder)); } private ApplicationPackage createApplicationPackage(String host1, String host2) { |