summaryrefslogtreecommitdiffstats
path: root/config-application-package
diff options
context:
space:
mode:
authorHarald Musum <musum@oath.com>2017-08-28 15:27:01 +0200
committerHarald Musum <musum@oath.com>2017-08-28 15:27:01 +0200
commit6450f3fbf69d22b123a3ff26702364c8046f7240 (patch)
tree9aa527d900ef19c0332b146c273a941cfaffaa07 /config-application-package
parent2b7452bda4e045b1c145c82dde0d6cdda778051d (diff)
Refactor schema validation setup
* Try to avoid hardcoding and having to specify version several times * Make sure to only copy schema files once
Diffstat (limited to 'config-application-package')
-rw-r--r--config-application-package/src/main/java/com/yahoo/config/model/application/provider/ApplicationPackageXmlFilesValidator.java40
-rw-r--r--config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java2
-rw-r--r--config-application-package/src/main/java/com/yahoo/config/model/application/provider/SchemaValidator.java219
-rw-r--r--config-application-package/src/main/java/com/yahoo/config/model/application/provider/SchemaValidators.java195
-rw-r--r--config-application-package/src/main/java/com/yahoo/config/model/application/provider/SimpleApplicationValidator.java2
5 files changed, 251 insertions, 207 deletions
diff --git a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/ApplicationPackageXmlFilesValidator.java b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/ApplicationPackageXmlFilesValidator.java
index 29002d8a685..b4d65ce6d0e 100644
--- a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/ApplicationPackageXmlFilesValidator.java
+++ b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/ApplicationPackageXmlFilesValidator.java
@@ -11,7 +11,6 @@ import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.List;
-import java.util.Optional;
/**
* Validation of xml files in application package against RELAX NG schemas.
@@ -22,15 +21,14 @@ public class ApplicationPackageXmlFilesValidator {
private final AppSubDirs appDirs;
- /** The Vespa version this package should be validated against */
- private final Version vespaVersion;
+ private final SchemaValidators validators;
private static final FilenameFilter xmlFilter = (dir, name) -> name.endsWith(".xml");
public ApplicationPackageXmlFilesValidator(AppSubDirs appDirs, Version vespaVersion) {
this.appDirs = appDirs;
- this.vespaVersion = vespaVersion;
+ this.validators = new SchemaValidators(vespaVersion, new BaseDeployLogger());
}
public static ApplicationPackageXmlFilesValidator createDefaultXMLValidator(File appDir, Version vespaVersion) {
@@ -43,10 +41,10 @@ public class ApplicationPackageXmlFilesValidator {
@SuppressWarnings("deprecation")
public void checkApplication() throws IOException {
- validate(SchemaValidator.servicesXmlSchemaName, servicesFileName());
- validateOptional(SchemaValidator.hostsXmlSchemaName, FilesApplicationPackage.HOSTS);
- validateOptional(SchemaValidator.deploymentXmlSchemaName, FilesApplicationPackage.DEPLOYMENT_FILE.getName());
- validateOptional(SchemaValidator.validationOverridesXmlSchemaName, FilesApplicationPackage.VALIDATION_OVERRIDES.getName());
+ validate(validators.servicesXmlValidator(), servicesFileName());
+ validateOptional(validators.hostsXmlValidator(), FilesApplicationPackage.HOSTS);
+ validateOptional(validators.deploymentXmlValidator(), FilesApplicationPackage.DEPLOYMENT_FILE.getName());
+ validateOptional(validators.validationOverridesXmlValidator(), FilesApplicationPackage.VALIDATION_OVERRIDES.getName());
if (appDirs.searchdefinitions().exists()) {
if (FilesApplicationPackage.getSearchDefinitionFiles(appDirs.root()).isEmpty()) {
@@ -55,26 +53,26 @@ public class ApplicationPackageXmlFilesValidator {
}
}
- validate(appDirs.routingtables, "routing-standalone.rnc");
+ validateRouting(appDirs.routingtables);
}
// For testing
- public static void checkIncludedDirs(ApplicationPackage app, Version vespaVersion) throws IOException {
+ public void checkIncludedDirs(ApplicationPackage app) throws IOException {
for (String includedDir : app.getUserIncludeDirs()) {
List<NamedReader> includedFiles = app.getFiles(Path.fromString(includedDir), ".xml", true);
for (NamedReader file : includedFiles) {
- createSchemaValidator("container-include.rnc", vespaVersion).validate(file);
+ validators.containerIncludeXmlValidator().validate(file);
}
}
}
- private void validateOptional(String schema, String file) throws IOException {
+ private void validateOptional(SchemaValidator validator, String file) throws IOException {
if ( ! appDirs.file(file).exists()) return;
- validate(schema, file);
+ validate(validator, file);
}
- private void validate(String schema, String file) throws IOException {
- createSchemaValidator(schema, vespaVersion).validate(appDirs.file(file));
+ private void validate(SchemaValidator validator, String filename) throws IOException {
+ validator.validate(appDirs.file(filename));
}
@SuppressWarnings("deprecation")
@@ -87,26 +85,22 @@ public class ApplicationPackageXmlFilesValidator {
return servicesFile;
}
- private void validate(Tuple2<File, String> directory, String schemaFile) throws IOException {
+ private void validateRouting(Tuple2<File, String> directory) throws IOException {
if ( ! directory.first.isDirectory()) return;
- validate(directory, createSchemaValidator(schemaFile, vespaVersion));
+ validateRouting(validators.routingStandaloneXmlValidator(), directory);
}
- private void validate(Tuple2<File, String> directory, SchemaValidator validator) throws IOException {
+ private void validateRouting(SchemaValidator validator, Tuple2<File, String> directory) throws IOException {
File dir = directory.first;
if ( ! dir.isDirectory()) return;
String directoryName = directory.second;
for (File f : dir.listFiles(xmlFilter)) {
if (f.isDirectory())
- validate(new Tuple2<>(f, directoryName + File.separator + f.getName()),validator);
+ validateRouting(validator, new Tuple2<>(f, directoryName + File.separator + f.getName()));
else
validator.validate(f, directoryName + File.separator + f.getName());
}
}
- private static SchemaValidator createSchemaValidator(String schemaFile, Version vespaVersion) {
- return new SchemaValidator(schemaFile, new BaseDeployLogger(), vespaVersion);
- }
-
}
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 8b8921f50a1..22b8e841430 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
@@ -634,7 +634,7 @@ public class FilesApplicationPackage implements ApplicationPackage {
com.yahoo.component.Version modelVersion = vespaVersion.map(v -> new com.yahoo.component.Version(vespaVersion.toString())).orElse(Vtag.currentVersion);
ApplicationPackageXmlFilesValidator xmlFilesValidator = ApplicationPackageXmlFilesValidator.createDefaultXMLValidator(appDir, modelVersion);
xmlFilesValidator.checkApplication();
- ApplicationPackageXmlFilesValidator.checkIncludedDirs(this, modelVersion);
+ xmlFilesValidator.checkIncludedDirs(this);
}
@Override
diff --git a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/SchemaValidator.java b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/SchemaValidator.java
index 70da2f2e92e..d0cca38b375 100644
--- a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/SchemaValidator.java
+++ b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/SchemaValidator.java
@@ -6,214 +6,40 @@ import com.thaiopensource.util.PropertyMapBuilder;
import com.thaiopensource.validate.ValidateProperty;
import com.thaiopensource.validate.ValidationDriver;
import com.thaiopensource.validate.rng.CompactSchemaReader;
-import com.yahoo.component.Version;
import com.yahoo.config.application.api.DeployLogger;
-import com.yahoo.io.IOUtils;
import com.yahoo.io.reader.NamedReader;
-import com.yahoo.log.LogLevel;
-import static com.yahoo.vespa.defaults.Defaults.getDefaults;
import com.yahoo.yolean.Exceptions;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.FrameworkUtil;
import org.xml.sax.ErrorHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
+
import java.io.File;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.Reader;
-import java.net.JarURLConnection;
-import java.net.URL;
-import java.util.Enumeration;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
import java.util.logging.Level;
-import java.util.logging.Logger;
/**
- * Validates xml files against one schema.
+ * Validates xml files against a schema.
*
* @author tonytv
*/
public class SchemaValidator {
- public static final String schemaDirBase = System.getProperty("java.io.tmpdir", File.separator + "tmp" + File.separator + "vespa");
- static final String servicesXmlSchemaName = "services.rnc";
- static final String hostsXmlSchemaName = "hosts.rnc";
- static final String deploymentXmlSchemaName = "deployment.rnc";
- static final String validationOverridesXmlSchemaName = "validation-overrides.rnc";
private final CustomErrorHandler errorHandler = new CustomErrorHandler();
private final ValidationDriver driver;
- private DeployLogger deployLogger;
- private static final Logger log = Logger.getLogger(SchemaValidator.class.getName());
-
- /**
- * Initializes the validator by using the given file as schema file
- * @param schema a schema file in RNC format
- * @param logger a logger
- * @param vespaVersion the version of Vespa we should validate against
- */
- public SchemaValidator(String schema, DeployLogger logger, Version vespaVersion) {
- this.deployLogger = logger;
- driver = new ValidationDriver(PropertyMap.EMPTY, instanceProperties(), CompactSchemaReader.getInstance());
- File schemaDir = new File(schemaDirBase);
- try {
- schemaDir = saveSchemasFromJar(new File(SchemaValidator.schemaDirBase), vespaVersion);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- loadSchema(new File(schemaDir + File.separator + "schema" + File.separator + schema));
- IOUtils.recursiveDeleteDir(schemaDir);
- }
+ private final DeployLogger deployLogger;
/**
* Initializes the validator by using the given file as schema file
- * @param schema a schema file in RNC format
- * @param vespaVersion the version we should validate against
- * @throws IOException if it is not possible to read schema files
- */
- public SchemaValidator(String schema, Version vespaVersion) throws IOException {
- this(schema, new BaseDeployLogger(), vespaVersion);
- }
-
- /**
- * Create a validator for services.xml for tests
- * @throws IOException if it is not possible to read schema files
- */
- public static SchemaValidator createTestValidatorServices(Version vespaVersion) throws IOException {
- return new SchemaValidator(servicesXmlSchemaName, vespaVersion);
- }
-
- /**
- * Create a validator for hosts.xml for tests
- * @throws IOException if it is not possible to read schema files
- */
- public static SchemaValidator createTestValidatorHosts(Version vespaVersion) throws IOException {
- return new SchemaValidator(hostsXmlSchemaName, vespaVersion);
- }
-
- /**
- * Create a validator for deployment.xml for tests
*
+ * @param schemaFile schema file
* @throws IOException if it is not possible to read schema files
*/
- public static SchemaValidator createTestValidatorDeployment(Version vespaVersion) throws IOException {
- return new SchemaValidator(deploymentXmlSchemaName, vespaVersion);
- }
-
- private class CustomErrorHandler implements ErrorHandler {
- volatile String fileName;
-
- public void warning(SAXParseException e) throws SAXException {
- deployLogger.log(Level.WARNING, message(e));
- }
-
- public void error(SAXParseException e) throws SAXException {
- throw new IllegalArgumentException(message(e));
- }
-
- public void fatalError(SAXParseException e) throws SAXException {
- throw new IllegalArgumentException(message(e));
- }
-
- private String message(SAXParseException e) {
- return "XML error in " + fileName + ": " +
- Exceptions.toMessageString(e)
- + " [" + e.getLineNumber() + ":" + e.getColumnNumber() + "]";
- }
- }
-
- /**
- * Look for the schema files that should be in vespa-model.jar and saves them on temp dir.
- *
- * @return the directory the schema files are stored in
- * @throws IOException if it is not possible to read schema files
- */
- private File saveSchemasFromJar(File tmpBase, Version vespaVersion) throws IOException {
- final Class<? extends SchemaValidator> schemaValidatorClass = this.getClass();
- final ClassLoader classLoader = schemaValidatorClass.getClassLoader();
- Enumeration<URL> uris = classLoader.getResources("schema");
- if (uris==null) return null;
- File tmpDir = java.nio.file.Files.createTempDirectory(tmpBase.toPath(), "vespa").toFile();
- log.log(LogLevel.DEBUG, "Saving schemas to " + tmpDir);
- while(uris.hasMoreElements()) {
- URL u = uris.nextElement();
- log.log(LogLevel.DEBUG, "uri for resource 'schema'=" + u.toString());
- if ("jar".equals(u.getProtocol())) {
- JarURLConnection jarConnection = (JarURLConnection) u.openConnection();
- JarFile jarFile = jarConnection.getJarFile();
- for (Enumeration<JarEntry> entries = jarFile.entries();
- entries.hasMoreElements();) {
-
- JarEntry je=entries.nextElement();
- if (je.getName().startsWith("schema/") && je.getName().endsWith(".rnc")) {
- writeContentsToFile(tmpDir, je.getName(), jarFile.getInputStream(je));
- }
- }
- jarFile.close();
- } else if ("bundle".equals(u.getProtocol())) {
- Bundle bundle = FrameworkUtil.getBundle(schemaValidatorClass);
- log.log(LogLevel.DEBUG, classLoader.toString());
- log.log(LogLevel.DEBUG, "bundle=" + bundle);
- // TODO: Hack to handle cases where bundle=null
- if (bundle == null) {
- File schemaPath;
- if (vespaVersion.getMajor() == 5) {
- schemaPath = new File(getDefaults().underVespaHome("share/vespa/schema/version/5.x/schema/"));
- } else {
- schemaPath = new File(getDefaults().underVespaHome("share/vespa/schema/"));
- }
- log.log(LogLevel.DEBUG, "Using schemas found in " + schemaPath);
- copySchemas(schemaPath, tmpDir);
- } else {
- log.log(LogLevel.DEBUG, String.format("Saving schemas for model bundle %s:%s", bundle.getSymbolicName(), bundle
- .getVersion()));
- for (Enumeration<URL> entries = bundle.findEntries("schema", "*.rnc", true);
- entries.hasMoreElements(); ) {
-
- URL url = entries.nextElement();
- writeContentsToFile(tmpDir, url.getFile(), url.openStream());
- }
- }
- } else if ("file".equals(u.getProtocol())) {
- File schemaPath = new File(u.getPath());
- copySchemas(schemaPath, tmpDir);
- }
- }
- return tmpDir;
- }
-
- private static void copySchemas(File from, File to) throws IOException {
- // TODO: only copy .rnc files.
- if (! from.exists()) throw new IOException("Could not find schema source directory '" + from + "'");
- if (! from.isDirectory()) throw new IOException("Schema source '" + from + "' is not a directory");
- File sourceFile = new File(from, servicesXmlSchemaName);
- if (! sourceFile.exists()) throw new IOException("Schema source file '" + sourceFile + "' not found");
- IOUtils.copyDirectoryInto(from, to);
- }
-
- private static void writeContentsToFile(File outDir, String outFile, InputStream inputStream) throws IOException {
- String contents = IOUtils.readAll(new InputStreamReader(inputStream));
- File out = new File(outDir, outFile);
- IOUtils.writeFile(out, contents, false);
- }
-
- private void loadSchema(File schemaFile) {
- try {
- driver.loadSchema(ValidationDriver.fileInputSource(schemaFile));
- } catch (SAXException e) {
- throw new RuntimeException("Invalid schema '" + schemaFile + "'", e);
- } catch (IOException e) {
- throw new RuntimeException("IO error reading schema '" + schemaFile + "'", e);
- }
- }
-
- private PropertyMap instanceProperties() {
- PropertyMapBuilder builder = new PropertyMapBuilder();
- builder.put(ValidateProperty.ERROR_HANDLER, errorHandler);
- return builder.toPropertyMap();
+ SchemaValidator(File schemaFile, DeployLogger deployLogger) throws IOException, SAXException {
+ this.deployLogger = deployLogger;
+ this.driver = new ValidationDriver(PropertyMap.EMPTY, instanceProperties(), CompactSchemaReader.getInstance());
+ driver.loadSchema(ValidationDriver.fileInputSource(schemaFile));
}
public void validate(File file) throws IOException {
@@ -246,4 +72,33 @@ public class SchemaValidator {
"XML error in " + (fileName == null ? " input" : fileName) + ": " + Exceptions.toMessageString(e));
}
}
+
+ private PropertyMap instanceProperties() {
+ PropertyMapBuilder builder = new PropertyMapBuilder();
+ builder.put(ValidateProperty.ERROR_HANDLER, errorHandler);
+ return builder.toPropertyMap();
+ }
+
+ private class CustomErrorHandler implements ErrorHandler {
+ volatile String fileName;
+
+ public void warning(SAXParseException e) throws SAXException {
+ deployLogger.log(Level.WARNING, message(e));
+ }
+
+ public void error(SAXParseException e) throws SAXException {
+ throw new IllegalArgumentException(message(e));
+ }
+
+ public void fatalError(SAXParseException e) throws SAXException {
+ throw new IllegalArgumentException(message(e));
+ }
+
+ private String message(SAXParseException e) {
+ return "XML error in " + fileName + ": " +
+ Exceptions.toMessageString(e)
+ + " [" + e.getLineNumber() + ":" + e.getColumnNumber() + "]";
+ }
+ }
+
}
diff --git a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/SchemaValidators.java b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/SchemaValidators.java
new file mode 100644
index 00000000000..e7e65751ee8
--- /dev/null
+++ b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/SchemaValidators.java
@@ -0,0 +1,195 @@
+// 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.component.Version;
+import com.yahoo.config.application.api.DeployLogger;
+import com.yahoo.io.IOUtils;
+import com.yahoo.log.LogLevel;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+import org.xml.sax.SAXException;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.JarURLConnection;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.logging.Logger;
+
+import static com.yahoo.vespa.defaults.Defaults.getDefaults;
+
+/**
+ * Wrapper class for schema validators for application package xml files
+ *
+ * @author hmusum
+ */
+public class SchemaValidators {
+
+ private static final String schemaDirBase = System.getProperty("java.io.tmpdir", File.separator + "tmp" + File.separator + "vespa");
+ private static final Logger log = Logger.getLogger(SchemaValidators.class.getName());
+
+ private static final String servicesXmlSchemaName = "services.rnc";
+ private static final String hostsXmlSchemaName = "hosts.rnc";
+ private static final String deploymentXmlSchemaName = "deployment.rnc";
+ private static final String validationOverridesXmlSchemaName = "validation-overrides.rnc";
+ private static final String containerIncludeXmlSchemaName = "container-include.rnc";
+ private static final String routingStandaloneXmlSchemaName = "routing-standalone.rnc";
+
+
+ private final DeployLogger deployLogger;
+
+ private final SchemaValidator servicesXmlValidator;
+ private final SchemaValidator hostsXmlValidator;
+ private final SchemaValidator deploymentXmlValidator;
+ private final SchemaValidator validationOverridesXmlValidator;
+ private final SchemaValidator containerIncludeXmlValidator;
+ private final SchemaValidator routingStandaloneXmlValidator;
+
+ /**
+ * Initializes the validator by using the given file as schema file
+ *
+ * @param vespaVersion the version of Vespa we should validate against
+ */
+ public SchemaValidators(Version vespaVersion, DeployLogger logger) {
+ this.deployLogger = logger;
+ File schemaDir;
+ try {
+ schemaDir = saveSchemasFromJar(new File(SchemaValidators.schemaDirBase), vespaVersion);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ servicesXmlValidator = createValidator(schemaDir, servicesXmlSchemaName);
+ hostsXmlValidator = createValidator(schemaDir, hostsXmlSchemaName);
+ deploymentXmlValidator = createValidator(schemaDir, deploymentXmlSchemaName);
+ validationOverridesXmlValidator = createValidator(schemaDir, validationOverridesXmlSchemaName);
+ containerIncludeXmlValidator = createValidator(schemaDir, containerIncludeXmlSchemaName);
+ routingStandaloneXmlValidator = createValidator(schemaDir, routingStandaloneXmlSchemaName);
+ IOUtils.recursiveDeleteDir(schemaDir);
+ }
+
+ /**
+ * Initializes the validator by using the given file as schema file
+ *
+ * @param vespaVersion the version of Vespa we should validate against
+ */
+ public SchemaValidators(Version vespaVersion) {
+ this(vespaVersion, new BaseDeployLogger());
+ }
+
+ public SchemaValidator servicesXmlValidator() throws IOException {
+ return servicesXmlValidator;
+ }
+
+ public SchemaValidator hostsXmlValidator() throws IOException {
+ return hostsXmlValidator;
+ }
+
+ public SchemaValidator deploymentXmlValidator() throws IOException {
+ return deploymentXmlValidator;
+ }
+
+ SchemaValidator validationOverridesXmlValidator() throws IOException {
+ return validationOverridesXmlValidator;
+ }
+
+ SchemaValidator containerIncludeXmlValidator() {
+ return containerIncludeXmlValidator;
+ }
+
+ public SchemaValidator routingStandaloneXmlValidator() {
+ return routingStandaloneXmlValidator;
+ }
+
+ /**
+ * Look for the schema files that should be in vespa-model.jar and saves them on temp dir.
+ *
+ * @return the directory the schema files are stored in
+ * @throws IOException if it is not possible to read schema files
+ */
+ File saveSchemasFromJar(File tmpBase, Version vespaVersion) throws IOException {
+ final Class<? extends SchemaValidators> schemaValidatorClass = this.getClass();
+ final ClassLoader classLoader = schemaValidatorClass.getClassLoader();
+ Enumeration<URL> uris = classLoader.getResources("schema");
+ if (uris == null) return null;
+ File tmpDir = java.nio.file.Files.createTempDirectory(tmpBase.toPath(), "vespa").toFile();
+ log.log(LogLevel.DEBUG, "Will save all XML schemas to " + tmpDir);
+ while (uris.hasMoreElements()) {
+ URL u = uris.nextElement();
+ log.log(LogLevel.DEBUG, "uri for resource 'schema'=" + u.toString());
+ if ("jar".equals(u.getProtocol())) {
+ JarURLConnection jarConnection = (JarURLConnection) u.openConnection();
+ JarFile jarFile = jarConnection.getJarFile();
+ for (Enumeration<JarEntry> entries = jarFile.entries();
+ entries.hasMoreElements(); ) {
+
+ JarEntry je = entries.nextElement();
+ if (je.getName().startsWith("schema/") && je.getName().endsWith(".rnc")) {
+ writeContentsToFile(tmpDir, je.getName(), jarFile.getInputStream(je));
+ }
+ }
+ jarFile.close();
+ } else if ("bundle".equals(u.getProtocol())) {
+ Bundle bundle = FrameworkUtil.getBundle(schemaValidatorClass);
+ log.log(LogLevel.DEBUG, classLoader.toString());
+ log.log(LogLevel.DEBUG, "bundle=" + bundle);
+ // TODO: Hack to handle cases where bundle=null
+ if (bundle == null) {
+ File schemaPath;
+ if (vespaVersion.getMajor() == 5) {
+ schemaPath = new File(getDefaults().underVespaHome("share/vespa/schema/version/5.x/schema/"));
+ } else {
+ schemaPath = new File(getDefaults().underVespaHome("share/vespa/schema/"));
+ }
+ log.log(LogLevel.DEBUG, "Using schemas found in " + schemaPath);
+ copySchemas(schemaPath, tmpDir);
+ } else {
+ log.log(LogLevel.DEBUG, String.format("Saving schemas for model bundle %s:%s", bundle.getSymbolicName(), bundle
+ .getVersion()));
+ for (Enumeration<URL> entries = bundle.findEntries("schema", "*.rnc", true);
+ entries.hasMoreElements(); ) {
+
+ URL url = entries.nextElement();
+ writeContentsToFile(tmpDir, url.getFile(), url.openStream());
+ }
+ }
+ } else if ("file".equals(u.getProtocol())) {
+ File schemaPath = new File(u.getPath());
+ copySchemas(schemaPath, tmpDir);
+ }
+ }
+ return tmpDir;
+ }
+
+ // TODO: This only copies schema for services.xml. Why?
+ private static void copySchemas(File from, File to) throws IOException {
+ // TODO: only copy .rnc files.
+ if (! from.exists()) throw new IOException("Could not find schema source directory '" + from + "'");
+ if (! from.isDirectory()) throw new IOException("Schema source '" + from + "' is not a directory");
+ File sourceFile = new File(from, servicesXmlSchemaName);
+ if (! sourceFile.exists()) throw new IOException("Schema source file '" + sourceFile + "' not found");
+ IOUtils.copyDirectoryInto(from, to);
+ }
+
+ private static void writeContentsToFile(File outDir, String outFile, InputStream inputStream) throws IOException {
+ String contents = IOUtils.readAll(new InputStreamReader(inputStream));
+ File out = new File(outDir, outFile);
+ IOUtils.writeFile(out, contents, false);
+ }
+
+ private SchemaValidator createValidator(File schemaDir, String schemaFile) {
+ try {
+ File file = new File(schemaDir + File.separator + "schema" + File.separator + schemaFile);
+ return new SchemaValidator(file, deployLogger);
+ } catch (SAXException e) {
+ throw new RuntimeException("Invalid schema '" + schemaFile + "'", e);
+ } catch (IOException e) {
+ throw new RuntimeException("IO error reading schema '" + schemaFile + "'", e);
+ }
+ }
+
+}
diff --git a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/SimpleApplicationValidator.java b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/SimpleApplicationValidator.java
index f94cf3e31a0..9db254bc742 100644
--- a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/SimpleApplicationValidator.java
+++ b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/SimpleApplicationValidator.java
@@ -14,6 +14,6 @@ import java.io.Reader;
public class SimpleApplicationValidator {
public static void checkServices(Reader reader, Version version) throws IOException {
- SchemaValidator.createTestValidatorServices(version).validate(reader);
+ new SchemaValidators(version, new BaseDeployLogger()).servicesXmlValidator().validate(reader);
}
}