diff options
author | Harald Musum <musum@oath.com> | 2018-11-05 14:54:52 +0100 |
---|---|---|
committer | Harald Musum <musum@oath.com> | 2018-11-05 17:43:05 +0100 |
commit | 6630d84ae7856c26c00f5f1d10e1c0a3e304170f (patch) | |
tree | 1f55749a8d903398069a2ea6e95f5a45c783406d | |
parent | e5d0e505d22f728ff97da039c6eceb5860147511 (diff) |
Use simpler map for models
Need to keep old constructor and make a temporary one with an ignored
argument to make this work (since arguments will be equal due to type erasure)
4 files changed, 110 insertions, 77 deletions
diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java index 140a7f71c16..a21c65c40d5 100644 --- a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java +++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java @@ -193,13 +193,12 @@ public class InstanceValidatorTest { private SuperModelProvider mockSuperModelProvider(ApplicationInfo... appInfos) { SuperModel superModel = new SuperModel(Stream.of(appInfos) - .collect(Collectors.groupingBy( - appInfo -> appInfo.getApplicationId().tenant(), - Collectors.toMap( - ApplicationInfo::getApplicationId, - Function.identity() - ) - ))); + .collect(Collectors.toMap( + ApplicationInfo::getApplicationId, + Function.identity() + ) + ), + false); SuperModelProvider superModelProvider = mock(SuperModelProvider.class); when(superModelProvider.getSuperModel()).thenReturn(superModel); 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 index d03824120d8..dccbc143c01 100644 --- 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 @@ -1,24 +1,35 @@ // 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.google.common.collect.ImmutableMap; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.TenantName; +import java.util.ArrayList; 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; + + private final Map<ApplicationId, ApplicationInfo> models; public SuperModel() { this.models = Collections.emptyMap(); } + // TODO: Remove when oldest model used is 6.309 or newer public SuperModel(Map<TenantName, Map<ApplicationId, ApplicationInfo>> models) { + this.models = new LinkedHashMap<>(); + models.values().forEach(entry -> entry.forEach(this.models::put)); + } + + // TODO: The ignored parameter is just to circumvent the fact that you cannot have + // two constructors with same type erasure, the above will be removed and this one can + // be fixed + public SuperModel(Map<ApplicationId, ApplicationInfo> models, boolean ignored) { this.models = models; } @@ -27,65 +38,45 @@ public class SuperModel { * TODO: Make the returned map immutable (and type to Map<ApplicationId, ApplicationInfo>) */ public Map<TenantName, Map<ApplicationId, ApplicationInfo>> getAllModels() { - return models; + Map<TenantName, Map<ApplicationId, ApplicationInfo>> newModels = new LinkedHashMap<>(); + + this.models.forEach((key, value) -> { + if (!newModels.containsKey(key.tenant())) { + newModels.put(key.tenant(), new LinkedHashMap<>()); + } + newModels.get(key.tenant()).put(key, value); + }); + return newModels ; + } + + public Map<ApplicationId, ApplicationInfo> getModels() { + return ImmutableMap.copyOf(models); } public List<ApplicationInfo> getAllApplicationInfos() { - return models.values().stream().flatMap(entry -> entry.values().stream()).collect(Collectors.toList()); + return new ArrayList<>(models.values()); } 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); + ApplicationInfo applicationInfo = models.get(applicationId); + return applicationInfo == null ? Optional.empty() : 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); + Map<ApplicationId, ApplicationInfo> newModels = cloneModels(models); + newModels.put(application.getApplicationId(), application); + + return new SuperModel(newModels, false); } 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()); - } - } + Map<ApplicationId, ApplicationInfo> newModels = cloneModels(models); + newModels.remove(applicationId); - return new SuperModel(newModels); + return new SuperModel(newModels, false); } - 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; + private static Map<ApplicationId, ApplicationInfo> cloneModels(Map<ApplicationId, ApplicationInfo> models) { + return new LinkedHashMap<>(models); } } 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 323b52ee4ac..b7ca52390ed 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 @@ -6,6 +6,8 @@ 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.model.deploy.DeployProperties; +import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ApplicationName; import com.yahoo.config.provision.InstanceName; @@ -39,7 +41,6 @@ import static org.junit.Assert.assertTrue; /** * @author Ulf Lilleengen - * @since 5.9 */ public class SuperModelControllerTest { @@ -47,13 +48,13 @@ public class SuperModelControllerTest { @Before public void setupHandler() throws IOException, SAXException { - Map<TenantName, Map<ApplicationId, ApplicationInfo>> models = new LinkedHashMap<>(); - models.put(TenantName.from("a"), new LinkedHashMap<>()); + Map<ApplicationId, ApplicationInfo> models = 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 ApplicationInfo(app, 4l, new VespaModel(FilesApplicationPackage.fromFile(testApp)))); - SuperModel superModel = new SuperModel(models); + models.put(app, new ApplicationInfo(app, 4l, new VespaModel(FilesApplicationPackage.fromFile(testApp)))); + SuperModel superModel = new SuperModel(models, false); handler = new SuperModelController(new SuperModelConfigProvider(superModel, Zone.defaultZone()), new TestConfigDefinitionRepo(), 2, new UncompressedConfigResponseFactory()); } @@ -81,21 +82,25 @@ public class SuperModelControllerTest { } @Test - public void test_lb_config_multiple_apps() throws IOException, SAXException { + public void test_lb_config_multiple_apps_legacy_super_model() throws IOException, SAXException { Map<TenantName, Map<ApplicationId, ApplicationInfo>> models = new LinkedHashMap<>(); - models.put(TenantName.from("t1"), new LinkedHashMap<>()); - models.put(TenantName.from("t2"), new LinkedHashMap<>()); + TenantName t1 = TenantName.from("t1"); + TenantName t2 = TenantName.from("t2"); + models.put(t1, new LinkedHashMap<>()); + models.put(t2, new LinkedHashMap<>()); File testApp1 = new File("src/test/resources/deploy/app"); File testApp2 = new File("src/test/resources/deploy/advancedapp"); File testApp3 = new File("src/test/resources/deploy/advancedapp"); // TODO must fix equals, hashCode on Tenant Version vespaVersion = Version.fromIntValues(1, 2, 3); - models.get(TenantName.from("t1")).put(applicationId("mysimpleapp"), - new ApplicationInfo(applicationId("mysimpleapp"), 4l, new VespaModel(FilesApplicationPackage.fromFile(testApp1)))); - models.get(TenantName.from("t1")).put(applicationId("myadvancedapp"), - new ApplicationInfo(applicationId("myadvancedapp"), 4l, new VespaModel(FilesApplicationPackage.fromFile(testApp2)))); - models.get(TenantName.from("t2")).put(applicationId("minetooadvancedapp"), - new ApplicationInfo(applicationId("minetooadvancedapp"), 4l, new VespaModel(FilesApplicationPackage.fromFile(testApp3)))); + + ApplicationId simple = applicationId("mysimpleapp", t1); + ApplicationId advanced = applicationId("myadvancedapp", t1); + ApplicationId tooAdvanced = applicationId("minetooadvancedapp", t2); + models.get(t1).put(simple, createApplicationInfo(testApp1, simple, 4l)); + models.get(t1).put(advanced, createApplicationInfo(testApp2, simple, 4l)); + models.get(t2).put(tooAdvanced, createApplicationInfo(testApp3, simple, 4l)); + 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(); @@ -108,9 +113,38 @@ public class SuperModelControllerTest { assertQrServer(lbc.tenants("t2").applications("minetooadvancedapp:prod:default:default")); } - private ApplicationId applicationId(String applicationName) { - return ApplicationId.from(TenantName.defaultName(), - ApplicationName.from(applicationName), InstanceName.defaultName()); + @Test + public void test_lb_config_multiple_apps() throws IOException, SAXException { + Map<ApplicationId, ApplicationInfo> models = new LinkedHashMap<>(); + TenantName t1 = TenantName.from("t1"); + TenantName t2 = TenantName.from("t2"); + File testApp1 = new File("src/test/resources/deploy/app"); + File testApp2 = new File("src/test/resources/deploy/advancedapp"); + File testApp3 = new File("src/test/resources/deploy/advancedapp"); + // TODO must fix equals, hashCode on Tenant + Version vespaVersion = Version.fromIntValues(1, 2, 3); + + ApplicationId simple = applicationId("mysimpleapp", t1); + ApplicationId advanced = applicationId("myadvancedapp", t1); + ApplicationId tooAdvanced = applicationId("minetooadvancedapp", t2); + models.put(simple, createApplicationInfo(testApp1, simple, 4l)); + models.put(advanced, createApplicationInfo(testApp2, simple, 4l)); + models.put(tooAdvanced, createApplicationInfo(testApp3, simple, 4l)); + + SuperModel superModel = new SuperModel(models, false); + 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); + assertThat(lbc.tenants().size(), is(2)); + assertThat(lbc.tenants("t1").applications().size(), is(2)); + assertThat(lbc.tenants("t2").applications().size(), is(1)); + assertThat(lbc.tenants("t2").applications("minetooadvancedapp:prod:default:default").hosts().size(), is(1)); + assertQrServer(lbc.tenants("t2").applications("minetooadvancedapp:prod:default:default")); + } + + private ApplicationId applicationId(String applicationName, TenantName tenantName) { + return ApplicationId.from(tenantName, ApplicationName.from(applicationName), InstanceName.defaultName()); } private void assertQrServer(Applications app) { @@ -130,6 +164,18 @@ public class SuperModelControllerTest { org.junit.Assert.fail("No qrserver service in config"); } + private DeployState createDeployState(File applicationPackage, ApplicationId applicationId) { + return new DeployState.Builder() + .applicationPackage(FilesApplicationPackage.fromFile(applicationPackage)) + .properties(new DeployProperties.Builder().applicationId(applicationId).build()) + .build(); + } + + private ApplicationInfo createApplicationInfo(File applicationPackage, ApplicationId applicationId, long generation) throws IOException, SAXException { + DeployState deployState = createDeployState(applicationPackage, applicationId); + return new ApplicationInfo(applicationId, generation, new VespaModel(deployState)); + } + } diff --git a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/ExampleModel.java b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/ExampleModel.java index 186b22cf4ec..7341c817747 100644 --- a/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/ExampleModel.java +++ b/service-monitor/src/test/java/com/yahoo/vespa/service/monitor/internal/ExampleModel.java @@ -9,7 +9,6 @@ import com.yahoo.config.model.api.ServiceInfo; import com.yahoo.config.model.api.SuperModel; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.InstanceName; -import com.yahoo.config.provision.TenantName; import com.yahoo.vespa.service.monitor.internal.slobrok.SlobrokMonitor; import java.util.ArrayList; @@ -45,11 +44,9 @@ public class ExampleModel { .then() .build(); - Map<TenantName, Map<ApplicationId, ApplicationInfo>> applicationInfos = new HashMap<>(); - applicationInfos.put(applicationInfo.getApplicationId().tenant(), new HashMap<>()); - applicationInfos.get(applicationInfo.getApplicationId().tenant()) - .put(applicationInfo.getApplicationId(), applicationInfo); - return new SuperModel(applicationInfos); + Map<ApplicationId, ApplicationInfo> applicationInfos = new HashMap<>(); + applicationInfos.put(applicationInfo.getApplicationId(), applicationInfo); + return new SuperModel(applicationInfos, false); } public static ApplicationBuilder createApplication(String tenant, |