From 28f6fb192d3ba9d019fa9265b2770cc4325d5240 Mon Sep 17 00:00:00 2001 From: Morten Tokle Date: Mon, 20 Nov 2017 14:12:53 +0100 Subject: Move identity configuration services.xml -> deployment.xml --- .../config/application/api/DeploymentSpec.java | 62 ++++++++++++++++++++-- .../api/xml/DeploymentSpecXmlReader.java | 20 +++++-- .../config/application/api/DeploymentSpecTest.java | 52 ++++++++++++++++++ .../vespa/model/container/ContainerCluster.java | 33 ++++++++++++ .../model/container/xml/ContainerModelBuilder.java | 35 ------------ .../src/main/resources/schema/containercluster.rnc | 8 +-- .../src/main/resources/schema/deployment.rnc | 9 +++- .../model/container/xml/IdentityBuilderTest.java | 28 +++++++--- .../src/test/schema-test-files/deployment.xml | 4 +- .../src/test/schema-test-files/services.xml | 4 -- 10 files changed, 188 insertions(+), 67 deletions(-) diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java index 4d370ba5039..1a2335c82db 100644 --- a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java +++ b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java @@ -39,28 +39,36 @@ public class DeploymentSpec { UpgradePolicy.defaultPolicy, Collections.emptyList(), Collections.emptyList(), - ""); + "", + Optional.empty(), + Optional.empty()); private final Optional globalServiceId; private final UpgradePolicy upgradePolicy; private final List changeBlockers; private final List steps; private final String xmlForm; + private final Optional athenzDomain; + private final Optional athenzService; public DeploymentSpec(Optional globalServiceId, UpgradePolicy upgradePolicy, List changeBlockers, List steps) { - this(globalServiceId, upgradePolicy, changeBlockers, steps, null); + this(globalServiceId, upgradePolicy, changeBlockers, steps, null, Optional.empty(), Optional.empty()); } public DeploymentSpec(Optional globalServiceId, UpgradePolicy upgradePolicy, - List changeBlockers, List steps, String xmlForm) { + List changeBlockers, List steps, String xmlForm, + Optional athenzDomain, Optional athenzService) { validateTotalDelay(steps); this.globalServiceId = globalServiceId; this.upgradePolicy = upgradePolicy; this.changeBlockers = changeBlockers; this.steps = ImmutableList.copyOf(completeSteps(new ArrayList<>(steps))); this.xmlForm = xmlForm; + this.athenzDomain = athenzDomain; + this.athenzService = athenzService; validateZones(this.steps); + validateAthenz(); } /** Throw an IllegalArgumentException if the total delay exceeds 24 hours */ @@ -81,7 +89,30 @@ public class DeploymentSpec { for (DeclaredZone zone : step.zones()) ensureUnique(zone, zones); } - + + /* + * Throw an IllegalArgumentException if Athenz configuration violates: + * domain not configured -> no zone can configure service + * domain configured -> all zones must configure service + */ + private void validateAthenz() { + // If athenz domain is not set, athenz service cannot be set on any level + if (! athenzDomain.isPresent()) { + for (DeclaredZone zone : zones()) { + if(zone.athenzService().isPresent()) { + throw new IllegalArgumentException("Athenz service configured for zone: " + zone + ", but Athenz domain is not configured"); + } + } + // if athenz domain is configured, athenz service must be set implicitly or directly on all zones. + } else if(! athenzService.isPresent()) { + for (DeclaredZone zone : zones()) { + if(! zone.athenzService().isPresent()) { + throw new IllegalArgumentException("Athenz domain is configured, but Athenz service not configured for zone: " + zone); + } + } + } + } + private void ensureUnique(DeclaredZone zone, Set zones) { if ( ! zones.add(zone)) throw new IllegalArgumentException(zone + " is listed twice in deployment.xml"); @@ -212,6 +243,20 @@ public class DeploymentSpec { return b.toString(); } + /** Returns the athenz domain if configured */ + public Optional athenzDomain() { + return athenzDomain; + } + + /** Returns the athenz service for environment/region if configured */ + public Optional athenzService(Environment environment, RegionName region) { + return zones().stream() + .filter(zone -> zone.deploysTo(environment, Optional.of(region))) + .findFirst() + .map(DeclaredZone::athenzService) + .orElse(athenzService); + } + /** This may be invoked by a continuous build */ public static void main(String[] args) { if (args.length != 2 && args.length != 3) { @@ -276,11 +321,17 @@ public class DeploymentSpec { private final boolean active; + private Optional athenzService; + public DeclaredZone(Environment environment) { this(environment, Optional.empty(), false); } public DeclaredZone(Environment environment, Optional region, boolean active) { + this(environment, region, active, Optional.empty()); + } + + public DeclaredZone(Environment environment, Optional region, boolean active, Optional athenzService) { if (environment != Environment.prod && region.isPresent()) throw new IllegalArgumentException("Non-prod environments cannot specify a region"); if (environment == Environment.prod && ! region.isPresent()) @@ -288,6 +339,7 @@ public class DeploymentSpec { this.environment = environment; this.region = region; this.active = active; + this.athenzService = athenzService; } public Environment environment() { return environment; } @@ -298,6 +350,8 @@ public class DeploymentSpec { /** Returns whether this zone should receive production traffic */ public boolean active() { return active; } + public Optional athenzService() { return athenzService; } + @Override public List zones() { return Collections.singletonList(this); } diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java b/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java index 5599b257b16..1a970e53713 100644 --- a/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java +++ b/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java @@ -72,6 +72,7 @@ public class DeploymentSpecXmlReader { if (environment == Environment.prod) { for (Element stepTag : XML.getChildren(environmentTag)) { + Optional athenzService = stringAttribute("athenz-service", environmentTag); if (stepTag.getTagName().equals("delay")) { steps.add(new Delay(Duration.ofSeconds(longAttribute("hours", stepTag) * 60 * 60 + longAttribute("minutes", stepTag) * 60 + @@ -79,11 +80,11 @@ public class DeploymentSpecXmlReader { } else if (stepTag.getTagName().equals("parallel")) { List zones = new ArrayList<>(); for (Element regionTag : XML.getChildren(stepTag)) { - zones.add(readDeclaredZone(environment, regionTag)); + zones.add(readDeclaredZone(environment, athenzService, regionTag)); } steps.add(new ParallelZones(zones)); } else { // a region: deploy step - steps.add(readDeclaredZone(environment, stepTag)); + steps.add(readDeclaredZone(environment, athenzService, stepTag)); } } } else { @@ -94,8 +95,11 @@ public class DeploymentSpecXmlReader { globalServiceId = readGlobalServiceId(environmentTag); else if (readGlobalServiceId(environmentTag).isPresent()) throw new IllegalArgumentException("Attribute 'global-service-id' is only valid on 'prod' tag."); + } - return new DeploymentSpec(globalServiceId, readUpgradePolicy(root), readChangeBlockers(root), steps, xmlForm); + Optional athenzDomain = stringAttribute("athenz-domain", root); + Optional athenzService = stringAttribute("athenz-service", root); + return new DeploymentSpec(globalServiceId, readUpgradePolicy(root), readChangeBlockers(root), steps, xmlForm, athenzDomain, athenzService); } /** Imposes some constraints on tag order which are not expressible in the schema */ @@ -132,13 +136,19 @@ public class DeploymentSpecXmlReader { } } + /** Returns the given attribute as a string, or Optional.empty if it is not present or empty */ + private Optional stringAttribute(String attributeName, Element tag) { + String value = tag.getAttribute(attributeName); + return Optional.ofNullable(value).filter(s -> ! s.equals("")); + } + private boolean isEnvironmentName(String tagName) { return tagName.equals(testTag) || tagName.equals(stagingTag) || tagName.equals(prodTag); } - private DeclaredZone readDeclaredZone(Environment environment, Element regionTag) { + private DeclaredZone readDeclaredZone(Environment environment, Optional athenzService, Element regionTag) { return new DeclaredZone(environment, Optional.of(RegionName.from(XML.getValue(regionTag).trim())), - readActive(regionTag)); + readActive(regionTag), athenzService); } private Optional readGlobalServiceId(Element environmentTag) { diff --git a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java index 5050f88af31..5dcb3bc1ebe 100644 --- a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java +++ b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java @@ -367,4 +367,56 @@ public class DeploymentSpecTest { assertTrue(spec.canUpgradeAt(Instant.parse("2017-09-23T10:15:30.00Z"))); } + @Test + public void deploymentSpecWithAthenzIdentity() { + StringReader r = new StringReader( + "\n" + + " \n" + + " us-west-1\n" + + " \n" + + "" + ); + DeploymentSpec spec = DeploymentSpec.fromXml(r); + assertEquals(spec.athenzDomain().get(), "domain"); + assertEquals(spec.athenzService(Environment.prod, RegionName.from("us-west-1")).get(), "service"); + } + + @Test + public void deploymentSpecUsesServiceFromEnvironment() { + StringReader r = new StringReader( + "\n" + + " \n" + + " \n" + + " us-west-1\n" + + " \n" + + "" + ); + DeploymentSpec spec = DeploymentSpec.fromXml(r); + assertEquals(spec.athenzDomain().get(), "domain"); + assertEquals(spec.athenzService(Environment.prod, RegionName.from("us-west-1")).get(), "prodservice"); + } + + @Test(expected = IllegalArgumentException.class) + public void athenzDomainMissingService() { + StringReader r = new StringReader( + "\n" + + " \n" + + " us-west-1\n" + + " \n" + + "" + ); + DeploymentSpec spec = DeploymentSpec.fromXml(r); + } + + @Test(expected = IllegalArgumentException.class) + public void athenzDomainMissingDomain() { + StringReader r = new StringReader( + "\n" + + " \n" + + " us-west-1\n" + + " \n" + + "" + ); + DeploymentSpec spec = DeploymentSpec.fromXml(r); + } } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java index 91d5b7fe267..1e9dc569ff5 100755 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java @@ -13,8 +13,10 @@ import com.yahoo.config.application.api.DeploymentSpec; import com.yahoo.config.docproc.DocprocConfig; import com.yahoo.config.docproc.SchemamappingConfig; import com.yahoo.config.model.ApplicationConfigProducerRoot; +import com.yahoo.config.model.api.ConfigServerSpec; import com.yahoo.config.model.producer.AbstractConfigProducer; import com.yahoo.config.model.producer.AbstractConfigProducerRoot; +import com.yahoo.config.provision.HostName; import com.yahoo.config.provision.Rotation; import com.yahoo.config.provision.Zone; import com.yahoo.container.BundlesConfig; @@ -232,6 +234,7 @@ public final class ContainerCluster addSimpleComponent("com.yahoo.container.core.slobrok.SlobrokConfigurator"); addSimpleComponent("com.yahoo.container.handler.VipStatus"); addJaxProviders(); + addIdentity(); } public void setZone(Zone zone) { @@ -304,6 +307,36 @@ public final class ContainerCluster addSimpleComponent(XPathFactoryProvider.class); } + public void addIdentity() { + getDeploymentSpec().ifPresent(deploymentSpec -> { + deploymentSpec.athenzDomain().ifPresent(domain -> { + + String service = deploymentSpec.athenzService(zone.environment(), zone.region()) + .orElseThrow(() -> new RuntimeException("Missing Athenz service configuration")); + + Identity identity = new Identity(domain.trim(), service.trim(), getLoadBalancerName()); + addComponent(identity); + + getContainers().forEach(container -> { + container.setProp("identity.domain", domain); + container.setProp("identity.service", service); + }); + }); + }); + } + + private HostName getLoadBalancerName() { + // Set lbaddress, or use first hostname if not specified. + // TODO: Remove the orElseGet part when this is set up in all zones + return Optional.ofNullable(getRoot().getDeployState().getProperties().loadBalancerName()) + .orElseGet( + () -> HostName.from(getRoot().getDeployState().getProperties().configServerSpecs().stream() + .findFirst() + .map(ConfigServerSpec::getHostName) + .orElse("unknown") // Currently unable to test this, hence the unknown + )); + } + public final void addComponent(Component component) { if (clusterVerifier.acceptComponent(component)) { componentGroup.addComponent(component); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java index d59846cd5e2..121039a248d 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java @@ -7,7 +7,6 @@ import com.yahoo.config.application.Xml; import com.yahoo.config.application.api.ApplicationPackage; import com.yahoo.config.application.api.DeployLogger; import com.yahoo.config.model.ConfigModelContext; -import com.yahoo.config.model.api.ConfigServerSpec; import com.yahoo.config.model.application.provider.IncludeDirs; import com.yahoo.config.model.builder.xml.ConfigModelBuilder; import com.yahoo.config.model.builder.xml.ConfigModelId; @@ -16,7 +15,6 @@ import com.yahoo.config.provision.Capacity; import com.yahoo.config.provision.ClusterMembership; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.Environment; -import com.yahoo.config.provision.HostName; import com.yahoo.config.provision.NodeType; import com.yahoo.container.jdisc.config.MetricDefaultsConfig; import com.yahoo.search.rendering.RendererRegistry; @@ -39,7 +37,6 @@ import com.yahoo.vespa.model.clients.ContainerDocumentApi; import com.yahoo.vespa.model.container.Container; import com.yahoo.vespa.model.container.ContainerCluster; import com.yahoo.vespa.model.container.ContainerModel; -import com.yahoo.vespa.model.container.Identity; import com.yahoo.vespa.model.container.component.Component; import com.yahoo.vespa.model.container.component.FileStatusHandlerComponent; import com.yahoo.vespa.model.container.component.chain.ProcessingHandler; @@ -165,13 +162,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder { addServerProviders(spec, cluster); addLegacyFilters(spec, cluster); // TODO: Remove for Vespa 7 - // Athenz copper argos - // NOTE: Must be done after addNodes() - addIdentity(spec, - cluster, - context.getDeployState().getProperties().configServerSpecs(), - context.getDeployState().getProperties().loadBalancerName()); - //TODO: overview handler, see DomQrserverClusterBuilder } @@ -698,31 +688,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder { } } - private void addIdentity(Element element, ContainerCluster cluster, List configServerSpecs, HostName loadBalancerName) { - Element identityElement = XML.getChild(element, "identity"); - if(identityElement != null) { - String domain = XML.getValue(XML.getChild(identityElement, "domain")); - String service = XML.getValue(XML.getChild(identityElement, "service")); - - // Set lbaddress, or use first hostname if not specified. - HostName lbName = Optional.ofNullable(loadBalancerName) - .orElseGet( - () -> HostName.from(configServerSpecs.stream() - .findFirst() - .map(ConfigServerSpec::getHostName) - .orElse("unknown") // Currently unable to test this, hence the unknown - )); - - Identity identity = new Identity(domain.trim(), service.trim(), lbName); - cluster.addComponent(identity); - - cluster.getContainers().forEach(container -> { - container.setProp("identity.domain", domain); - container.setProp("identity.service", service); - }); - } - } - /** * Disallow renderers named "DefaultRenderer" or "JsonRenderer" */ diff --git a/config-model/src/main/resources/schema/containercluster.rnc b/config-model/src/main/resources/schema/containercluster.rnc index 47cf0638d72..6a90bef7bb2 100644 --- a/config-model/src/main/resources/schema/containercluster.rnc +++ b/config-model/src/main/resources/schema/containercluster.rnc @@ -7,8 +7,7 @@ ContainerCluster = element container | jdisc { ContainerServices & DocumentBinding* & Aliases? & - NodesOfContainerCluster? & - Identity? + NodesOfContainerCluster? } ContainerServices = @@ -226,8 +225,3 @@ DocumentBinding = element document { attribute class { xsd:NCName } & attribute bundle { xsd:NCName } } - -Identity = element identity { - element domain { xsd:NCName } & - element service { xsd:NCName } -} diff --git a/config-model/src/main/resources/schema/deployment.rnc b/config-model/src/main/resources/schema/deployment.rnc index 90bff8e31b3..2ecfa781876 100644 --- a/config-model/src/main/resources/schema/deployment.rnc +++ b/config-model/src/main/resources/schema/deployment.rnc @@ -4,6 +4,8 @@ start = element deployment { attribute version { "1.0" } & + attribute athenz-domain { xsd:string }? & + attribute athenz-service { xsd:string }? & Upgrade? & BlockChange* & Test? & @@ -31,15 +33,18 @@ BlockUpgrade = element block-upgrade { # Legacy name - remove on Vespa 7 } Test = element test { - text + attribute athenz-service { xsd:string }? & + text } Staging = element staging { - text + attribute athenz-service { xsd:string }? & + text } Prod = element prod { attribute global-service-id { text }? & + attribute athenz-service { xsd:string }? & Region* & Delay* & Parallel* diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java index df118b0e349..c8a245e68b0 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java @@ -1,7 +1,11 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.container.xml; +import com.yahoo.config.application.api.ApplicationPackage; import com.yahoo.config.model.builder.xml.test.DomBuilderTest; +import com.yahoo.config.model.deploy.DeployState; +import com.yahoo.config.model.test.MockApplicationPackage; +import com.yahoo.config.model.test.MockRoot; import com.yahoo.container.core.identity.IdentityConfig; import com.yahoo.vespa.model.container.Identity; import org.junit.Test; @@ -17,16 +21,24 @@ import static org.junit.Assert.assertEquals; */ public class IdentityBuilderTest extends ContainerModelBuilderTestBase { @Test - public void identity_config_produced() throws IOException, SAXException { + public void identity_config_produced_from_deployment_spec() throws IOException, SAXException { Element clusterElem = DomBuilderTest.parse( - "", - " ", - " domain", - " service", - " ", - ""); + ""); + String deploymentXml = "\n" + + " \n" + + " \n" + + " default\n" + + " \n" + + "\n"; + + ApplicationPackage applicationPackage = new MockApplicationPackage.Builder() + .withDeploymentSpec(deploymentXml) + .build(); + + // Override root + root = new MockRoot("root", applicationPackage); + createModel(root, DeployState.createTestState(applicationPackage), clusterElem); - createModel(root, clusterElem); IdentityConfig identityConfig = root.getConfig(IdentityConfig.class, "default/component/" + Identity.CLASS); assertEquals("domain", identityConfig.domain()); assertEquals("service", identityConfig.service()); diff --git a/config-model/src/test/schema-test-files/deployment.xml b/config-model/src/test/schema-test-files/deployment.xml index f469d22b6f0..f9a62eb648f 100644 --- a/config-model/src/test/schema-test-files/deployment.xml +++ b/config-model/src/test/schema-test-files/deployment.xml @@ -1,12 +1,12 @@ - + - + us-west-1 us-central-1 diff --git a/config-model/src/test/schema-test-files/services.xml b/config-model/src/test/schema-test-files/services.xml index 98637c03020..a02346193cc 100644 --- a/config-model/src/test/schema-test-files/services.xml +++ b/config-model/src/test/schema-test-files/services.xml @@ -35,10 +35,6 @@ - - mydomain - myservice - -- cgit v1.2.3 From 4fa8521f1d23a64c0c0bc1b8fb11c1be7a7c3762 Mon Sep 17 00:00:00 2001 From: Morten Tokle Date: Wed, 22 Nov 2017 13:44:48 +0100 Subject: Move deployment spec ContainerCluster -> ContainerModelBuilder --- .../config/application/api/DeploymentSpec.java | 27 ++++--- .../api/xml/DeploymentSpecXmlReader.java | 10 ++- .../config/application/api/DeploymentSpecTest.java | 8 +- .../vespa/model/container/ContainerCluster.java | 88 ---------------------- .../com/yahoo/vespa/model/container/Identity.java | 12 +-- .../model/container/xml/ContainerModelBuilder.java | 73 ++++++++++++++++++ .../model/container/xml/IdentityBuilderTest.java | 2 +- .../com/yahoo/config/provision/AthenzDomain.java | 20 +++++ .../com/yahoo/config/provision/AthenzService.java | 20 +++++ 9 files changed, 146 insertions(+), 114 deletions(-) create mode 100644 config-provisioning/src/main/java/com/yahoo/config/provision/AthenzDomain.java create mode 100644 config-provisioning/src/main/java/com/yahoo/config/provision/AthenzService.java diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java index 1a2335c82db..64e986abf9b 100644 --- a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java +++ b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java @@ -3,6 +3,8 @@ package com.yahoo.config.application.api; import com.google.common.collect.ImmutableList; import com.yahoo.config.application.api.xml.DeploymentSpecXmlReader; +import com.yahoo.config.provision.AthenzDomain; +import com.yahoo.config.provision.AthenzService; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.RegionName; @@ -48,8 +50,8 @@ public class DeploymentSpec { private final List changeBlockers; private final List steps; private final String xmlForm; - private final Optional athenzDomain; - private final Optional athenzService; + private final Optional athenzDomain; + private final Optional athenzService; public DeploymentSpec(Optional globalServiceId, UpgradePolicy upgradePolicy, List changeBlockers, List steps) { @@ -58,7 +60,7 @@ public class DeploymentSpec { public DeploymentSpec(Optional globalServiceId, UpgradePolicy upgradePolicy, List changeBlockers, List steps, String xmlForm, - Optional athenzDomain, Optional athenzService) { + Optional athenzDomain, Optional athenzService) { validateTotalDelay(steps); this.globalServiceId = globalServiceId; this.upgradePolicy = upgradePolicy; @@ -103,7 +105,7 @@ public class DeploymentSpec { throw new IllegalArgumentException("Athenz service configured for zone: " + zone + ", but Athenz domain is not configured"); } } - // if athenz domain is configured, athenz service must be set implicitly or directly on all zones. + // if athenz domain is not set, athenz service must be set implicitly or directly on all zones. } else if(! athenzService.isPresent()) { for (DeclaredZone zone : zones()) { if(! zone.athenzService().isPresent()) { @@ -244,17 +246,18 @@ public class DeploymentSpec { } /** Returns the athenz domain if configured */ - public Optional athenzDomain() { + public Optional athenzDomain() { return athenzDomain; } /** Returns the athenz service for environment/region if configured */ - public Optional athenzService(Environment environment, RegionName region) { - return zones().stream() + public Optional athenzService(Environment environment, RegionName region) { + AthenzService athenzService = zones().stream() .filter(zone -> zone.deploysTo(environment, Optional.of(region))) .findFirst() - .map(DeclaredZone::athenzService) - .orElse(athenzService); + .flatMap(DeclaredZone::athenzService) + .orElse(this.athenzService.orElse(null)); + return Optional.ofNullable(athenzService); } /** This may be invoked by a continuous build */ @@ -321,7 +324,7 @@ public class DeploymentSpec { private final boolean active; - private Optional athenzService; + private Optional athenzService; public DeclaredZone(Environment environment) { this(environment, Optional.empty(), false); @@ -331,7 +334,7 @@ public class DeploymentSpec { this(environment, region, active, Optional.empty()); } - public DeclaredZone(Environment environment, Optional region, boolean active, Optional athenzService) { + public DeclaredZone(Environment environment, Optional region, boolean active, Optional athenzService) { if (environment != Environment.prod && region.isPresent()) throw new IllegalArgumentException("Non-prod environments cannot specify a region"); if (environment == Environment.prod && ! region.isPresent()) @@ -350,7 +353,7 @@ public class DeploymentSpec { /** Returns whether this zone should receive production traffic */ public boolean active() { return active; } - public Optional athenzService() { return athenzService; } + public Optional athenzService() { return athenzService; } @Override public List zones() { return Collections.singletonList(this); } diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java b/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java index 1a970e53713..8bc4e0026a6 100644 --- a/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java +++ b/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java @@ -7,6 +7,8 @@ import com.yahoo.config.application.api.DeploymentSpec.Delay; import com.yahoo.config.application.api.DeploymentSpec.ParallelZones; import com.yahoo.config.application.api.DeploymentSpec.Step; import com.yahoo.config.application.api.TimeWindow; +import com.yahoo.config.provision.AthenzDomain; +import com.yahoo.config.provision.AthenzService; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.RegionName; import com.yahoo.io.IOUtils; @@ -72,7 +74,7 @@ public class DeploymentSpecXmlReader { if (environment == Environment.prod) { for (Element stepTag : XML.getChildren(environmentTag)) { - Optional athenzService = stringAttribute("athenz-service", environmentTag); + Optional athenzService = stringAttribute("athenz-service", environmentTag).map(AthenzService::from); if (stepTag.getTagName().equals("delay")) { steps.add(new Delay(Duration.ofSeconds(longAttribute("hours", stepTag) * 60 * 60 + longAttribute("minutes", stepTag) * 60 + @@ -97,8 +99,8 @@ public class DeploymentSpecXmlReader { throw new IllegalArgumentException("Attribute 'global-service-id' is only valid on 'prod' tag."); } - Optional athenzDomain = stringAttribute("athenz-domain", root); - Optional athenzService = stringAttribute("athenz-service", root); + Optional athenzDomain = stringAttribute("athenz-domain", root).map(AthenzDomain::from); + Optional athenzService = stringAttribute("athenz-service", root).map(AthenzService::from); return new DeploymentSpec(globalServiceId, readUpgradePolicy(root), readChangeBlockers(root), steps, xmlForm, athenzDomain, athenzService); } @@ -146,7 +148,7 @@ public class DeploymentSpecXmlReader { return tagName.equals(testTag) || tagName.equals(stagingTag) || tagName.equals(prodTag); } - private DeclaredZone readDeclaredZone(Environment environment, Optional athenzService, Element regionTag) { + private DeclaredZone readDeclaredZone(Environment environment, Optional athenzService, Element regionTag) { return new DeclaredZone(environment, Optional.of(RegionName.from(XML.getValue(regionTag).trim())), readActive(regionTag), athenzService); } diff --git a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java index 5dcb3bc1ebe..99243125f9c 100644 --- a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java +++ b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java @@ -368,7 +368,7 @@ public class DeploymentSpecTest { } @Test - public void deploymentSpecWithAthenzIdentity() { + public void athenz_config_is_read_from_deployment() { StringReader r = new StringReader( "\n" + " \n" + @@ -382,7 +382,7 @@ public class DeploymentSpecTest { } @Test - public void deploymentSpecUsesServiceFromEnvironment() { + public void athenz_service_is_overridden_from_environment() { StringReader r = new StringReader( "\n" + " \n" + @@ -397,7 +397,7 @@ public class DeploymentSpecTest { } @Test(expected = IllegalArgumentException.class) - public void athenzDomainMissingService() { + public void it_fails_when_athenz_service_is_not_defined() { StringReader r = new StringReader( "\n" + " \n" + @@ -409,7 +409,7 @@ public class DeploymentSpecTest { } @Test(expected = IllegalArgumentException.class) - public void athenzDomainMissingDomain() { + public void it_fails_when_athenz_service_is_configured_but_not_athenz_domain() { StringReader r = new StringReader( "\n" + " \n" + diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java index 1e9dc569ff5..4383e55e45d 100755 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java @@ -9,15 +9,10 @@ import com.yahoo.component.ComponentSpecification; import com.yahoo.config.FileReference; import com.yahoo.config.application.api.ApplicationMetaData; import com.yahoo.config.application.api.ComponentInfo; -import com.yahoo.config.application.api.DeploymentSpec; import com.yahoo.config.docproc.DocprocConfig; import com.yahoo.config.docproc.SchemamappingConfig; import com.yahoo.config.model.ApplicationConfigProducerRoot; -import com.yahoo.config.model.api.ConfigServerSpec; import com.yahoo.config.model.producer.AbstractConfigProducer; -import com.yahoo.config.model.producer.AbstractConfigProducerRoot; -import com.yahoo.config.provision.HostName; -import com.yahoo.config.provision.Rotation; import com.yahoo.config.provision.Zone; import com.yahoo.container.BundlesConfig; import com.yahoo.container.ComponentsConfig; @@ -87,7 +82,6 @@ import com.yahoo.vespaclient.config.FeederConfig; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; -import java.io.Reader; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; @@ -234,7 +228,6 @@ public final class ContainerCluster addSimpleComponent("com.yahoo.container.core.slobrok.SlobrokConfigurator"); addSimpleComponent("com.yahoo.container.handler.VipStatus"); addJaxProviders(); - addIdentity(); } public void setZone(Zone zone) { @@ -307,36 +300,6 @@ public final class ContainerCluster addSimpleComponent(XPathFactoryProvider.class); } - public void addIdentity() { - getDeploymentSpec().ifPresent(deploymentSpec -> { - deploymentSpec.athenzDomain().ifPresent(domain -> { - - String service = deploymentSpec.athenzService(zone.environment(), zone.region()) - .orElseThrow(() -> new RuntimeException("Missing Athenz service configuration")); - - Identity identity = new Identity(domain.trim(), service.trim(), getLoadBalancerName()); - addComponent(identity); - - getContainers().forEach(container -> { - container.setProp("identity.domain", domain); - container.setProp("identity.service", service); - }); - }); - }); - } - - private HostName getLoadBalancerName() { - // Set lbaddress, or use first hostname if not specified. - // TODO: Remove the orElseGet part when this is set up in all zones - return Optional.ofNullable(getRoot().getDeployState().getProperties().loadBalancerName()) - .orElseGet( - () -> HostName.from(getRoot().getDeployState().getProperties().configServerSpecs().stream() - .findFirst() - .map(ConfigServerSpec::getHostName) - .orElse("unknown") // Currently unable to test this, hence the unknown - )); - } - public final void addComponent(Component component) { if (clusterVerifier.acceptComponent(component)) { componentGroup.addComponent(component); @@ -415,8 +378,6 @@ public final class ContainerCluster container.setClusterName(name); container.setProp("clustername", name) .setProp("index", this.containers.size()); - setRotations(container, getRotations(), getGlobalServiceId(), name); - container.setProp("activeRotation", Boolean.toString(getActiveRotation())); containers.add(container); } @@ -426,55 +387,6 @@ public final class ContainerCluster } } - private Optional getGlobalServiceId() { - Optional deploymentSpec = getDeploymentSpec(); - if (deploymentSpec.isPresent()) return deploymentSpec.get().globalServiceId(); - return Optional.empty(); - } - - private Set getRotations() { - return Optional.ofNullable(getRoot()) - .map(root -> root.getDeployState().getRotations()) - .orElse(Collections.emptySet()); - } - - private boolean getActiveRotation() { - return Optional.ofNullable(getRoot()) - .map(root -> root.getDeployState().getProperties().zone()) - .map(this::zoneHasActiveRotation) - .orElse(false); - } - - private boolean zoneHasActiveRotation(Zone zone) { - Optional spec = getDeploymentSpec(); - if (!spec.isPresent()) { - return false; - } - return spec.get().zones().stream() - .anyMatch(declaredZone -> declaredZone.deploysTo(zone.environment(), Optional.of(zone.region())) && - declaredZone.active()); - } - - private Optional getDeploymentSpec() { - Optional deploymentSpec = Optional.empty(); - AbstractConfigProducerRoot root = getRoot(); - if (root != null) { - final Optional deployment = root.getDeployState().getApplicationPackage().getDeployment(); - if (deployment.isPresent()) { - deploymentSpec = Optional.of(DeploymentSpec.fromXml(deployment.get())); - } - } - return deploymentSpec; - } - - private void setRotations(Container container, Set rotations, Optional globalServiceId, String containerClusterName) { - if ( ! rotations.isEmpty() && globalServiceId.isPresent()) { - if (containerClusterName.equals(globalServiceId.get())) { - container.setProp("rotations", rotations.stream().map(Rotation::getId).collect(Collectors.joining(","))); - } - } - } - public void setProcessingChains(ProcessingChains processingChains, String... serverBindings) { if (this.processingChains != null) throw new IllegalStateException("ProcessingChains should only be set once."); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/Identity.java b/config-model/src/main/java/com/yahoo/vespa/model/container/Identity.java index bc7a6e20361..bf5a7757149 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/Identity.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/Identity.java @@ -1,6 +1,8 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.container; +import com.yahoo.config.provision.AthenzDomain; +import com.yahoo.config.provision.AthenzService; import com.yahoo.config.provision.HostName; import com.yahoo.container.core.identity.IdentityConfig; import com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl; @@ -12,11 +14,11 @@ import com.yahoo.vespa.model.container.component.SimpleComponent; public class Identity extends SimpleComponent implements IdentityConfig.Producer { public static final String CLASS = AthenzIdentityProviderImpl.class.getName(); - private final String domain; - private final String service; + private final AthenzDomain domain; + private final AthenzService service; private final HostName loadBalancerName; - public Identity(String domain, String service, HostName loadBalancerName) { + public Identity(AthenzDomain domain, AthenzService service, HostName loadBalancerName) { super(CLASS); this.domain = domain; this.service = service; @@ -25,8 +27,8 @@ public class Identity extends SimpleComponent implements IdentityConfig.Producer @Override public void getConfig(IdentityConfig.Builder builder) { - builder.domain(domain); - builder.service(service); + builder.domain(domain.value()); + builder.service(service.value()); // Current interpretation of loadbalancer address is: hostname. // Config should be renamed or send the uri builder.loadBalancerAddress(loadBalancerName.value()); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java index 121039a248d..4dba9f923a8 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java @@ -6,16 +6,22 @@ import com.yahoo.component.Version; import com.yahoo.config.application.Xml; import com.yahoo.config.application.api.ApplicationPackage; import com.yahoo.config.application.api.DeployLogger; +import com.yahoo.config.application.api.DeploymentSpec; import com.yahoo.config.model.ConfigModelContext; +import com.yahoo.config.model.api.ConfigServerSpec; import com.yahoo.config.model.application.provider.IncludeDirs; import com.yahoo.config.model.builder.xml.ConfigModelBuilder; import com.yahoo.config.model.builder.xml.ConfigModelId; import com.yahoo.config.model.producer.AbstractConfigProducer; +import com.yahoo.config.provision.AthenzService; import com.yahoo.config.provision.Capacity; import com.yahoo.config.provision.ClusterMembership; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.Environment; +import com.yahoo.config.provision.HostName; import com.yahoo.config.provision.NodeType; +import com.yahoo.config.provision.Rotation; +import com.yahoo.config.provision.Zone; import com.yahoo.container.jdisc.config.MetricDefaultsConfig; import com.yahoo.search.rendering.RendererRegistry; import com.yahoo.text.XML; @@ -37,6 +43,7 @@ import com.yahoo.vespa.model.clients.ContainerDocumentApi; import com.yahoo.vespa.model.container.Container; import com.yahoo.vespa.model.container.ContainerCluster; import com.yahoo.vespa.model.container.ContainerModel; +import com.yahoo.vespa.model.container.Identity; import com.yahoo.vespa.model.container.component.Component; import com.yahoo.vespa.model.container.component.FileStatusHandlerComponent; import com.yahoo.vespa.model.container.component.chain.ProcessingHandler; @@ -61,6 +68,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Set; import java.util.function.Consumer; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -85,6 +93,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder { private final boolean standaloneBuilder; private final Networking networking; protected DeployLogger log; + private Optional deploymentSpec; public static final List configModelIds = ImmutableList.of(ConfigModelId.fromName("container"), ConfigModelId.fromName("jdisc")); @@ -108,6 +117,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder { @Override public void doBuild(ContainerModel model, Element spec, ConfigModelContext modelContext) { app = modelContext.getApplicationPackage(); + deploymentSpec = app.getDeployment().map(DeploymentSpec::fromXml); checkVersion(spec); this.log = modelContext.getDeployLogger(); @@ -162,9 +172,43 @@ public class ContainerModelBuilder extends ConfigModelBuilder { addServerProviders(spec, cluster); addLegacyFilters(spec, cluster); // TODO: Remove for Vespa 7 + // Athenz copper argos + // NOTE: Must be done after addNodes() + addIdentity(cluster, + context.getDeployState().getProperties().configServerSpecs(), + context.getDeployState().getProperties().loadBalancerName(), + context.getDeployState().zone()); + + addRotationInfo(cluster, context.getDeployState().zone(), context.getDeployState().getRotations()); + //TODO: overview handler, see DomQrserverClusterBuilder } + private void addRotationInfo(ContainerCluster cluster, Zone zone, Set rotations) { + Optional globalServiceId = deploymentSpec.flatMap(DeploymentSpec::globalServiceId); + cluster.getContainers().forEach(container -> { + setRotations(container, rotations, globalServiceId, cluster.getName()); + container.setProp("activeRotation", Boolean.toString(zoneHasActiveRotation(zone))); + }); + } + + private boolean zoneHasActiveRotation(Zone zone) { + return deploymentSpec.map(DeploymentSpec::zones) + .map(List::stream) + .map(x -> x.anyMatch(declaredZone -> declaredZone.deploysTo(zone.environment(), Optional.of(zone.region())) && + declaredZone.active())) + .orElse(false); + } + + private void setRotations(Container container, Set rotations, Optional globalServiceId, String containerClusterName) { + + if ( ! rotations.isEmpty() && globalServiceId.isPresent()) { + if (containerClusterName.equals(globalServiceId.get())) { + container.setProp("rotations", rotations.stream().map(Rotation::getId).collect(Collectors.joining(","))); + } + } + } + private void addRoutingAliases(ContainerCluster cluster, Element spec, Environment environment) { if (environment != Environment.prod) return; @@ -688,6 +732,35 @@ public class ContainerModelBuilder extends ConfigModelBuilder { } } + private void addIdentity(ContainerCluster cluster, List configServerSpecs, HostName loadBalancerName, Zone zone) { + deploymentSpec.ifPresent(spec -> { + spec.athenzDomain().ifPresent(domain -> { + AthenzService service = spec.athenzService(zone.environment(), zone.region()) + .orElseThrow(() -> new RuntimeException("Missing Athenz service configuration")); + Identity identity = new Identity(domain, service, getLoadBalancerName(loadBalancerName, configServerSpecs)); + cluster.addComponent(identity); + + cluster.getContainers().forEach(container -> { + container.setProp("identity.domain", domain.value()); + container.setProp("identity.service", service.value()); + }); + }); + }); + } + + private HostName getLoadBalancerName(HostName loadbalancerName, List configServerSpecs) { + // Set lbaddress, or use first hostname if not specified. + // TODO: Remove this method and use the loadbalancerName directly + return Optional.ofNullable(loadbalancerName) + .orElseGet( + () -> HostName.from(configServerSpecs.stream() + .findFirst() + .map(ConfigServerSpec::getHostName) + .orElse("unknown") // Currently unable to test this, hence the unknown + )); + } + + /** * Disallow renderers named "DefaultRenderer" or "JsonRenderer" */ diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java index c8a245e68b0..def23be1474 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java @@ -23,7 +23,7 @@ public class IdentityBuilderTest extends ContainerModelBuilderTestBase { @Test public void identity_config_produced_from_deployment_spec() throws IOException, SAXException { Element clusterElem = DomBuilderTest.parse( - ""); + ""); String deploymentXml = "\n" + " \n" + " \n" + diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzDomain.java b/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzDomain.java new file mode 100644 index 00000000000..a7367aaac17 --- /dev/null +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzDomain.java @@ -0,0 +1,20 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.config.provision; + +/** + * @author mortent + */ +public class AthenzDomain { + + private final String name; + + private AthenzDomain(String name) { + this.name = name; + } + + public static AthenzDomain from(String value) { + return new AthenzDomain(value); + } + + public String value() { return name; } +} diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzService.java b/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzService.java new file mode 100644 index 00000000000..312145ca36d --- /dev/null +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzService.java @@ -0,0 +1,20 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.config.provision; + +/** + * @author mortent + */ +public class AthenzService { + + private final String name; + + private AthenzService(String name) { + this.name = name; + } + + public String value() { return name; } + + public static AthenzService from(String value) { + return new AthenzService(value); + } +} -- cgit v1.2.3 From 8a3a438afaf538766e5388bb48802db05fc055ce Mon Sep 17 00:00:00 2001 From: Morten Tokle Date: Wed, 22 Nov 2017 13:55:21 +0100 Subject: Rename Identity -> IdentityProvider --- .../com/yahoo/vespa/model/container/Identity.java | 36 ---------------------- .../vespa/model/container/IdentityProvider.java | 36 ++++++++++++++++++++++ .../model/container/xml/ContainerModelBuilder.java | 20 ++++++------ .../model/container/xml/IdentityBuilderTest.java | 4 +-- 4 files changed, 48 insertions(+), 48 deletions(-) delete mode 100644 config-model/src/main/java/com/yahoo/vespa/model/container/Identity.java create mode 100644 config-model/src/main/java/com/yahoo/vespa/model/container/IdentityProvider.java diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/Identity.java b/config-model/src/main/java/com/yahoo/vespa/model/container/Identity.java deleted file mode 100644 index bf5a7757149..00000000000 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/Identity.java +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.vespa.model.container; - -import com.yahoo.config.provision.AthenzDomain; -import com.yahoo.config.provision.AthenzService; -import com.yahoo.config.provision.HostName; -import com.yahoo.container.core.identity.IdentityConfig; -import com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl; -import com.yahoo.vespa.model.container.component.SimpleComponent; - -/** - * @author mortent - */ -public class Identity extends SimpleComponent implements IdentityConfig.Producer { - public static final String CLASS = AthenzIdentityProviderImpl.class.getName(); - - private final AthenzDomain domain; - private final AthenzService service; - private final HostName loadBalancerName; - - public Identity(AthenzDomain domain, AthenzService service, HostName loadBalancerName) { - super(CLASS); - this.domain = domain; - this.service = service; - this.loadBalancerName = loadBalancerName; - } - - @Override - public void getConfig(IdentityConfig.Builder builder) { - builder.domain(domain.value()); - builder.service(service.value()); - // Current interpretation of loadbalancer address is: hostname. - // Config should be renamed or send the uri - builder.loadBalancerAddress(loadBalancerName.value()); - } -} diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/IdentityProvider.java b/config-model/src/main/java/com/yahoo/vespa/model/container/IdentityProvider.java new file mode 100644 index 00000000000..0368f7eaf3e --- /dev/null +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/IdentityProvider.java @@ -0,0 +1,36 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.model.container; + +import com.yahoo.config.provision.AthenzDomain; +import com.yahoo.config.provision.AthenzService; +import com.yahoo.config.provision.HostName; +import com.yahoo.container.core.identity.IdentityConfig; +import com.yahoo.container.jdisc.athenz.impl.AthenzIdentityProviderImpl; +import com.yahoo.vespa.model.container.component.SimpleComponent; + +/** + * @author mortent + */ +public class IdentityProvider extends SimpleComponent implements IdentityConfig.Producer { + public static final String CLASS = AthenzIdentityProviderImpl.class.getName(); + + private final AthenzDomain domain; + private final AthenzService service; + private final HostName loadBalancerName; + + public IdentityProvider(AthenzDomain domain, AthenzService service, HostName loadBalancerName) { + super(CLASS); + this.domain = domain; + this.service = service; + this.loadBalancerName = loadBalancerName; + } + + @Override + public void getConfig(IdentityConfig.Builder builder) { + builder.domain(domain.value()); + builder.service(service.value()); + // Current interpretation of loadbalancer address is: hostname. + // Config should be renamed or send the uri + builder.loadBalancerAddress(loadBalancerName.value()); + } +} diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java index 4dba9f923a8..e91d360c9f8 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java @@ -43,7 +43,7 @@ import com.yahoo.vespa.model.clients.ContainerDocumentApi; import com.yahoo.vespa.model.container.Container; import com.yahoo.vespa.model.container.ContainerCluster; import com.yahoo.vespa.model.container.ContainerModel; -import com.yahoo.vespa.model.container.Identity; +import com.yahoo.vespa.model.container.IdentityProvider; import com.yahoo.vespa.model.container.component.Component; import com.yahoo.vespa.model.container.component.FileStatusHandlerComponent; import com.yahoo.vespa.model.container.component.chain.ProcessingHandler; @@ -174,17 +174,17 @@ public class ContainerModelBuilder extends ConfigModelBuilder { // Athenz copper argos // NOTE: Must be done after addNodes() - addIdentity(cluster, - context.getDeployState().getProperties().configServerSpecs(), - context.getDeployState().getProperties().loadBalancerName(), - context.getDeployState().zone()); + addIdentityProvider(cluster, + context.getDeployState().getProperties().configServerSpecs(), + context.getDeployState().getProperties().loadBalancerName(), + context.getDeployState().zone()); - addRotationInfo(cluster, context.getDeployState().zone(), context.getDeployState().getRotations()); + addRotationProperties(cluster, context.getDeployState().zone(), context.getDeployState().getRotations()); //TODO: overview handler, see DomQrserverClusterBuilder } - private void addRotationInfo(ContainerCluster cluster, Zone zone, Set rotations) { + private void addRotationProperties(ContainerCluster cluster, Zone zone, Set rotations) { Optional globalServiceId = deploymentSpec.flatMap(DeploymentSpec::globalServiceId); cluster.getContainers().forEach(container -> { setRotations(container, rotations, globalServiceId, cluster.getName()); @@ -732,13 +732,13 @@ public class ContainerModelBuilder extends ConfigModelBuilder { } } - private void addIdentity(ContainerCluster cluster, List configServerSpecs, HostName loadBalancerName, Zone zone) { + private void addIdentityProvider(ContainerCluster cluster, List configServerSpecs, HostName loadBalancerName, Zone zone) { deploymentSpec.ifPresent(spec -> { spec.athenzDomain().ifPresent(domain -> { AthenzService service = spec.athenzService(zone.environment(), zone.region()) .orElseThrow(() -> new RuntimeException("Missing Athenz service configuration")); - Identity identity = new Identity(domain, service, getLoadBalancerName(loadBalancerName, configServerSpecs)); - cluster.addComponent(identity); + IdentityProvider identityProvider = new IdentityProvider(domain, service, getLoadBalancerName(loadBalancerName, configServerSpecs)); + cluster.addComponent(identityProvider); cluster.getContainers().forEach(container -> { container.setProp("identity.domain", domain.value()); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java index def23be1474..17890a552f9 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java @@ -7,7 +7,7 @@ import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.test.MockApplicationPackage; import com.yahoo.config.model.test.MockRoot; import com.yahoo.container.core.identity.IdentityConfig; -import com.yahoo.vespa.model.container.Identity; +import com.yahoo.vespa.model.container.IdentityProvider; import org.junit.Test; import org.w3c.dom.Element; import org.xml.sax.SAXException; @@ -39,7 +39,7 @@ public class IdentityBuilderTest extends ContainerModelBuilderTestBase { root = new MockRoot("root", applicationPackage); createModel(root, DeployState.createTestState(applicationPackage), clusterElem); - IdentityConfig identityConfig = root.getConfig(IdentityConfig.class, "default/component/" + Identity.CLASS); + IdentityConfig identityConfig = root.getConfig(IdentityConfig.class, "default/component/" + IdentityProvider.CLASS); assertEquals("domain", identityConfig.domain()); assertEquals("service", identityConfig.service()); } -- cgit v1.2.3 From a677dbb09f92d1c19ed394ebb93b2e5f247fa8c5 Mon Sep 17 00:00:00 2001 From: Morten Tokle Date: Wed, 22 Nov 2017 13:55:36 +0100 Subject: Add equals and hashcode --- .../java/com/yahoo/config/provision/AthenzDomain.java | 15 +++++++++++++++ .../java/com/yahoo/config/provision/AthenzService.java | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzDomain.java b/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzDomain.java index a7367aaac17..847606ecaac 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzDomain.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzDomain.java @@ -17,4 +17,19 @@ public class AthenzDomain { } public String value() { return name; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AthenzDomain that = (AthenzDomain) o; + + return name != null ? name.equals(that.name) : that.name == null; + } + + @Override + public int hashCode() { + return name != null ? name.hashCode() : 0; + } } diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzService.java b/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzService.java index 312145ca36d..0db7d6ecd5e 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzService.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzService.java @@ -17,4 +17,19 @@ public class AthenzService { public static AthenzService from(String value) { return new AthenzService(value); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + AthenzService that = (AthenzService) o; + + return name != null ? name.equals(that.name) : that.name == null; + } + + @Override + public int hashCode() { + return name != null ? name.hashCode() : 0; + } } -- cgit v1.2.3 From a304ae016dd10ffcb7018dff77207415dcab3483 Mon Sep 17 00:00:00 2001 From: Morten Tokle Date: Wed, 22 Nov 2017 14:07:37 +0100 Subject: Remove deploymentspec member variable --- .../model/container/xml/ContainerModelBuilder.java | 55 ++++++++++------------ 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java index e91d360c9f8..5049bd43db5 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java @@ -93,7 +93,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder { private final boolean standaloneBuilder; private final Networking networking; protected DeployLogger log; - private Optional deploymentSpec; public static final List configModelIds = ImmutableList.of(ConfigModelId.fromName("container"), ConfigModelId.fromName("jdisc")); @@ -117,7 +116,6 @@ public class ContainerModelBuilder extends ConfigModelBuilder { @Override public void doBuild(ContainerModel model, Element spec, ConfigModelContext modelContext) { app = modelContext.getApplicationPackage(); - deploymentSpec = app.getDeployment().map(DeploymentSpec::fromXml); checkVersion(spec); this.log = modelContext.getDeployLogger(); @@ -174,30 +172,31 @@ public class ContainerModelBuilder extends ConfigModelBuilder { // Athenz copper argos // NOTE: Must be done after addNodes() - addIdentityProvider(cluster, - context.getDeployState().getProperties().configServerSpecs(), - context.getDeployState().getProperties().loadBalancerName(), - context.getDeployState().zone()); - - addRotationProperties(cluster, context.getDeployState().zone(), context.getDeployState().getRotations()); + app.getDeployment().map(DeploymentSpec::fromXml) + .ifPresent(deplspec -> { + addIdentityProvider(cluster, + context.getDeployState().getProperties().configServerSpecs(), + context.getDeployState().getProperties().loadBalancerName(), + context.getDeployState().zone(), + deplspec); + + addRotationProperties(cluster, context.getDeployState().zone(), context.getDeployState().getRotations(), deplspec); + }); //TODO: overview handler, see DomQrserverClusterBuilder } - private void addRotationProperties(ContainerCluster cluster, Zone zone, Set rotations) { - Optional globalServiceId = deploymentSpec.flatMap(DeploymentSpec::globalServiceId); + private void addRotationProperties(ContainerCluster cluster, Zone zone, Set rotations, DeploymentSpec spec) { cluster.getContainers().forEach(container -> { - setRotations(container, rotations, globalServiceId, cluster.getName()); - container.setProp("activeRotation", Boolean.toString(zoneHasActiveRotation(zone))); + setRotations(container, rotations, spec.globalServiceId(), cluster.getName()); + container.setProp("activeRotation", Boolean.toString(zoneHasActiveRotation(zone, spec))); }); } - private boolean zoneHasActiveRotation(Zone zone) { - return deploymentSpec.map(DeploymentSpec::zones) - .map(List::stream) - .map(x -> x.anyMatch(declaredZone -> declaredZone.deploysTo(zone.environment(), Optional.of(zone.region())) && - declaredZone.active())) - .orElse(false); + private boolean zoneHasActiveRotation(Zone zone, DeploymentSpec spec) { + return spec.zones().stream() + .anyMatch(declaredZone -> declaredZone.deploysTo(zone.environment(), Optional.of(zone.region())) && + declaredZone.active()); } private void setRotations(Container container, Set rotations, Optional globalServiceId, String containerClusterName) { @@ -732,18 +731,16 @@ public class ContainerModelBuilder extends ConfigModelBuilder { } } - private void addIdentityProvider(ContainerCluster cluster, List configServerSpecs, HostName loadBalancerName, Zone zone) { - deploymentSpec.ifPresent(spec -> { - spec.athenzDomain().ifPresent(domain -> { - AthenzService service = spec.athenzService(zone.environment(), zone.region()) - .orElseThrow(() -> new RuntimeException("Missing Athenz service configuration")); - IdentityProvider identityProvider = new IdentityProvider(domain, service, getLoadBalancerName(loadBalancerName, configServerSpecs)); - cluster.addComponent(identityProvider); + private void addIdentityProvider(ContainerCluster cluster, List configServerSpecs, HostName loadBalancerName, Zone zone, DeploymentSpec spec) { + spec.athenzDomain().ifPresent(domain -> { + AthenzService service = spec.athenzService(zone.environment(), zone.region()) + .orElseThrow(() -> new RuntimeException("Missing Athenz service configuration")); + IdentityProvider identityProvider = new IdentityProvider(domain, service, getLoadBalancerName(loadBalancerName, configServerSpecs)); + cluster.addComponent(identityProvider); - cluster.getContainers().forEach(container -> { - container.setProp("identity.domain", domain.value()); - container.setProp("identity.service", service.value()); - }); + cluster.getContainers().forEach(container -> { + container.setProp("identity.domain", domain.value()); + container.setProp("identity.service", service.value()); }); }); } -- cgit v1.2.3 From fb57c901152f668aeb87cf89865c9d5401d61646 Mon Sep 17 00:00:00 2001 From: Morten Tokle Date: Wed, 22 Nov 2017 14:47:50 +0100 Subject: Move routing test to own class --- .../model/container/ContainerClusterTest.java | 45 +------------ .../container/xml/ContainerModelBuilderTest.java | 2 +- .../model/container/xml/IdentityBuilderTest.java | 3 - .../model/container/xml/RoutingBuilderTest.java | 78 ++++++++++++++++++++++ 4 files changed, 80 insertions(+), 48 deletions(-) create mode 100644 config-model/src/test/java/com/yahoo/vespa/model/container/xml/RoutingBuilderTest.java diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java index af846f10ffe..d9c151480fe 100755 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java @@ -18,15 +18,14 @@ import com.yahoo.container.jdisc.config.MetricDefaultsConfig; import com.yahoo.search.config.QrStartConfig; import com.yahoo.vespa.model.Host; import com.yahoo.vespa.model.HostResource; -import com.yahoo.vespa.model.admin.clustercontroller.ClusterControllerContainer; import com.yahoo.vespa.model.admin.clustercontroller.ClusterControllerClusterVerifier; +import com.yahoo.vespa.model.admin.clustercontroller.ClusterControllerContainer; import com.yahoo.vespa.model.container.component.Component; import com.yahoo.vespa.model.container.docproc.ContainerDocproc; import com.yahoo.vespa.model.container.search.ContainerSearch; import com.yahoo.vespa.model.container.search.searchchain.SearchChains; import org.junit.Test; -import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.Optional; @@ -266,48 +265,6 @@ public class ContainerClusterTest { assertEquals(0, cluster.getAllComponents().stream().map(c -> c.getClassId().getName()).filter(c -> c.equals("com.yahoo.jdisc.http.filter.security.RoutingConfigProvider")).count()); } - @Test - public void setsRotationActiveAccordingToDeploymentSpec() { - String deploymentSpec = "\n" + - " \n" + - " us-north-1\n" + - " \n" + - " us-north-2\n" + - " us-north-3\n" + - " \n" + - " us-north-4\n" + - " \n" + - ""; - for (String region : Arrays.asList("us-north-1", "us-north-3")) { - Container container = containerIn(region, deploymentSpec); - assertEquals("Region " + region + " is active", "true", - container.getServicePropertyString("activeRotation")); - } - for (String region : Arrays.asList("us-north-2", "us-north-4")) { - Container container = containerIn(region, deploymentSpec); - assertEquals("Region " + region + " is inactive", "false", - container.getServicePropertyString("activeRotation")); - } - Container container = containerIn("unknown", deploymentSpec); - assertEquals("Unknown region is inactive", "false", - container.getServicePropertyString("activeRotation")); - } - - private static Container containerIn(String regionName, String deploymentSpec) { - ApplicationPackage applicationPackage = new MockApplicationPackage.Builder() - .withDeploymentSpec(deploymentSpec) - .build(); - DeployState state = new DeployState.Builder() - .applicationPackage(applicationPackage) - .properties(new DeployProperties.Builder().hostedVespa(true).zone( - new Zone(Environment.prod, RegionName.from(regionName))).build() - ) - .build(); - MockRoot root = new MockRoot("foo", state); - ContainerCluster cluster = new ContainerCluster(root, "container0", "container1"); - addContainer(cluster, "c1", "c1.domain"); - return cluster.getContainers().get(0); - } private static void addContainer(ContainerCluster cluster, String name, String hostName) { Container container = new Container(cluster, name, 0); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java index 0e6bce73867..d09211aea45 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilderTest.java @@ -26,7 +26,6 @@ import com.yahoo.container.servlet.ServletConfigConfig; import com.yahoo.container.usability.BindingsOverviewHandler; import com.yahoo.jdisc.http.ServletPathsConfig; import com.yahoo.prelude.cluster.QrMonitorConfig; -import static com.yahoo.vespa.defaults.Defaults.getDefaults; import com.yahoo.vespa.model.AbstractService; import com.yahoo.vespa.model.VespaModel; import com.yahoo.vespa.model.container.Container; @@ -46,6 +45,7 @@ import java.util.Map; import java.util.logging.Level; import static com.yahoo.test.LinePatternMatcher.containsLineWithPattern; +import static com.yahoo.vespa.defaults.Defaults.getDefaults; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; import static org.hamcrest.CoreMatchers.nullValue; diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java index 17890a552f9..d3ad2ccc721 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/IdentityBuilderTest.java @@ -5,7 +5,6 @@ import com.yahoo.config.application.api.ApplicationPackage; import com.yahoo.config.model.builder.xml.test.DomBuilderTest; import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.test.MockApplicationPackage; -import com.yahoo.config.model.test.MockRoot; import com.yahoo.container.core.identity.IdentityConfig; import com.yahoo.vespa.model.container.IdentityProvider; import org.junit.Test; @@ -35,8 +34,6 @@ public class IdentityBuilderTest extends ContainerModelBuilderTestBase { .withDeploymentSpec(deploymentXml) .build(); - // Override root - root = new MockRoot("root", applicationPackage); createModel(root, DeployState.createTestState(applicationPackage), clusterElem); IdentityConfig identityConfig = root.getConfig(IdentityConfig.class, "default/component/" + IdentityProvider.CLASS); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/xml/RoutingBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/RoutingBuilderTest.java new file mode 100644 index 00000000000..a2f32694340 --- /dev/null +++ b/config-model/src/test/java/com/yahoo/vespa/model/container/xml/RoutingBuilderTest.java @@ -0,0 +1,78 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.model.container.xml; + +import com.yahoo.config.application.api.ApplicationPackage; +import com.yahoo.config.model.builder.xml.test.DomBuilderTest; +import com.yahoo.config.model.deploy.DeployState; +import com.yahoo.config.model.test.MockApplicationPackage; +import com.yahoo.config.model.test.MockRoot; +import com.yahoo.config.provision.Environment; +import com.yahoo.config.provision.RegionName; +import com.yahoo.config.provision.Zone; +import com.yahoo.vespa.model.container.Container; +import com.yahoo.vespa.model.container.ContainerCluster; +import org.junit.Test; +import org.w3c.dom.Element; +import org.xml.sax.SAXException; + +import java.io.IOException; +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; + +/** + * @author mortent + */ +public class RoutingBuilderTest extends ContainerModelBuilderTestBase { + + @Test + public void setsRotationActiveAccordingToDeploymentSpec() throws IOException, SAXException { + Element clusterElem = DomBuilderTest.parse( + ""); + + String deploymentSpec = "\n" + + " \n" + + " us-north-1\n" + + " \n" + + " us-north-2\n" + + " us-north-3\n" + + " \n" + + " us-north-4\n" + + " \n" + + ""; + + ApplicationPackage applicationPackage = new MockApplicationPackage.Builder() + .withDeploymentSpec(deploymentSpec) + .build(); + //root = new MockRoot("root", applicationPackage); + for (String region : Arrays.asList("us-north-1", "us-north-3")) { + Container container = getContainer(applicationPackage, region, clusterElem); + + assertEquals("Region " + region + " is active", "true", + container.getServicePropertyString("activeRotation")); + } + for (String region : Arrays.asList("us-north-2", "us-north-4")) { + Container container = getContainer(applicationPackage, region, clusterElem); + + assertEquals("Region " + region + " is inactive", "false", + container.getServicePropertyString("activeRotation")); + } + Container container = getContainer(applicationPackage, "unknown", clusterElem); + assertEquals("Unknown region is inactive", "false", + container.getServicePropertyString("activeRotation")); + } + + + private Container getContainer(ApplicationPackage applicationPackage, String region, Element clusterElem) throws IOException, SAXException { + DeployState deployState = new DeployState.Builder() + .applicationPackage(applicationPackage) + .zone(new Zone(Environment.prod, RegionName.from(region))) + .build(); + + root = new MockRoot("root", deployState); + createModel(root, deployState, clusterElem); + ContainerCluster cluster = getContainerCluster("default"); + return cluster.getContainers().get(0); + + } +} -- cgit v1.2.3 From 4259571e690aa1f5cad9fa3e0487c5ab26bebd6d Mon Sep 17 00:00:00 2001 From: Morten Tokle Date: Wed, 22 Nov 2017 14:53:07 +0100 Subject: Add tostring --- .../src/main/java/com/yahoo/config/provision/AthenzDomain.java | 7 +++++++ .../src/main/java/com/yahoo/config/provision/AthenzService.java | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzDomain.java b/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzDomain.java index 847606ecaac..193a02ccf26 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzDomain.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzDomain.java @@ -18,6 +18,13 @@ public class AthenzDomain { public String value() { return name; } + @Override + public String toString() { + return "AthenzDomain{" + + "name='" + name + '\'' + + '}'; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzService.java b/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzService.java index 0db7d6ecd5e..54f2889d95c 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzService.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/AthenzService.java @@ -18,6 +18,13 @@ public class AthenzService { return new AthenzService(value); } + @Override + public String toString() { + return "AthenzService{" + + "name='" + name + '\'' + + '}'; + } + @Override public boolean equals(Object o) { if (this == o) return true; -- cgit v1.2.3 From c01e20ac15192f25b9ff46f9dd8a3938bc2438c6 Mon Sep 17 00:00:00 2001 From: Morten Tokle Date: Wed, 22 Nov 2017 14:54:25 +0100 Subject: Rename --- .../com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java index 5049bd43db5..81fc464327e 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java @@ -173,14 +173,14 @@ public class ContainerModelBuilder extends ConfigModelBuilder { // Athenz copper argos // NOTE: Must be done after addNodes() app.getDeployment().map(DeploymentSpec::fromXml) - .ifPresent(deplspec -> { + .ifPresent(deploymentSpec -> { addIdentityProvider(cluster, context.getDeployState().getProperties().configServerSpecs(), context.getDeployState().getProperties().loadBalancerName(), context.getDeployState().zone(), - deplspec); + deploymentSpec); - addRotationProperties(cluster, context.getDeployState().zone(), context.getDeployState().getRotations(), deplspec); + addRotationProperties(cluster, context.getDeployState().zone(), context.getDeployState().getRotations(), deploymentSpec); }); //TODO: overview handler, see DomQrserverClusterBuilder -- cgit v1.2.3 From 7c6b77534b607c6123956ad5cb04f1bf82812b93 Mon Sep 17 00:00:00 2001 From: Morten Tokle Date: Thu, 23 Nov 2017 08:17:25 +0100 Subject: Fix tests after refactor --- .../java/com/yahoo/config/application/api/DeploymentSpecTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java index 99243125f9c..103724744de 100644 --- a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java +++ b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java @@ -377,8 +377,8 @@ public class DeploymentSpecTest { "" ); DeploymentSpec spec = DeploymentSpec.fromXml(r); - assertEquals(spec.athenzDomain().get(), "domain"); - assertEquals(spec.athenzService(Environment.prod, RegionName.from("us-west-1")).get(), "service"); + assertEquals(spec.athenzDomain().get().value(), "domain"); + assertEquals(spec.athenzService(Environment.prod, RegionName.from("us-west-1")).get().value(), "service"); } @Test @@ -392,8 +392,8 @@ public class DeploymentSpecTest { "" ); DeploymentSpec spec = DeploymentSpec.fromXml(r); - assertEquals(spec.athenzDomain().get(), "domain"); - assertEquals(spec.athenzService(Environment.prod, RegionName.from("us-west-1")).get(), "prodservice"); + assertEquals(spec.athenzDomain().get().value(), "domain"); + assertEquals(spec.athenzService(Environment.prod, RegionName.from("us-west-1")).get().value(), "prod-service"); } @Test(expected = IllegalArgumentException.class) -- cgit v1.2.3 From 1e23ba499b681f05f5c19c09e26e4488b4d31121 Mon Sep 17 00:00:00 2001 From: Morten Tokle Date: Thu, 23 Nov 2017 11:43:21 +0100 Subject: Fix failing tests --- .../http/CompressedApplicationInputStreamTest.java | 27 ++++++++++++---------- .../server/http/v2/SessionCreateHandlerTest.java | 27 ++++++++++++++-------- .../server/model/LbServicesProducerTest.java | 5 ++-- .../resources/deploy/advancedapp/deployment.xml | 1 + .../src/test/resources/deploy/app/deployment.xml | 1 + .../test/resources/deploy/validapp/deployment.xml | 1 + 6 files changed, 39 insertions(+), 23 deletions(-) create mode 100644 configserver/src/test/resources/deploy/advancedapp/deployment.xml create mode 100644 configserver/src/test/resources/deploy/app/deployment.xml create mode 100644 configserver/src/test/resources/deploy/validapp/deployment.xml diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/CompressedApplicationInputStreamTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/CompressedApplicationInputStreamTest.java index 5d23f1a4556..ddd29f96695 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/CompressedApplicationInputStreamTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/CompressedApplicationInputStreamTest.java @@ -1,8 +1,8 @@ // 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.http; +import com.google.common.collect.ImmutableList; import com.google.common.io.ByteStreams; -import com.yahoo.vespa.config.server.http.CompressedApplicationInputStream; import org.apache.commons.compress.archivers.ArchiveOutputStream; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; @@ -10,16 +10,19 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import org.junit.Test; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; import java.util.Arrays; import java.util.List; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.Matchers.containsInAnyOrder; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; /** * @author lulf @@ -37,6 +40,7 @@ public class CompressedApplicationInputStreamTest { File app = new File("src/test/resources/deploy/validapp"); writeFileToTar(taos, new File(app, "services.xml")); writeFileToTar(taos, new File(app, "hosts.xml")); + writeFileToTar(taos, new File(app, "deployment.xml")); taos.close(); return outFile; } @@ -55,14 +59,8 @@ public class CompressedApplicationInputStreamTest { void assertTestApp(File outApp) { String [] files = outApp.list(); - assertThat(files.length, is(2)); - if ("hosts.xml".equals(files[0])) { - assertThat(files[1], is("services.xml")); - } else if ("hosts.xml".equals(files[1])) { - assertThat(files[0], is("services.xml")); - } else { - fail("Both services.xml and hosts.xml should be contained in the unpacked application"); - } + assertThat(files.length, is(3)); + assertThat(Arrays.asList(files), containsInAnyOrder(ImmutableList.of(is("hosts.xml"), is("services.xml"), is("deployment.xml")))); } @Test @@ -88,6 +86,10 @@ public class CompressedApplicationInputStreamTest { archiveOutputStream.putArchiveEntry(archiveOutputStream.createArchiveEntry(file, "application/" + file.getName())); ByteStreams.copy(new FileInputStream(file), archiveOutputStream); archiveOutputStream.closeArchiveEntry(); + file = new File(app, "deployment.xml"); + archiveOutputStream.putArchiveEntry(archiveOutputStream.createArchiveEntry(file, "application/" + file.getName())); + ByteStreams.copy(new FileInputStream(file), archiveOutputStream); + archiveOutputStream.closeArchiveEntry(); archiveOutputStream.close(); @@ -134,9 +136,10 @@ public class CompressedApplicationInputStreamTest { new TarArchiveInputStream(new GZIPInputStream(new FileInputStream(gzFile)))); File outApp = unpacked.decompress(); List files = Arrays.asList(outApp.listFiles()); - assertThat(files.size(), is(4)); + assertThat(files.size(), is(5)); assertTrue(files.contains(new File(outApp, "services.xml"))); assertTrue(files.contains(new File(outApp, "hosts.xml"))); + assertTrue(files.contains(new File(outApp, "deployment.xml"))); assertTrue(files.contains(new File(outApp, "searchdefinitions"))); assertTrue(files.contains(new File(outApp, "external"))); File sd = files.get(files.indexOf(new File(outApp, "searchdefinitions"))); diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandlerTest.java index 7fe7b350734..310342e81f1 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandlerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionCreateHandlerTest.java @@ -3,11 +3,11 @@ package com.yahoo.vespa.config.server.http.v2; import com.yahoo.cloud.config.ConfigserverConfig; import com.yahoo.config.model.application.provider.FilesApplicationPackage; +import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.TenantName; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.container.logging.AccessLog; -import com.yahoo.config.provision.ApplicationId; import com.yahoo.vespa.config.server.ApplicationRepository; import com.yahoo.vespa.config.server.application.MemoryTenantApplications; import com.yahoo.vespa.config.server.application.TenantApplications; @@ -15,24 +15,33 @@ import com.yahoo.vespa.config.server.http.CompressedApplicationInputStreamTest; import com.yahoo.vespa.config.server.http.HandlerTest; import com.yahoo.vespa.config.server.http.HttpErrorResponse; import com.yahoo.vespa.config.server.http.SessionHandlerTest; -import com.yahoo.vespa.config.server.session.*; +import com.yahoo.vespa.config.server.session.LocalSessionRepo; +import com.yahoo.vespa.config.server.session.SessionFactory; import com.yahoo.vespa.config.server.tenant.Tenants; -import com.yahoo.vespa.curator.mock.MockCurator; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; import java.time.Clock; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import static com.yahoo.jdisc.Response.Status.*; +import static com.yahoo.jdisc.Response.Status.BAD_REQUEST; +import static com.yahoo.jdisc.Response.Status.INTERNAL_SERVER_ERROR; +import static com.yahoo.jdisc.Response.Status.METHOD_NOT_ALLOWED; +import static com.yahoo.jdisc.Response.Status.OK; +import static com.yahoo.jdisc.http.HttpRequest.Method.GET; +import static com.yahoo.jdisc.http.HttpRequest.Method.POST; import static org.hamcrest.core.Is.is; -import static org.junit.Assert.*; - -import static com.yahoo.jdisc.http.HttpRequest.Method.*; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; /** * @author hmusum @@ -168,7 +177,7 @@ public class SessionCreateHandlerTest extends SessionHandlerTest { assertTrue(applicationPackage.exists()); final File[] files = applicationPackage.listFiles(); assertNotNull(files); - assertThat(files.length, is(2)); + assertThat(files.length, is(3)); } @Test 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 474b93f6972..df8ed405fe3 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 @@ -88,8 +88,9 @@ public class LbServicesProducerTest { private LbServicesConfig createModelAndGetLbServicesConfig(RegionName regionName) throws IOException, SAXException { final Zone zone = new Zone(Environment.prod, regionName); - Map> testModel = createTestModel(new DeployState.Builder(). - properties(new DeployProperties.Builder().zone(zone).build())); + Map> testModel = createTestModel(new DeployState.Builder() + .properties(new DeployProperties.Builder().zone(zone).build()) + .zone(zone)); return getLbServicesConfig(new Zone(Environment.prod, regionName), testModel); } diff --git a/configserver/src/test/resources/deploy/advancedapp/deployment.xml b/configserver/src/test/resources/deploy/advancedapp/deployment.xml new file mode 100644 index 00000000000..fa1d1388e67 --- /dev/null +++ b/configserver/src/test/resources/deploy/advancedapp/deployment.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/configserver/src/test/resources/deploy/app/deployment.xml b/configserver/src/test/resources/deploy/app/deployment.xml new file mode 100644 index 00000000000..fa1d1388e67 --- /dev/null +++ b/configserver/src/test/resources/deploy/app/deployment.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/configserver/src/test/resources/deploy/validapp/deployment.xml b/configserver/src/test/resources/deploy/validapp/deployment.xml new file mode 100644 index 00000000000..fa1d1388e67 --- /dev/null +++ b/configserver/src/test/resources/deploy/validapp/deployment.xml @@ -0,0 +1 @@ + \ No newline at end of file -- cgit v1.2.3