diff options
author | Jon Bratseth <bratseth@verizonmedia.com> | 2019-09-09 13:52:14 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@verizonmedia.com> | 2019-09-09 13:52:14 +0200 |
commit | 01b61de4db4be59d86298d540aaa948c68185585 (patch) | |
tree | 29508a311bc414d7bd6b243e948fb06651fa6350 | |
parent | f78bc7ec2bbab76e5c9bec35d3a7ef3edcff9f40 (diff) |
Allow services.xml variants on application instance name
21 files changed, 323 insertions, 179 deletions
diff --git a/config-application-package/src/main/java/com/yahoo/config/application/OverrideProcessor.java b/config-application-package/src/main/java/com/yahoo/config/application/OverrideProcessor.java index 0599afa056d..15b775a4543 100644 --- a/config-application-package/src/main/java/com/yahoo/config/application/OverrideProcessor.java +++ b/config-application-package/src/main/java/com/yahoo/config/application/OverrideProcessor.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.config.application; -import com.google.common.collect.ImmutableSet; import com.yahoo.config.provision.Environment; +import com.yahoo.config.provision.InstanceName; import com.yahoo.config.provision.RegionName; import com.yahoo.log.LogLevel; import com.yahoo.text.XML; @@ -38,13 +38,22 @@ class OverrideProcessor implements PreProcessor { private static final Logger log = Logger.getLogger(OverrideProcessor.class.getName()); + private final InstanceName instance; private final Environment environment; private final RegionName region; - private static final String ATTR_ID = "id"; - private static final String ATTR_ENV = "environment"; - private static final String ATTR_REG = "region"; + private static final String ID_ATTRIBUTE = "id"; + private static final String INSTANCE_ATTRIBUTE = "instance"; + private static final String ENVIRONMENT_ATTRIBUTE = "environment"; + private static final String REGION_ATTRIBUTE = "region"; + + // TODO: Remove after September 2019 public OverrideProcessor(Environment environment, RegionName region) { + this(InstanceName.from("default"), environment, region); + } + + public OverrideProcessor(InstanceName instance, Environment environment, RegionName region) { + this.instance = instance; this.environment = environment; this.region = region; } @@ -73,42 +82,53 @@ class OverrideProcessor implements PreProcessor { for (Element child : XML.getChildren(parent)) { applyOverrides(child, context); // Remove attributes - child.removeAttributeNS(XmlPreProcessor.deployNamespaceUri, ATTR_ENV); - child.removeAttributeNS(XmlPreProcessor.deployNamespaceUri, ATTR_REG); + child.removeAttributeNS(XmlPreProcessor.deployNamespaceUri, INSTANCE_ATTRIBUTE); + child.removeAttributeNS(XmlPreProcessor.deployNamespaceUri, ENVIRONMENT_ATTRIBUTE); + child.removeAttributeNS(XmlPreProcessor.deployNamespaceUri, REGION_ATTRIBUTE); } } private Context getParentContext(Element parent, Context context) { + Set<InstanceName> instances = context.instances; Set<Environment> environments = context.environments; Set<RegionName> regions = context.regions; + if (instances.isEmpty()) + instances = getInstances(parent); if (environments.isEmpty()) environments = getEnvironments(parent); if (regions.isEmpty()) regions = getRegions(parent); - return Context.create(environments, regions); + return Context.create(instances, environments, regions); } /** * Prune overrides from parent according to deploy override rules. * - * @param parent Parent {@link Element} above children. - * @param children Children where one {@link Element} will remain as the overriding element - * @param context Current context with environment and region. + * @param parent parent {@link Element} above children. + * @param children children where one {@link Element} will remain as the overriding element + * @param context current context with instance, environment and region. */ private void pruneOverrides(Element parent, List<Element> children, Context context) { checkConsistentInheritance(children, context); - pruneNonMatchingEnvironmentsAndRegions(parent, children); - retainMostSpecificEnvironmentAndRegion(parent, children, context); + pruneNonMatching(parent, children); + retainMostSpecific(parent, children, context); } private void checkConsistentInheritance(List<Element> children, Context context) { for (Element child : children) { + Set<InstanceName> instances = getInstances(child); + if ( ! instances.isEmpty() && ! context.instances.isEmpty() && ! context.instances.containsAll(instances)) { + throw new IllegalArgumentException("Instances in child (" + instances + + ") are not a subset of those of the parent (" + context.instances + ") at " + child); + } + Set<Environment> environments = getEnvironments(child); - Set<RegionName> regions = getRegions(child); if ( ! environments.isEmpty() && ! context.environments.isEmpty() && ! context.environments.containsAll(environments)) { throw new IllegalArgumentException("Environments in child (" + environments + ") are not a subset of those of the parent (" + context.environments + ") at " + child); } + + Set<RegionName> regions = getRegions(child); if ( ! regions.isEmpty() && ! context.regions.isEmpty() && ! context.regions.containsAll(regions)) { throw new IllegalArgumentException("Regions in child (" + regions + ") are not a subset of those of the parent (" + context.regions + ") at " + child); @@ -119,18 +139,24 @@ class OverrideProcessor implements PreProcessor { /** * Prune elements that are not matching our environment and region */ - private void pruneNonMatchingEnvironmentsAndRegions(Element parent, List<Element> children) { + private void pruneNonMatching(Element parent, List<Element> children) { Iterator<Element> elemIt = children.iterator(); while (elemIt.hasNext()) { Element child = elemIt.next(); - if ( ! matches(getEnvironments(child), getRegions(child))) { + if ( ! matches(getInstances(child), getEnvironments(child), getRegions(child))) { parent.removeChild(child); elemIt.remove(); } } } - private boolean matches(Set<Environment> elementEnvironments, Set<RegionName> elementRegions) { + private boolean matches(Set<InstanceName> elementInstances, + Set<Environment> elementEnvironments, + Set<RegionName> elementRegions) { + if ( ! elementInstances.isEmpty()) { // match instance + if ( ! elementInstances.contains(instance)) return false; + } + if ( ! elementEnvironments.isEmpty()) { // match environment if ( ! elementEnvironments.contains(environment)) return false; } @@ -149,7 +175,7 @@ class OverrideProcessor implements PreProcessor { /** * Find the most specific element and remove all others. */ - private void retainMostSpecificEnvironmentAndRegion(Element parent, List<Element> children, Context context) { + private void retainMostSpecific(Element parent, List<Element> children, Context context) { // Keep track of elements with highest number of matches (might be more than one element with same tag, need a list) List<Element> bestMatches = new ArrayList<>(); int bestMatch = 0; @@ -181,8 +207,11 @@ class OverrideProcessor implements PreProcessor { private int getNumberOfOverrides(Element child, Context context) { int currentMatch = 0; + Set<InstanceName> elementInstances = hasInstance(child) ? getInstances(child) : context.instances; Set<Environment> elementEnvironments = hasEnvironment(child) ? getEnvironments(child) : context.environments; Set<RegionName> elementRegions = hasRegion(child) ? getRegions(child) : context.regions; + if ( ! elementInstances.isEmpty() && elementInstances.contains(instance)) + currentMatch++; if ( ! elementEnvironments.isEmpty() && elementEnvironments.contains(environment)) currentMatch++; if ( ! elementRegions.isEmpty() && elementRegions.contains(region)) @@ -192,7 +221,7 @@ class OverrideProcessor implements PreProcessor { /** Called on each element which is selected by matching some override condition */ private void doElementSpecificProcessingOnOverride(List<Element> elements) { - // if node capacity is specified explicitly for some env/region we should require that capacity + // if node capacity is specified explicitly for some combination we should require that capacity elements.forEach(element -> { if (element.getTagName().equals("nodes")) if (element.getChildNodes().getLength() == 0) // specifies capacity, not a list of nodes @@ -219,22 +248,32 @@ class OverrideProcessor implements PreProcessor { } } + private boolean hasInstance(Element element) { + return element.hasAttributeNS(XmlPreProcessor.deployNamespaceUri, INSTANCE_ATTRIBUTE); + } + private boolean hasRegion(Element element) { - return element.hasAttributeNS(XmlPreProcessor.deployNamespaceUri, ATTR_REG); + return element.hasAttributeNS(XmlPreProcessor.deployNamespaceUri, REGION_ATTRIBUTE); } private boolean hasEnvironment(Element element) { - return element.hasAttributeNS(XmlPreProcessor.deployNamespaceUri, ATTR_ENV); + return element.hasAttributeNS(XmlPreProcessor.deployNamespaceUri, ENVIRONMENT_ATTRIBUTE); + } + + private Set<InstanceName> getInstances(Element element) { + String instance = element.getAttributeNS(XmlPreProcessor.deployNamespaceUri, INSTANCE_ATTRIBUTE); + if (instance == null || instance.isEmpty()) return Collections.emptySet(); + return Arrays.stream(instance.split(" ")).map(InstanceName::from).collect(Collectors.toSet()); } private Set<Environment> getEnvironments(Element element) { - String env = element.getAttributeNS(XmlPreProcessor.deployNamespaceUri, ATTR_ENV); + String env = element.getAttributeNS(XmlPreProcessor.deployNamespaceUri, ENVIRONMENT_ATTRIBUTE); if (env == null || env.isEmpty()) return Collections.emptySet(); return Arrays.stream(env.split(" ")).map(Environment::from).collect(Collectors.toSet()); } private Set<RegionName> getRegions(Element element) { - String reg = element.getAttributeNS(XmlPreProcessor.deployNamespaceUri, ATTR_REG); + String reg = element.getAttributeNS(XmlPreProcessor.deployNamespaceUri, REGION_ATTRIBUTE); if (reg == null || reg.isEmpty()) return Collections.emptySet(); return Arrays.stream(reg.split(" ")).map(RegionName::from).collect(Collectors.toSet()); } @@ -244,10 +283,10 @@ class OverrideProcessor implements PreProcessor { // Index by tag name for (Element child : children) { String key = child.getTagName(); - if (child.hasAttribute(ATTR_ID)) { - key += child.getAttribute(ATTR_ID); + if (child.hasAttribute(ID_ATTRIBUTE)) { + key += child.getAttribute(ID_ATTRIBUTE); } - if (!elementsByTagName.containsKey(key)) { + if ( ! elementsByTagName.containsKey(key)) { elementsByTagName.put(key, new ArrayList<>()); } elementsByTagName.get(key).add(child); @@ -290,21 +329,24 @@ class OverrideProcessor implements PreProcessor { */ private static final class Context { - final ImmutableSet<Environment> environments; - - final ImmutableSet<RegionName> regions; + final Set<InstanceName> instances; + final Set<Environment> environments; + final Set<RegionName> regions; - private Context(Set<Environment> environments, Set<RegionName> regions) { - this.environments = ImmutableSet.copyOf(environments); - this.regions = ImmutableSet.copyOf(regions); + private Context(Set<InstanceName> instances, Set<Environment> environments, Set<RegionName> regions) { + this.instances = Set.copyOf(instances); + this.environments = Set.copyOf(environments); + this.regions = Set.copyOf(regions); } static Context empty() { - return new Context(ImmutableSet.of(), ImmutableSet.of()); + return new Context(Set.of(), Set.of(), Set.of()); } - public static Context create(Set<Environment> environments, Set<RegionName> regions) { - return new Context(environments, regions); + public static Context create(Set<InstanceName> instances, + Set<Environment> environments, + Set<RegionName> regions) { + return new Context(instances, environments, regions); } } diff --git a/config-application-package/src/main/java/com/yahoo/config/application/XmlPreProcessor.java b/config-application-package/src/main/java/com/yahoo/config/application/XmlPreProcessor.java index 261a684353b..73f97cf516f 100644 --- a/config-application-package/src/main/java/com/yahoo/config/application/XmlPreProcessor.java +++ b/config-application-package/src/main/java/com/yahoo/config/application/XmlPreProcessor.java @@ -2,6 +2,7 @@ package com.yahoo.config.application; import com.yahoo.config.provision.Environment; +import com.yahoo.config.provision.InstanceName; import com.yahoo.config.provision.RegionName; import org.w3c.dom.Document; import org.xml.sax.InputSource; @@ -32,17 +33,29 @@ public class XmlPreProcessor { private final File applicationDir; private final Reader xmlInput; + private final InstanceName instance; private final Environment environment; private final RegionName region; private final List<PreProcessor> chain; + // TODO: Remove after September 2019 public XmlPreProcessor(File applicationDir, File xmlInput, Environment environment, RegionName region) throws IOException { - this(applicationDir, new FileReader(xmlInput), environment, region); + this(applicationDir, new FileReader(xmlInput), InstanceName.from("default"), environment, region); } + public XmlPreProcessor(File applicationDir, File xmlInput, InstanceName instance, Environment environment, RegionName region) throws IOException { + this(applicationDir, new FileReader(xmlInput), instance, environment, region); + } + + // TODO: Remove after September 2019 public XmlPreProcessor(File applicationDir, Reader xmlInput, Environment environment, RegionName region) throws IOException { + this(applicationDir, xmlInput, InstanceName.from("default"), environment, region); + } + + public XmlPreProcessor(File applicationDir, Reader xmlInput, InstanceName instance, Environment environment, RegionName region) { this.applicationDir = applicationDir; this.xmlInput = xmlInput; + this.instance = instance; this.environment = environment; this.region = region; this.chain = setupChain(); @@ -64,7 +77,7 @@ public class XmlPreProcessor { private List<PreProcessor> setupChain() { List<PreProcessor> chain = new ArrayList<>(); chain.add(new IncludeProcessor(applicationDir)); - chain.add(new OverrideProcessor(environment, region)); + chain.add(new OverrideProcessor(instance, environment, region)); chain.add(new PropertiesProcessor()); return chain; } diff --git a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/DeployData.java b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/DeployData.java index cd13305c009..344035745f8 100644 --- a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/DeployData.java +++ b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/DeployData.java @@ -1,8 +1,13 @@ // 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.application.provider; +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.ApplicationName; +import com.yahoo.config.provision.InstanceName; +import com.yahoo.config.provision.TenantName; + /** - * A class for holding values generated or computed during deployment + * Data generated or computed during deployment * * @author hmusum */ @@ -11,8 +16,7 @@ public class DeployData { /** Which user deployed */ private final String deployedByUser; - /** Name of application given by user */ - private final String applicationName; + private final ApplicationId applicationId; /** The absolute path to the directory holding the application */ private final String deployedFromDir; @@ -27,6 +31,7 @@ public class DeployData { private final long generation; private final long currentlyActiveGeneration; + // TODO: Remove after September 2019 public DeployData(String deployedByUser, String deployedFromDir, String applicationName, @@ -34,39 +39,45 @@ public class DeployData { boolean internalRedeploy, Long generation, long currentlyActiveGeneration) { + this(deployedByUser, + deployedFromDir, + ApplicationId.from(TenantName.defaultName(), ApplicationName.from(applicationName), InstanceName.from("default")), + deployTimestamp, + internalRedeploy, + generation, currentlyActiveGeneration); + } + + public DeployData(String deployedByUser, + String deployedFromDir, + ApplicationId applicationId, + Long deployTimestamp, + boolean internalRedeploy, + Long generation, + long currentlyActiveGeneration) { this.deployedByUser = deployedByUser; this.deployedFromDir = deployedFromDir; - this.applicationName = applicationName; + this.applicationId = applicationId; this.deployTimestamp = deployTimestamp; this.internalRedeploy = internalRedeploy; this.generation = generation; this.currentlyActiveGeneration = currentlyActiveGeneration; } - public String getDeployedByUser() { - return deployedByUser; - } + public String getDeployedByUser() { return deployedByUser; } - public String getDeployedFromDir() { - return deployedFromDir; - } + public String getDeployedFromDir() { return deployedFromDir; } - public long getDeployTimestamp() { - return deployTimestamp; - } + public long getDeployTimestamp() { return deployTimestamp; } public boolean isInternalRedeploy() { return internalRedeploy; } - public long getGeneration() { - return generation; - } + public long getGeneration() { return generation; } - public long getCurrentlyActiveGeneration() { - return currentlyActiveGeneration; - } + public long getCurrentlyActiveGeneration() { return currentlyActiveGeneration; } - public String getApplicationName() { - return applicationName; - } + public ApplicationId getApplicationId() { return applicationId; } + + // TODO: remove after September 2019 + public String getApplicationName() { return applicationId.application().toString(); } } diff --git a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java index b2a1507b424..2859d9f89fc 100644 --- a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java +++ b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java @@ -13,6 +13,10 @@ import com.yahoo.config.application.api.UnparsedConfigDefinition; import com.yahoo.config.codegen.DefParser; import com.yahoo.config.application.api.ApplicationFile; import com.yahoo.config.application.api.ApplicationPackage; +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.ApplicationName; +import com.yahoo.config.provision.InstanceName; +import com.yahoo.config.provision.TenantName; import com.yahoo.config.provision.Zone; import com.yahoo.path.Path; import com.yahoo.io.HexDump; @@ -117,7 +121,7 @@ public class FilesApplicationPackage implements ApplicationPackage { deployData.getDeployedFromDir(), deployData.getDeployTimestamp(), deployData.isInternalRedeploy(), - deployData.getApplicationName(), + deployData.getApplicationId(), computeCheckSum(appDir), deployData.getGeneration(), deployData.getCurrentlyActiveGeneration()); @@ -144,8 +148,10 @@ public class FilesApplicationPackage implements ApplicationPackage { this.metaData = metaData; } + @Override + @SuppressWarnings("deprecation") public String getApplicationName() { - return metaData.getApplicationName(); + return metaData.getApplicationId().application().value(); } @Override @@ -571,9 +577,18 @@ public class FilesApplicationPackage implements ApplicationPackage { } private static ApplicationMetaData readMetaData(File appDir) { - ApplicationMetaData defaultMetaData = new ApplicationMetaData(appDir, "n/a", "n/a", 0l, false, "", 0l, 0l); + ApplicationMetaData defaultMetaData = new ApplicationMetaData("n/a", + "n/a", + 0L, + false, + ApplicationId.from(TenantName.defaultName(), + ApplicationName.from(appDir.getName()), + InstanceName.defaultName()), + "", + 0L, + 0L); File metaFile = new File(appDir, META_FILE_NAME); - if (!metaFile.exists()) { + if ( ! metaFile.exists()) { return defaultMetaData; } try (FileReader reader = new FileReader(metaFile)) { @@ -663,7 +678,11 @@ public class FilesApplicationPackage implements ApplicationPackage { } private void preprocessXML(File destination, File inputXml, Zone zone) throws ParserConfigurationException, TransformerException, SAXException, IOException { - Document document = new XmlPreProcessor(appDir, inputXml, zone.environment(), zone.region()).run(); + Document document = new XmlPreProcessor(appDir, + inputXml, + metaData.getApplicationId().instance(), + zone.environment(), + zone.region()).run(); Transformer transformer = TransformerFactory.newInstance().newTransformer(); try (FileOutputStream outputStream = new FileOutputStream(destination)) { transformer.transform(new DOMSource(document), new StreamResult(outputStream)); diff --git a/config-application-package/src/test/java/com/yahoo/config/application/HostedOverrideProcessorTest.java b/config-application-package/src/test/java/com/yahoo/config/application/HostedOverrideProcessorTest.java index 4c6a3eb3513..d19ea177d9b 100644 --- a/config-application-package/src/test/java/com/yahoo/config/application/HostedOverrideProcessorTest.java +++ b/config-application-package/src/test/java/com/yahoo/config/application/HostedOverrideProcessorTest.java @@ -2,6 +2,7 @@ package com.yahoo.config.application; import com.yahoo.config.provision.Environment; +import com.yahoo.config.provision.InstanceName; import com.yahoo.config.provision.RegionName; import org.custommonkey.xmlunit.XMLUnit; import org.junit.Test; @@ -33,6 +34,7 @@ public class HostedOverrideProcessorTest { " <nodes deploy:environment='prod' count='3' flavor='v-4-8-100'/>" + " <nodes deploy:environment='prod' deploy:region='us-west' count='4'/>" + " <nodes deploy:environment='prod' deploy:region='us-east-3' flavor='v-8-8-100' count='5'/>" + + " <nodes deploy:instance='myinstance' deploy:environment='prod' deploy:region='us-west' count='1'/>" + " </container>" + "</services>"; @@ -62,6 +64,18 @@ public class HostedOverrideProcessorTest { } @Test + public void testParsingInstance() throws TransformerException { + String expected = + "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" + + "<services xmlns:deploy=\"vespa\" xmlns:preprocess=\"?\" version=\"1.0\">" + + " <container id=\"foo\" version=\"1.0\">" + + " <nodes count='1' required='true'/>" + + " </container>" + + "</services>"; + assertOverride(InstanceName.from("myinstance"), Environment.from("prod"), RegionName.from("us-west"), expected); + } + + @Test public void testParsingEnvironmentAndRegion2() throws TransformerException { String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" + @@ -146,8 +160,12 @@ public class HostedOverrideProcessorTest { } private void assertOverride(Environment environment, RegionName region, String expected) throws TransformerException { + assertOverride(InstanceName.from("default"), environment, region, expected); + } + + private void assertOverride(InstanceName instance, Environment environment, RegionName region, String expected) throws TransformerException { Document inputDoc = Xml.getDocument(new StringReader(input)); - Document newDoc = new OverrideProcessor(environment, region).process(inputDoc); + Document newDoc = new OverrideProcessor(instance, environment, region).process(inputDoc); TestBase.assertDocument(expected, newDoc); } diff --git a/config-application-package/src/test/java/com/yahoo/config/application/MultiOverrideProcessorTest.java b/config-application-package/src/test/java/com/yahoo/config/application/MultiOverrideProcessorTest.java index 7c054ec62ee..b9b8a9dd798 100644 --- a/config-application-package/src/test/java/com/yahoo/config/application/MultiOverrideProcessorTest.java +++ b/config-application-package/src/test/java/com/yahoo/config/application/MultiOverrideProcessorTest.java @@ -2,6 +2,7 @@ package com.yahoo.config.application; import com.yahoo.config.provision.Environment; +import com.yahoo.config.provision.InstanceName; import com.yahoo.config.provision.RegionName; import org.custommonkey.xmlunit.XMLUnit; import org.junit.Test; @@ -123,13 +124,13 @@ public class MultiOverrideProcessorTest { private void assertOverride(Environment environment, RegionName region, String expected) throws TransformerException { Document inputDoc = Xml.getDocument(new StringReader(input)); - Document newDoc = new OverrideProcessor(environment, region).process(inputDoc); + Document newDoc = new OverrideProcessor(InstanceName.from("default"), environment, region).process(inputDoc); TestBase.assertDocument(expected, newDoc); } private void assertOverrideWithIds(Environment environment, RegionName region, String expected) throws TransformerException { Document inputDoc = Xml.getDocument(new StringReader(inputWithIds)); - Document newDoc = new OverrideProcessor(environment, region).process(inputDoc); + Document newDoc = new OverrideProcessor(InstanceName.from("default"), environment, region).process(inputDoc); TestBase.assertDocument(expected, newDoc); } diff --git a/config-application-package/src/test/java/com/yahoo/config/application/OverrideProcessorTest.java b/config-application-package/src/test/java/com/yahoo/config/application/OverrideProcessorTest.java index 9113ce7f016..05a5357a8ab 100644 --- a/config-application-package/src/test/java/com/yahoo/config/application/OverrideProcessorTest.java +++ b/config-application-package/src/test/java/com/yahoo/config/application/OverrideProcessorTest.java @@ -2,6 +2,7 @@ package com.yahoo.config.application; import com.yahoo.config.provision.Environment; +import com.yahoo.config.provision.InstanceName; import com.yahoo.config.provision.RegionName; import org.custommonkey.xmlunit.XMLUnit; import org.junit.Test; @@ -331,7 +332,7 @@ public class OverrideProcessorTest { " </admin>" + "</services>"; Document inputDoc = Xml.getDocument(new StringReader(in)); - new OverrideProcessor(Environment.from("prod"), RegionName.from("us-west")).process(inputDoc); + new OverrideProcessor(InstanceName.from("default"), Environment.from("prod"), RegionName.from("us-west")).process(inputDoc); } @Test(expected = IllegalArgumentException.class) @@ -343,12 +344,12 @@ public class OverrideProcessorTest { " </admin>" + "</services>"; Document inputDoc = Xml.getDocument(new StringReader(in)); - new OverrideProcessor(Environment.defaultEnvironment(), RegionName.from("us-west")).process(inputDoc); + new OverrideProcessor(InstanceName.from("default"), Environment.defaultEnvironment(), RegionName.from("us-west")).process(inputDoc); } private void assertOverride(Environment environment, RegionName region, String expected) throws TransformerException { Document inputDoc = Xml.getDocument(new StringReader(OverrideProcessorTest.input)); - Document newDoc = new OverrideProcessor(environment, region).process(inputDoc); + Document newDoc = new OverrideProcessor(InstanceName.from("default"), environment, region).process(inputDoc); TestBase.assertDocument(expected, newDoc); } diff --git a/config-application-package/src/test/java/com/yahoo/config/application/PropertiesProcessorTest.java b/config-application-package/src/test/java/com/yahoo/config/application/PropertiesProcessorTest.java index 038447c7b99..fe9ca4a7951 100644 --- a/config-application-package/src/test/java/com/yahoo/config/application/PropertiesProcessorTest.java +++ b/config-application-package/src/test/java/com/yahoo/config/application/PropertiesProcessorTest.java @@ -26,7 +26,7 @@ public class PropertiesProcessorTest { } @Test - public void testPropertyValues() throws ParserConfigurationException, TransformerException, SAXException, IOException { + public void testPropertyValues() throws TransformerException { String input = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" + "<services xmlns:deploy=\"vespa\" xmlns:preprocess=\"properties\" version=\"1.0\">" + " <preprocess:properties>" + @@ -50,7 +50,7 @@ public class PropertiesProcessorTest { } @Test - public void testPropertyApplying() throws IOException, SAXException, XMLStreamException, ParserConfigurationException, TransformerException { + public void testPropertyApplying() throws TransformerException { String input = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" + "<services xmlns:deploy=\"vespa\" xmlns:preprocess=\"properties\" version=\"1.0\">" + " <preprocess:properties>" + @@ -104,7 +104,7 @@ public class PropertiesProcessorTest { // TODO: Check that warning is actually logged @Test - public void testWarnIfDuplicatePropertyForSameEnvironment() throws IOException, SAXException, XMLStreamException, ParserConfigurationException, TransformerException { + public void testWarnIfDuplicatePropertyForSameEnvironment() throws TransformerException { String input = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" + "<services xmlns:deploy=\"vespa\" xmlns:preprocess=\"properties\" version=\"1.0\">" + " <preprocess:properties>" + diff --git a/config-application-package/src/test/java/com/yahoo/config/application/XmlPreprocessorTest.java b/config-application-package/src/test/java/com/yahoo/config/application/XmlPreprocessorTest.java index eacaa4a881a..549fbdb41ea 100644 --- a/config-application-package/src/test/java/com/yahoo/config/application/XmlPreprocessorTest.java +++ b/config-application-package/src/test/java/com/yahoo/config/application/XmlPreprocessorTest.java @@ -2,6 +2,7 @@ package com.yahoo.config.application; import com.yahoo.config.provision.Environment; +import com.yahoo.config.provision.InstanceName; import com.yahoo.config.provision.RegionName; import org.junit.Test; import org.w3c.dom.Document; @@ -48,7 +49,7 @@ public class XmlPreprocessorTest { " </nodes>\n" + " </container>\n" + "</services>"; - TestBase.assertDocument(expectedDev, new XmlPreProcessor(appDir, services, Environment.dev, RegionName.from("default")).run()); + TestBase.assertDocument(expectedDev, new XmlPreProcessor(appDir, services, InstanceName.defaultName(), Environment.dev, RegionName.from("default")).run()); String expectedStaging = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" + @@ -75,7 +76,7 @@ public class XmlPreprocessorTest { " </container>\n" + "</services>"; // System.out.println(Xml.documentAsString(new XmlPreProcessor(appDir, services, Environment.staging, RegionName.from("default")).run())); - TestBase.assertDocument(expectedStaging, new XmlPreProcessor(appDir, services, Environment.staging, RegionName.from("default")).run()); + TestBase.assertDocument(expectedStaging, new XmlPreProcessor(appDir, services, InstanceName.defaultName(), Environment.staging, RegionName.from("default")).run()); String expectedUsWest = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" + @@ -109,7 +110,7 @@ public class XmlPreprocessorTest { " </nodes>\n" + " </container>\n" + "</services>"; - TestBase.assertDocument(expectedUsWest, new XmlPreProcessor(appDir, services, Environment.prod, RegionName.from("us-west")).run()); + TestBase.assertDocument(expectedUsWest, new XmlPreProcessor(appDir, services, InstanceName.defaultName(), Environment.prod, RegionName.from("us-west")).run()); String expectedUsEastAndCentral = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" + @@ -143,9 +144,9 @@ public class XmlPreprocessorTest { " </container>\n" + "</services>"; TestBase.assertDocument(expectedUsEastAndCentral, - new XmlPreProcessor(appDir, services, Environment.prod, RegionName.from("us-east")).run()); + new XmlPreProcessor(appDir, services, InstanceName.defaultName(), Environment.prod, RegionName.from("us-east")).run()); TestBase.assertDocument(expectedUsEastAndCentral, - new XmlPreProcessor(appDir, services, Environment.prod, RegionName.from("us-central")).run()); + new XmlPreProcessor(appDir, services, InstanceName.defaultName(), Environment.prod, RegionName.from("us-central")).run()); } @Test @@ -189,7 +190,7 @@ public class XmlPreprocessorTest { " <adminserver hostalias=\"node0\"/>" + " </admin>" + "</services>"; - Document docDev = (new XmlPreProcessor(appDir, new StringReader(input), Environment.prod, RegionName.from("default")).run()); + Document docDev = (new XmlPreProcessor(appDir, new StringReader(input), InstanceName.defaultName(), Environment.prod, RegionName.from("default")).run()); TestBase.assertDocument(expectedProd, docDev); } diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationMetaData.java b/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationMetaData.java index 236a954f483..c4dee70cd86 100644 --- a/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationMetaData.java +++ b/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationMetaData.java @@ -1,6 +1,10 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.application.api; +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.ApplicationName; +import com.yahoo.config.provision.InstanceName; +import com.yahoo.config.provision.TenantName; import com.yahoo.slime.*; import com.yahoo.text.Utf8; @@ -18,26 +22,45 @@ public class ApplicationMetaData { private final String deployedFromDir; private final long deployTimestamp; private final boolean internalRedeploy; + private final ApplicationId applicationId; + private final String checksum; private final long generation; private final long previousActiveGeneration; - private final String checkSum; - private final String appName; - public ApplicationMetaData(File appDir, String deployedByUser, String deployedFromDir, Long deployTimestamp, + // TODO: Remove after September 2019 + public ApplicationMetaData(File appDir, + String deployedByUser, + String deployedFromDir, + Long deployTimestamp, boolean internalRedeploy, - String checkSum, Long generation, long previousActiveGeneration) { + String checksum, + Long generation, + long previousActiveGeneration) { this(deployedByUser, deployedFromDir, deployTimestamp, internalRedeploy, - appDir.getName(), checkSum, generation, previousActiveGeneration); + appDir.getName(), checksum, generation, previousActiveGeneration); } + // TODO: Remove after September 2019 public ApplicationMetaData(String deployedByUser, String deployedFromDir, Long deployTimestamp, boolean internalRedeploy, - String applicationName, String checkSum, Long generation, long previousActiveGeneration) { - this.appName = applicationName; + String applicationName, String checksum, Long generation, long previousActiveGeneration) { + this(deployedByUser, + deployedFromDir, + deployTimestamp, + internalRedeploy, + ApplicationId.from(TenantName.defaultName(), ApplicationName.from(applicationName), InstanceName.from("default")), + checksum, + generation, + previousActiveGeneration); + } + + public ApplicationMetaData(String deployedByUser, String deployedFromDir, Long deployTimestamp, boolean internalRedeploy, + ApplicationId applicationId, String checksum, Long generation, long previousActiveGeneration) { this.deployedByUser = deployedByUser; this.deployedFromDir = deployedFromDir; this.deployTimestamp = deployTimestamp; this.internalRedeploy = internalRedeploy; - this.checkSum = checkSum; + this.applicationId = applicationId; + this.checksum = checksum; this.generation = generation; this.previousActiveGeneration = previousActiveGeneration; } @@ -48,9 +71,8 @@ public class ApplicationMetaData { * * @return application name */ - public String getApplicationName() { - return appName; - } + // TODO: Remove after September 2019 + public String getApplicationName() { return applicationId.application().toString(); } /** * Gets the user who deployed the application. @@ -68,9 +90,9 @@ public class ApplicationMetaData { * * @return path to raw deploy directory (for the original application) */ - public String getDeployPath() { - return deployedFromDir; - } + public String getDeployPath() { return deployedFromDir; } + + public ApplicationId getApplicationId() { return applicationId; } /** * Gets the time the application was deployed @@ -78,19 +100,15 @@ public class ApplicationMetaData { * * @return timestamp for when "deploy-application" was run. In ms. */ - public Long getDeployTimestamp() { - return deployTimestamp; - } + public Long getDeployTimestamp() { return deployTimestamp; } /** - * Gets the time the application was deployed + * Gets the time the application was deployed. * Will return null if a problem occurred while getting metadata * * @return timestamp for when "deploy-application" was run. In ms. */ - public Long getGeneration() { - return generation; - } + public Long getGeneration() { return generation; } /** * Returns whether this application generation was produced by a system internal redeployment, @@ -98,25 +116,20 @@ public class ApplicationMetaData { */ public boolean isInternalRedeploy() { return internalRedeploy; } - /** - * Returns an md5 hash of the contents of the application package - * @return an md5sum of the application package - */ - public String getCheckSum() { - return checkSum; - } + /** Returns an md5 hash of the contents of the application package */ + // TODO: Remove after September 2019 + public String getCheckSum() { return checksum; } - /** - * Returns the previously active generation at the point when this application was created. - * @return a generation. - */ - public long getPreviousActiveGeneration() { - return previousActiveGeneration; - } + /** Returns an md5 hash of the contents of the application package */ + public String getChecksum() { return checksum; } + + /** Returns the previously active generation at the point when this application was created. */ + public long getPreviousActiveGeneration() { return previousActiveGeneration; } @Override public String toString() { - return deployedByUser + ", " + deployedFromDir + ", " + deployTimestamp + ", " + generation + ", " + checkSum + ", " + previousActiveGeneration; + return deployedByUser + ", " + deployedFromDir + ", " + deployTimestamp + ", " + generation + ", " + + checksum + ", " + previousActiveGeneration; } public static ApplicationMetaData fromJsonString(String jsonString) { @@ -126,11 +139,19 @@ public class ApplicationMetaData { Inspector root = data.get(); Inspector deploy = root.field("deploy"); Inspector app = root.field("application"); + + // TODO: Simplify to just ApplicationId.fromSerializedForm(app.field("id").asString()) after September 2019 + ApplicationId applicationId = app.field("id").valid() ? + ApplicationId.fromSerializedForm(app.field("id").asString()) : + ApplicationId.from(TenantName.defaultName(), + ApplicationName.from(app.field("name").asString()), + InstanceName.from("default")); + return new ApplicationMetaData(deploy.field("user").asString(), deploy.field("from").asString(), deploy.field("timestamp").asLong(), booleanField("internalRedeploy", false, deploy), - app.field("name").asString(), + applicationId, app.field("checksum").asString(), app.field("generation").asLong(), app.field("previousActiveGeneration").asLong()); @@ -148,8 +169,9 @@ public class ApplicationMetaData { deploy.setLong("timestamp", deployTimestamp); deploy.setBool("internalRedeploy", internalRedeploy); Cursor app = meta.setObject("application"); - app.setString("name", appName); - app.setString("checksum", checkSum); + app.setString("id", applicationId.serializedForm()); + app.setString("name", applicationId.application().value()); // TODO: Remove after September 2019 + app.setString("checksum", checksum); app.setLong("generation", generation); app.setLong("previousActiveGeneration", previousActiveGeneration); return slime; diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationPackage.java b/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationPackage.java index 5cd119dcf65..48dd3663cc6 100644 --- a/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationPackage.java +++ b/config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationPackage.java @@ -85,7 +85,9 @@ public interface ApplicationPackage { * The name of the application package * * @return the name of the application (i.e the directory where the application package was deployed from) + * @deprecated do not use */ + @Deprecated // TODO: Remove on Vespa 8 String getApplicationName(); /** diff --git a/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java b/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java index 60435decb04..538b2f0f957 100644 --- a/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java +++ b/config-model/src/main/java/com/yahoo/config/model/test/MockApplicationPackage.java @@ -6,6 +6,10 @@ import com.yahoo.config.application.api.ComponentInfo; import com.yahoo.config.application.api.UnparsedConfigDefinition; import com.yahoo.config.application.api.ApplicationFile; import com.yahoo.component.Version; +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.ApplicationName; +import com.yahoo.config.provision.InstanceName; +import com.yahoo.config.provision.TenantName; import com.yahoo.io.IOUtils; import com.yahoo.path.Path; import com.yahoo.io.reader.NamedReader; @@ -73,13 +77,23 @@ public class MockApplicationPackage implements ApplicationPackage { this.failOnValidateXml = failOnValidateXml; queryProfileRegistry = new QueryProfileXMLReader().read(asNamedReaderList(queryProfileType), asNamedReaderList(queryProfile)); - applicationMetaData = new ApplicationMetaData(DEPLOYED_BY_USER, "dir", 0L, false, APPLICATION_NAME, "checksum", APPLICATION_GENERATION, 0L); + applicationMetaData = new ApplicationMetaData(DEPLOYED_BY_USER, + "dir", + 0L, + false, + ApplicationId.from(TenantName.defaultName(), + ApplicationName.from(APPLICATION_NAME), + InstanceName.defaultName()), + "checksum", + APPLICATION_GENERATION, + 0L); } /** Returns the root of this application package relative to the current dir */ protected File root() { return root; } @Override + @SuppressWarnings("deprecation") public String getApplicationName() { return "mock application"; } 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 15caebb19cc..4e043b0f2bf 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 @@ -449,11 +449,11 @@ public abstract class ContainerCluster<CONTAINER extends Container> @Override public void getConfig(ApplicationMetadataConfig.Builder builder) { if (applicationMetaData != null) { - builder.name(applicationMetaData.getApplicationName()). + builder.name(applicationMetaData.getApplicationId().application().value()). user(applicationMetaData.getDeployedByUser()). path(applicationMetaData.getDeployPath()). timestamp(applicationMetaData.getDeployTimestamp()). - checksum(applicationMetaData.getCheckSum()). + checksum(applicationMetaData.getChecksum()). generation(applicationMetaData.getGeneration()); } } diff --git a/config-model/src/test/java/com/yahoo/config/model/ApplicationDeployTest.java b/config-model/src/test/java/com/yahoo/config/model/ApplicationDeployTest.java index ec9d631dec5..8a8b23bb0c8 100644 --- a/config-model/src/test/java/com/yahoo/config/model/ApplicationDeployTest.java +++ b/config-model/src/test/java/com/yahoo/config/model/ApplicationDeployTest.java @@ -10,6 +10,7 @@ import com.yahoo.config.model.application.provider.Bundle; import com.yahoo.config.model.application.provider.DeployData; import com.yahoo.config.model.application.provider.FilesApplicationPackage; import com.yahoo.config.model.deploy.DeployState; +import com.yahoo.config.provision.ApplicationId; import com.yahoo.path.Path; import com.yahoo.document.DataType; import com.yahoo.document.config.DocumentmanagerConfig; @@ -33,19 +34,17 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.regex.Pattern; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.Matchers.contains; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -60,7 +59,6 @@ public class ApplicationDeployTest { @Test public void testVespaModel() throws SAXException, IOException { ApplicationPackageTester tester = ApplicationPackageTester.create(TESTDIR + "app1"); - assertThat(tester.app().getApplicationName(), is("app1")); VespaModel model = new VespaModel(tester.app()); List<SearchDefinition> searchDefinitions = tester.getSearchDefinitions(); assertEquals(searchDefinitions.size(), 5); @@ -92,8 +90,7 @@ public class ApplicationDeployTest { List<FilesApplicationPackage.Component> components = tester.app().getComponents(); assertEquals(1, components.size()); - Map<String, Bundle.DefEntry> defEntriesByName = - defEntries2map(components.get(0).getDefEntries()); + Map<String, Bundle.DefEntry> defEntriesByName = defEntries2map(components.get(0).getDefEntries()); assertEquals(5, defEntriesByName.size()); Bundle.DefEntry def1 = defEntriesByName.get("test-namespace"); @@ -106,15 +103,14 @@ public class ApplicationDeployTest { // Check that getFilename works ArrayList<String> sdFileNames = new ArrayList<>(); - for (SearchDefinition sd : searchDefinitions) { + for (SearchDefinition sd : searchDefinitions) sdFileNames.add(sd.getFilename()); - } Collections.sort(sdFileNames); - assertThat(sdFileNames.get(0), is("laptop.sd")); - assertThat(sdFileNames.get(1), is("music.sd")); - assertThat(sdFileNames.get(2), is("pc.sd")); - assertThat(sdFileNames.get(3), is("product.sd")); - assertThat(sdFileNames.get(4), is("sock.sd")); + assertEquals("laptop.sd", sdFileNames.get(0)); + assertEquals("music.sd", sdFileNames.get(1)); + assertEquals("pc.sd", sdFileNames.get(2)); + assertEquals("product.sd", sdFileNames.get(3)); + assertEquals("sock.sd", sdFileNames.get(4)); } @Test @@ -146,10 +142,8 @@ public class ApplicationDeployTest { String appDir = "src/test/cfg/application/app_sdbundles"; ApplicationPackageTester tester = ApplicationPackageTester.create(appDir); VespaModel model = new VespaModel(tester.app()); - // Check that the resulting documentmanager config contains those types DocumentmanagerConfig.Builder b = new DocumentmanagerConfig.Builder(); model.getConfig(b, VespaModel.ROOT_CONFIGID); - //String docMan = model.getConfig("documentmanager", "").toString(); DocumentmanagerConfig dc = b.build(); String docMan=ConfigInstance.serialize(dc).toString(); int pFlags = Pattern.MULTILINE + Pattern.DOTALL; @@ -169,8 +163,8 @@ public class ApplicationDeployTest { public void include_dirs_are_included() { ApplicationPackageTester tester = ApplicationPackageTester.create(TESTDIR + "include_dirs"); - List<String> includeDirs = tester.app().getUserIncludeDirs(); - assertThat(includeDirs, contains("jdisc_dir", "dir1", "dir2", "empty_dir")); + Set<String> includeDirs = new HashSet<>(tester.app().getUserIncludeDirs()); + assertEquals(Set.of("jdisc_dir", "dir1", "dir2", "empty_dir"), includeDirs); } @Test @@ -186,7 +180,8 @@ public class ApplicationDeployTest { FilesApplicationPackage.fromFile(appDir); fail("Expected exception due to non-existent include dir"); } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), containsString("Cannot include directory 'non-existent', as it does not exist")); + assertEquals("Cannot include directory 'non-existent', as it does not exist. Directory must reside in application package, and path must be given relative to application package.", + e.getMessage()); } } @@ -231,7 +226,7 @@ public class ApplicationDeployTest { ApplicationPackageTester.create(tmpDir.getAbsolutePath()); fail("Expected exception"); } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), containsString("element \"delay\" not allowed here")); + assertEquals("XML error in deployment.xml: element \"delay\" not allowed here; expected the element end-tag or element \"region\" [8:25], input:\n", e.getMessage()); } } @@ -264,28 +259,36 @@ public class ApplicationDeployTest { File tmp = Files.createTempDir(); String appPkg = TESTDIR + "app1"; IOUtils.copyDirectory(new File(appPkg), tmp); - DeployData deployData = new DeployData("foo", "bar", "baz", 13l, false, 1337l, 3l); + ApplicationId applicationId = ApplicationId.from("tenant1", "application1", "instance1"); + DeployData deployData = new DeployData("foo", + "bar", + applicationId, + 13L, + false, + 1337L, + 3L); FilesApplicationPackage app = FilesApplicationPackage.fromFileWithDeployData(tmp, deployData); app.writeMetaData(); FilesApplicationPackage newApp = FilesApplicationPackage.fromFileWithDeployData(tmp, deployData); ApplicationMetaData meta = newApp.getMetaData(); - assertThat(meta.getDeployedByUser(), is("foo")); - assertThat(meta.getDeployPath(), is("bar")); - assertThat(meta.getDeployTimestamp(), is(13L)); - assertThat(meta.getGeneration(), is(1337L)); - assertThat(meta.getPreviousActiveGeneration(), is(3L)); - String checkSum = meta.getCheckSum(); - assertNotNull(checkSum); + assertEquals("foo", meta.getDeployedByUser()); + assertEquals("bar", meta.getDeployPath()); + assertEquals(applicationId, meta.getApplicationId()); + assertEquals(13L, (long)meta.getDeployTimestamp()); + assertEquals(1337L, (long)meta.getGeneration()); + assertEquals(3L, meta.getPreviousActiveGeneration()); + String checksum = meta.getChecksum(); + assertNotNull(checksum); assertTrue((new File(tmp, "hosts.xml")).delete()); FilesApplicationPackage app2 = FilesApplicationPackage.fromFileWithDeployData(tmp, deployData); - String app2CheckSum = app2.getMetaData().getCheckSum(); - assertThat(app2CheckSum, is(not(checkSum))); + String app2Checksum = app2.getMetaData().getChecksum(); + assertNotEquals(checksum, app2Checksum); assertTrue((new File(tmp, "files/foo.json")).delete()); FilesApplicationPackage app3 = FilesApplicationPackage.fromFileWithDeployData(tmp, deployData); - String app3CheckSum = app3.getMetaData().getCheckSum(); - assertThat(app3CheckSum, is(not(app2CheckSum))); + String app3Checksum = app3.getMetaData().getChecksum(); + assertNotEquals(app2Checksum, app3Checksum); } @Test @@ -322,7 +325,8 @@ public class ApplicationDeployTest { FilesApplicationPackage.getComponents(new File("src/test/cfg/application/validation/invalidjar_app")); fail(); } catch (IllegalArgumentException e) { - assertThat(e.getMessage(), is("Error opening jar file 'invalid.jar'. Please check that this is a valid jar file")); + assertEquals("Error opening jar file 'invalid.jar'. Please check that this is a valid jar file", + e.getMessage()); } } @@ -340,15 +344,15 @@ public class ApplicationDeployTest { DeployState deployState = new DeployState.Builder().applicationPackage(app).build(); ConfigDefinition def = deployState.getConfigDefinition(new ConfigDefinitionKey("baz", "xyzzy")).get(); - assertThat(def.getNamespace(), is("xyzzy")); + assertEquals("xyzzy", def.getNamespace()); def = deployState.getConfigDefinition(new ConfigDefinitionKey("foo", "qux")).get(); - assertThat(def.getNamespace(), is("qux")); + assertEquals("qux", def.getNamespace()); // A config def without version in filename and version in file header def = deployState.getConfigDefinition(new ConfigDefinitionKey("bar", "xyzzy")).get(); - assertThat(def.getNamespace(), is("xyzzy")); - assertThat(def.getName(), is("bar")); + assertEquals("xyzzy", def.getNamespace()); + assertEquals("bar", def.getName()); } @Test(expected=IllegalArgumentException.class) diff --git a/config-model/src/test/java/com/yahoo/config/model/ApplicationPackageTester.java b/config-model/src/test/java/com/yahoo/config/model/ApplicationPackageTester.java index ab321ac5835..87b6efa83d6 100644 --- a/config-model/src/test/java/com/yahoo/config/model/ApplicationPackageTester.java +++ b/config-model/src/test/java/com/yahoo/config/model/ApplicationPackageTester.java @@ -33,8 +33,7 @@ public class ApplicationPackageTester { this.applicationPackage = applicationPackage; } catch (IOException e) { - throw new IllegalArgumentException("Could not create an application package from '" + - applicationPackageDir + "'", e); + throw new IllegalArgumentException("Could not create an application package from '" + applicationPackageDir + "'", e); } } diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionFactoryImpl.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionFactoryImpl.java index fad5685d6fa..cb1f6519f57 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionFactoryImpl.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionFactoryImpl.java @@ -87,7 +87,7 @@ public class SessionFactoryImpl implements SessionFactory, LocalSessionLoader { private ApplicationPackage createApplication(File userDir, File configApplicationDir, - String applicationName, + ApplicationId applicationId, long sessionId, long currentlyActiveSessionId, boolean internalRedeploy) { @@ -96,7 +96,7 @@ public class SessionFactoryImpl implements SessionFactory, LocalSessionLoader { if (user == null) { user = "unknown"; } - DeployData deployData = new DeployData(user, userDir.getAbsolutePath(), applicationName, deployTimestamp, internalRedeploy, sessionId, currentlyActiveSessionId); + DeployData deployData = new DeployData(user, userDir.getAbsolutePath(), applicationId, deployTimestamp, internalRedeploy, sessionId, currentlyActiveSessionId); return FilesApplicationPackage.fromFileWithDeployData(configApplicationDir, deployData); } @@ -150,7 +150,7 @@ public class SessionFactoryImpl implements SessionFactory, LocalSessionLoader { IOUtils.copyDirectory(applicationFile, userApplicationDir); ApplicationPackage applicationPackage = createApplication(applicationFile, userApplicationDir, - applicationId.application().value(), + applicationId, sessionId, currentlyActiveSessionId, internalRedeploy); diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackage.java b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackage.java index 786b26318a3..3af0df53cba 100644 --- a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackage.java +++ b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackage.java @@ -117,7 +117,7 @@ public class ZKApplicationPackage implements ApplicationPackage { @Override public String getApplicationName() { - return metaData.getApplicationName(); + return metaData.getApplicationId().application().value(); } @Override diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java index 589c3fcba6a..25ddddbdf11 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ApplicationRepositoryTest.java @@ -132,10 +132,10 @@ public class ApplicationRepositoryTest { ApplicationMetaData applicationMetaData = getApplicationMetaData(applicationId(), sessionId); assertNotEquals(sessionId, originalSessionId); - assertEquals(applicationMetaData.getApplicationName(), originalApplicationMetaData.getApplicationName()); - assertEquals(applicationMetaData.getPreviousActiveGeneration(), originalApplicationMetaData.getGeneration().longValue()); - assertNotEquals(applicationMetaData.getGeneration(), originalApplicationMetaData.getGeneration()); - assertEquals(applicationMetaData.getDeployedByUser(), originalApplicationMetaData.getDeployedByUser()); + assertEquals(originalApplicationMetaData.getApplicationId(), applicationMetaData.getApplicationId()); + assertEquals(originalApplicationMetaData.getPreviousActiveGeneration(), applicationMetaData.getGeneration().longValue()); + assertNotEquals(originalApplicationMetaData.getGeneration(), applicationMetaData.getGeneration()); + assertEquals(originalApplicationMetaData.getDeployedByUser(), applicationMetaData.getDeployedByUser()); } @Test diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClientTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClientTest.java index d01ebad8c26..14fa0cb2dbe 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClientTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClientTest.java @@ -11,6 +11,7 @@ import com.yahoo.config.model.application.provider.DeployData; import com.yahoo.config.model.application.provider.FilesApplicationPackage; import com.yahoo.config.model.application.provider.MockFileRegistry; import com.yahoo.config.provision.AllocatedHosts; +import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.HostSpec; import com.yahoo.path.Path; import com.yahoo.vespa.config.server.zookeeper.ConfigCurator; @@ -56,7 +57,7 @@ public class ZooKeeperClientTest { ApplicationPackage app = FilesApplicationPackage.fromFileWithDeployData(new File("src/test/apps/zkfeed"), new DeployData("foo", "/bar/baz", - "appName", + ApplicationId.from("default", "appName", "default"), 1345L, true, 3L, @@ -135,8 +136,7 @@ public class ZooKeeperClientTest { public void testFeedAppMetaDataToZooKeeper() { assertTrue(zk.exists(appPath, ConfigCurator.META_ZK_PATH)); ApplicationMetaData metaData = ApplicationMetaData.fromJsonString(zk.getData(appPath, ConfigCurator.META_ZK_PATH)); - assertThat(metaData.getApplicationName(), is("appName")); - assertTrue(metaData.getCheckSum().length() > 0); + assertTrue(metaData.getChecksum().length() > 0); assertTrue(metaData.isInternalRedeploy()); assertThat(metaData.getDeployedByUser(), is("foo")); assertThat(metaData.getDeployPath(), is("/bar/baz")); diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandlerTest.java index 0982fad2bcb..6ba3c33d37b 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandlerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/http/v2/SessionActiveHandlerTest.java @@ -218,7 +218,7 @@ public class SessionActiveHandlerTest extends SessionHandlerTest { } private void addLocalSession(long sessionId, DeployData deployData, SessionZooKeeperClient zkc) throws IOException { - writeApplicationId(zkc, deployData.getApplicationName()); + writeApplicationId(zkc, deployData.getApplicationId()); TenantFileSystemDirs tenantFileSystemDirs = new TenantFileSystemDirs(temporaryFolder.newFolder(), tenantName); ApplicationPackage app = FilesApplicationPackage.fromFileWithDeployData(testApp, deployData); localRepo.addSession(new LocalSession(tenantName, sessionId, new SessionTest.MockSessionPreparer(), @@ -278,7 +278,7 @@ public class SessionActiveHandlerTest extends SessionHandlerTest { this.initialStatus = initialStatus; this.deployData = new DeployData("foo", "bar", - appName, + ApplicationId.from(tenantName.value(), appName, "default"), 0L, false, sessionId, @@ -312,9 +312,7 @@ public class SessionActiveHandlerTest extends SessionHandlerTest { Optional.of(AllocatedHosts.withHosts(Collections.singleton(new HostSpec("bar", Collections.emptyList()))))); session = createRemoteSession(sessionId, initialStatus, zkClient); addLocalSession(sessionId, deployData, zkClient); - tenantRepository.getTenant(tenantName).getApplicationRepo().createApplication(ApplicationId.from(tenantName.value(), - deployData.getApplicationName(), - InstanceName.defaultName().value())); + tenantRepository.getTenant(tenantName).getApplicationRepo().createApplication(deployData.getApplicationId()); metaData = localRepo.getSession(sessionId).getMetaData(); actResponse = handler.handle(SessionHandlerTest.createTestRequest(pathPrefix, HttpRequest.Method.PUT, Cmd.ACTIVE, sessionId, subPath)); return this; @@ -349,8 +347,7 @@ public class SessionActiveHandlerTest extends SessionHandlerTest { assertFalse(hostProvisioner.activated); } - private void writeApplicationId(SessionZooKeeperClient zkc, String applicationName) { - ApplicationId id = ApplicationId.from(tenantName, ApplicationName.from(applicationName), InstanceName.defaultName()); + private void writeApplicationId(SessionZooKeeperClient zkc, ApplicationId id) { zkc.writeApplicationId(id); } diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandlerTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandlerTest.java index ff3d9449448..8b9028fee4a 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandlerTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/tenant/TenantRequestHandlerTest.java @@ -107,7 +107,7 @@ public class TenantRequestHandlerTest { ZooKeeperDeployer deployer = zkc.createDeployer(new BaseDeployLogger()); DeployData deployData = new DeployData("user", appDir.toString(), - appId.application().toString(), + appId, 0L, internalRedeploy, 0L, |