summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjørn Christian Seime <bjorncs@verizonmedia.com>2022-01-18 16:53:19 +0100
committerGitHub <noreply@github.com>2022-01-18 16:53:19 +0100
commit8ca62417e9c3b1bb2887226054069fb4c346c835 (patch)
treec723ea4908c718716bb4533b572834fb1a0a965a
parent305dd6ca6dd90d8cf1a1f51c6d8575d5f2b3ee67 (diff)
parent5baecf63ad51430f4458f6594822ed3143dc99d0 (diff)
Merge pull request #20860 from vespa-engine/bjorncs/validate-pom-repositories
Bjorncs/validate pom repositories
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/BundleValidator.java82
-rw-r--r--config-model/src/test/cfg/application/validation/testjars/pom-xml-warnings/META-INF/maven/com.yahoo.test/mybundle/pom.xml13
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/BundleValidatorTest.java23
3 files changed, 86 insertions, 32 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/BundleValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/BundleValidator.java
index 87a84911d3e..fe5ffb4e544 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/BundleValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/BundleValidator.java
@@ -18,6 +18,7 @@ import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.IOException;
import java.io.StringReader;
@@ -31,6 +32,7 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
@@ -58,7 +60,7 @@ public class BundleValidator extends Validator {
DeployLogger deployLogger = deployState.getDeployLogger();
deployLogger.log(Level.FINE, String.format("Validating bundle at '%s'", path));
JarFile jarFile = new JarFile(app.getFileReference(path));
- validateJarFile(deployLogger, jarFile);
+ validateJarFile(deployLogger, deployState.isHosted(), jarFile);
} catch (IOException e) {
throw new IllegalArgumentException(
"Failed to validate JAR file '" + path.last() + "'", e);
@@ -66,7 +68,7 @@ public class BundleValidator extends Validator {
}
}
- void validateJarFile(DeployLogger deployLogger, JarFile jarFile) throws IOException {
+ void validateJarFile(DeployLogger deployLogger, boolean isHosted, JarFile jarFile) throws IOException {
Manifest manifest = jarFile.getManifest();
String filename = Paths.get(jarFile.getName()).getFileName().toString();
if (manifest == null) {
@@ -74,7 +76,7 @@ public class BundleValidator extends Validator {
}
validateManifest(deployLogger, filename, manifest);
getPomXmlContent(deployLogger, jarFile)
- .ifPresent(pomXml -> validatePomXml(deployLogger, filename, pomXml));
+ .ifPresent(pomXml -> validatePomXml(deployLogger, isHosted, filename, pomXml));
}
private void validateManifest(DeployLogger deployLogger, String filename, Manifest mf) {
@@ -150,30 +152,60 @@ public class BundleValidator extends Validator {
});
}
- private void validatePomXml(DeployLogger deployLogger, String jarFilename, String pomXmlContent) {
- try {
- Document pom = DocumentBuilderFactory.newDefaultInstance().newDocumentBuilder()
- .parse(new InputSource(new StringReader(pomXmlContent)));
- NodeList dependencies = (NodeList) XPathFactory.newDefaultInstance().newXPath()
- .compile("/project/dependencies/dependency")
- .evaluate(pom, XPathConstants.NODESET);
- for (int i = 0; i < dependencies.getLength(); i++) {
- Element dependency = (Element) dependencies.item(i);
- String groupId = dependency.getElementsByTagName("groupId").item(0).getTextContent();
- String artifactId = dependency.getElementsByTagName("artifactId").item(0).getTextContent();
- for (DeprecatedMavenArtifact deprecatedArtifact : DeprecatedMavenArtifact.values()) {
- if (groupId.equals(deprecatedArtifact.groupId) && artifactId.equals(deprecatedArtifact.artifactId)) {
- deployLogger.logApplicationPackage(Level.WARNING,
- String.format(
- "The pom.xml of bundle '%s' includes a dependency to the artifact '%s:%s'. \n%s",
- jarFilename, groupId, artifactId, deprecatedArtifact.description));
- }
+ private void validatePomXml(DeployLogger deployLogger, boolean isHosted, String jarFilename, String pomXmlContent) {
+ if (isHosted) {
+ try {
+ Document pom = DocumentBuilderFactory.newDefaultInstance().newDocumentBuilder()
+ .parse(new InputSource(new StringReader(pomXmlContent)));
+ validateDependencies(deployLogger, jarFilename, pom);
+ validateRepositories(deployLogger, jarFilename, pom);
+ } catch (ParserConfigurationException e) {
+ throw new RuntimeException(e);
+ } catch (Exception e) {
+ deployLogger.log(Level.INFO, String.format("Unable to parse pom.xml from %s", jarFilename));
+ }
+ }
+ }
+
+ private static void validateDependencies(DeployLogger deployLogger, String jarFilename, Document pom) throws XPathExpressionException {
+ forEachPomXmlElement(pom, "dependencies/dependency", dependency -> {
+ String groupId = dependency.getElementsByTagName("groupId").item(0).getTextContent();
+ String artifactId = dependency.getElementsByTagName("artifactId").item(0).getTextContent();
+ for (DeprecatedMavenArtifact deprecatedArtifact : DeprecatedMavenArtifact.values()) {
+ if (groupId.equals(deprecatedArtifact.groupId) && artifactId.equals(deprecatedArtifact.artifactId)) {
+ deployLogger.logApplicationPackage(Level.WARNING,
+ String.format(
+ "The pom.xml of bundle '%s' includes a dependency to the artifact '%s:%s'. \n%s",
+ jarFilename, groupId, artifactId, deprecatedArtifact.description));
}
}
- } catch (ParserConfigurationException e) {
- throw new RuntimeException(e);
- } catch (Exception e) {
- deployLogger.log(Level.INFO, String.format("Unable to parse pom.xml from %s", jarFilename));
+ });
+ }
+
+ private static void validateRepositories(DeployLogger deployLogger, String jarFilename, Document pom) throws XPathExpressionException {
+ forEachPomXmlElement(pom, "pluginRepositories/pluginRepository",
+ repository -> validateRepository(deployLogger, jarFilename, "pluginRepositories", repository));
+ forEachPomXmlElement(pom, "repositories/repository",
+ repository -> validateRepository(deployLogger, jarFilename, "repositories", repository));
+ }
+
+ private static void validateRepository(DeployLogger deployLogger, String jarFilename, String parentElementName,
+ Element element) {
+ String url = element.getElementsByTagName("url").item(0).getTextContent();
+ if (url.contains("vespa-maven-libs-release-local")) {
+ deployLogger.logApplicationPackage(Level.WARNING,
+ String.format("<%s> in pom.xml of '%s' uses deprecated Maven repository '%s'.\n See announcement.",
+ parentElementName, jarFilename, url));
+ }
+ }
+
+ private static void forEachPomXmlElement(Document pom, String xpath, Consumer<Element> consumer) throws XPathExpressionException {
+ NodeList dependencies = (NodeList) XPathFactory.newDefaultInstance().newXPath()
+ .compile("/project/" + xpath)
+ .evaluate(pom, XPathConstants.NODESET);
+ for (int i = 0; i < dependencies.getLength(); i++) {
+ Element element = (Element) dependencies.item(i);
+ consumer.accept(element);
}
}
diff --git a/config-model/src/test/cfg/application/validation/testjars/pom-xml-warnings/META-INF/maven/com.yahoo.test/mybundle/pom.xml b/config-model/src/test/cfg/application/validation/testjars/pom-xml-warnings/META-INF/maven/com.yahoo.test/mybundle/pom.xml
index 1d28f307824..167751f55c4 100644
--- a/config-model/src/test/cfg/application/validation/testjars/pom-xml-warnings/META-INF/maven/com.yahoo.test/mybundle/pom.xml
+++ b/config-model/src/test/cfg/application/validation/testjars/pom-xml-warnings/META-INF/maven/com.yahoo.test/mybundle/pom.xml
@@ -12,4 +12,17 @@
<scope>test</scope>
</dependency>
</dependencies>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>my-plugin-repository</id>
+ <url>http://myartifactory:8000/artifactory/vespa-maven-libs-release-local</url>
+ </pluginRepository>
+ </pluginRepositories>
+ <repositories>
+ <repository>
+ <id>my-repository</id>
+ <url>http://myartifactory:8000/artifactory/vespa-maven-libs-release-local</url>
+ </repository>
+ </repositories>
</project> \ No newline at end of file
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/BundleValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/BundleValidatorTest.java
index ef4353d02fb..eeae7dfe0ee 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/BundleValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/BundleValidatorTest.java
@@ -29,7 +29,7 @@ public class BundleValidatorTest {
// Valid jar file
JarFile ok = createTemporaryJarFile("ok");
BundleValidator bundleValidator = new BundleValidator();
- bundleValidator.validateJarFile(new BaseDeployLogger(), ok);
+ bundleValidator.validateJarFile(new BaseDeployLogger(), false, ok);
// No manifest
validateWithException("nomanifest", "Non-existing or invalid manifest in nomanifest.jar");
@@ -39,7 +39,7 @@ public class BundleValidatorTest {
try {
JarFile jarFile = createTemporaryJarFile(jarName);
BundleValidator bundleValidator = new BundleValidator();
- bundleValidator.validateJarFile(new BaseDeployLogger(), jarFile);
+ bundleValidator.validateJarFile(new BaseDeployLogger(), false, jarFile);
assert (false);
} catch (IllegalArgumentException e) {
assertEquals(e.getMessage(), exceptionMessage);
@@ -52,7 +52,7 @@ public class BundleValidatorTest {
DeployLogger logger = createDeployLogger(buffer);
JarFile jarFile = createTemporaryJarFile("snapshot_bundle");
- new BundleValidator().validateJarFile(logger, jarFile);
+ new BundleValidator().validateJarFile(logger, false, jarFile);
assertTrue(buffer.toString().contains("Deploying snapshot bundle"));
}
@@ -62,7 +62,7 @@ public class BundleValidatorTest {
DeployLogger logger = createDeployLogger(buffer);
BundleValidator validator = new BundleValidator();
JarFile jarFile = createTemporaryJarFile("import-warnings");
- validator.validateJarFile(logger, jarFile);
+ validator.validateJarFile(logger, true, jarFile);
assertThat(buffer.toString())
.contains("For JAR file 'import-warnings.jar': \n" +
"Manifest imports the following Java packages from 'org.json:json': [org.json]. \n" +
@@ -70,18 +70,27 @@ public class BundleValidatorTest {
}
@Test
- public void outputs_deploy_warning_on_deprecated_dependency() throws IOException {
+ public void outputs_deploy_warnings_for_pom_xml() throws IOException {
StringBuffer buffer = new StringBuffer();
DeployLogger logger = createDeployLogger(buffer);
BundleValidator validator = new BundleValidator();
JarFile jarFile = createTemporaryJarFile("pom-xml-warnings");
- validator.validateJarFile(logger, jarFile);
- assertThat(buffer.toString())
+ validator.validateJarFile(logger, true, jarFile);
+ String output = buffer.toString();
+ assertThat(output)
.contains("The pom.xml of bundle 'pom-xml-warnings.jar' includes a dependency to the artifact " +
"'com.yahoo.vespa:vespa-http-client-extensions'. \n" +
"This artifact will be removed in Vespa 8. " +
"Programmatic use can be safely removed from system/staging tests. " +
"See internal Vespa 8 release notes for details.\n");
+ assertThat(output)
+ .contains("\n" +
+ "<pluginRepositories> in pom.xml of 'pom-xml-warnings.jar' uses deprecated Maven repository " +
+ "'http://myartifactory:8000/artifactory/vespa-maven-libs-release-local'.\n See announcement.");
+ assertThat(output)
+ .contains("\n" +
+ "<repositories> in pom.xml of 'pom-xml-warnings.jar' uses deprecated Maven repository " +
+ "'http://myartifactory:8000/artifactory/vespa-maven-libs-release-local'.\n See announcement.");
}
private JarFile createTemporaryJarFile(String testArtifact) throws IOException {