summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@verizonmedia.com>2020-03-13 15:03:16 +0100
committerJon Bratseth <bratseth@verizonmedia.com>2020-03-13 15:03:16 +0100
commitd1dc33f47cb35a0542f10f60309a3d24b7a85a29 (patch)
treea9076d1c5d0aa699e7f5a9131cb0d0c90646ef39
parent8afe53c8d43910621ce19ad7d278b601dd85eaa1 (diff)
searchdefinitions -> schemas
-rw-r--r--application/src/main/java/com/yahoo/application/Application.java6
-rw-r--r--application/src/main/java/com/yahoo/application/ApplicationBuilder.java4
-rw-r--r--application/src/test/java/com/yahoo/application/ApplicationBuilderTest.java9
-rw-r--r--config-application-package/src/main/java/com/yahoo/config/model/application/provider/AppSubDirs.java5
-rw-r--r--config-application-package/src/main/java/com/yahoo/config/model/application/provider/ApplicationPackageXmlFilesValidator.java10
-rw-r--r--config-application-package/src/main/java/com/yahoo/config/model/application/provider/FilesApplicationPackage.java156
-rw-r--r--config-model-api/abi-spec.json1
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/ApplicationPackage.java28
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/SuperModelListener.java3
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java20
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/ApplicationDeployTest.java17
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClient.java84
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplication.java13
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplicationPackage.java22
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClientTest.java20
15 files changed, 181 insertions, 217 deletions
diff --git a/application/src/main/java/com/yahoo/application/Application.java b/application/src/main/java/com/yahoo/application/Application.java
index b200244a21c..87e82a3fdeb 100644
--- a/application/src/main/java/com/yahoo/application/Application.java
+++ b/application/src/main/java/com/yahoo/application/Application.java
@@ -254,13 +254,13 @@ public final class Application implements AutoCloseable {
* @throws java.io.IOException e.g.if file not found
*/
public Builder documentType(String name, String searchDefinition) throws IOException {
- Path path = nestedResource(ApplicationPackage.SEARCH_DEFINITIONS_DIR, name, ApplicationPackage.SD_NAME_SUFFIX);
+ Path path = nestedResource(ApplicationPackage.SCHEMAS_DIR, name, ApplicationPackage.SD_NAME_SUFFIX);
createFile(path, searchDefinition);
return this;
}
public Builder expressionInclude(String name, String searchDefinition) throws IOException {
- Path path = nestedResource(ApplicationPackage.SEARCH_DEFINITIONS_DIR, name, ApplicationPackage.RANKEXPRESSION_NAME_SUFFIX);
+ Path path = nestedResource(ApplicationPackage.SCHEMAS_DIR, name, ApplicationPackage.RANKEXPRESSION_NAME_SUFFIX);
createFile(path, searchDefinition);
return this;
}
@@ -271,7 +271,7 @@ public final class Application implements AutoCloseable {
* @throws java.io.IOException e.g.if file not found
*/
public Builder rankExpression(String name, String rankExpressionContent) throws IOException {
- Path path = nestedResource(ApplicationPackage.SEARCH_DEFINITIONS_DIR, name, ApplicationPackage.RANKEXPRESSION_NAME_SUFFIX);
+ Path path = nestedResource(ApplicationPackage.SCHEMAS_DIR, name, ApplicationPackage.RANKEXPRESSION_NAME_SUFFIX);
createFile(path, rankExpressionContent);
return this;
}
diff --git a/application/src/main/java/com/yahoo/application/ApplicationBuilder.java b/application/src/main/java/com/yahoo/application/ApplicationBuilder.java
index 9d7cf2c8673..ac64ae188e5 100644
--- a/application/src/main/java/com/yahoo/application/ApplicationBuilder.java
+++ b/application/src/main/java/com/yahoo/application/ApplicationBuilder.java
@@ -37,13 +37,13 @@ public class ApplicationBuilder {
}
public ApplicationBuilder documentType(String name, String searchDefinition) throws IOException {
- Path path = nestedResource(ApplicationPackage.SEARCH_DEFINITIONS_DIR, name, ApplicationPackage.SD_NAME_SUFFIX);
+ Path path = nestedResource(ApplicationPackage.SCHEMAS_DIR, name, ApplicationPackage.SD_NAME_SUFFIX);
createFile(path, searchDefinition);
return this;
}
public ApplicationBuilder rankExpression(String name, String rankExpressionContent) throws IOException {
- Path path = nestedResource(ApplicationPackage.SEARCH_DEFINITIONS_DIR, name, ApplicationPackage.RANKEXPRESSION_NAME_SUFFIX);
+ Path path = nestedResource(ApplicationPackage.SCHEMAS_DIR, name, ApplicationPackage.RANKEXPRESSION_NAME_SUFFIX);
createFile(path, rankExpressionContent);
return this;
}
diff --git a/application/src/test/java/com/yahoo/application/ApplicationBuilderTest.java b/application/src/test/java/com/yahoo/application/ApplicationBuilderTest.java
index a4f566e2a71..a0c2ec9983b 100644
--- a/application/src/test/java/com/yahoo/application/ApplicationBuilderTest.java
+++ b/application/src/test/java/com/yahoo/application/ApplicationBuilderTest.java
@@ -32,9 +32,10 @@ public class ApplicationBuilderTest {
@Test
public void query_profile_can_be_added() throws Exception {
withApplicationBuilder(builder -> {
- builder.queryProfile("MyProfile", "<query-profile id=\"MyProfile\">" + //
- "<field name=\"message\">Hello world!</field>" + //
- "</query-profile>");
+ builder.queryProfile("MyProfile",
+ "<query-profile id=\"MyProfile\">" +
+ "<field name=\"message\">Hello world!</field>" +
+ "</query-profile>");
assertTrue(Files.exists(builder.getPath().resolve("search/query-profiles/MyProfile.xml")));
});
@@ -44,7 +45,7 @@ public class ApplicationBuilderTest {
public void rank_expression_can_be_added() throws Exception {
withApplicationBuilder(builder -> {
builder.rankExpression("myExpression", "content");
- assertTrue(Files.exists(builder.getPath().resolve("searchdefinitions/myExpression.expression")));
+ assertTrue(Files.exists(builder.getPath().resolve("schemas/myExpression.expression")));
});
}
diff --git a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/AppSubDirs.java b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/AppSubDirs.java
index 32054b1ad9a..2b7aa5ab6e1 100644
--- a/config-application-package/src/main/java/com/yahoo/config/model/application/provider/AppSubDirs.java
+++ b/config-application-package/src/main/java/com/yahoo/config/model/application/provider/AppSubDirs.java
@@ -59,8 +59,7 @@ public class AppSubDirs {
return configDefs.first;
}
- public File searchdefinitions() {
- return searchdefinitions.first;
- }
+ @Deprecated // Remove after March 2020
+ public File searchdefinitions() { return searchdefinitions.first; }
}
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 74ade9d8e14..b0c4f74f9f6 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
@@ -35,20 +35,11 @@ public class ApplicationPackageXmlFilesValidator {
return new ApplicationPackageXmlFilesValidator(new AppSubDirs(appDir), vespaVersion);
}
- @SuppressWarnings("deprecation")
public void checkApplication() throws IOException {
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()) {
- throw new IllegalArgumentException("Application package in " + appDirs.root() +
- " must contain at least one search definition (.sd) file when directory searchdefinitions/ exists.");
- }
- }
-
validateRouting(appDirs.routingtables);
}
@@ -71,7 +62,6 @@ public class ApplicationPackageXmlFilesValidator {
validator.validate(appDirs.file(filename));
}
- @SuppressWarnings("deprecation")
private String servicesFileName() {
String servicesFile = FilesApplicationPackage.SERVICES;
if ( ! appDirs.file(servicesFile).exists()) {
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 8c3ccdc4c0b..5860c365947 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
@@ -49,6 +49,7 @@ import java.security.MessageDigest;
import java.util.*;
import java.util.jar.JarFile;
import java.util.logging.Logger;
+import java.util.stream.Stream;
import static com.yahoo.text.Lowercase.toLowerCase;
@@ -336,77 +337,73 @@ public class FilesApplicationPackage implements ApplicationPackage {
public static Map<String, String> allSdsFromDocprocBundlesAndClasspath(File appDir) throws IOException {
File dpChains = new File(appDir, ApplicationPackage.COMPONENT_DIR);
if (!dpChains.exists() || !dpChains.isDirectory()) return Collections.emptyMap();
- List<String> usedNames = new ArrayList<>();
- Map<String, String> ret = new LinkedHashMap<>();
+ Set<String> usedNames = new HashSet<>();
+ Map<String, String> schemas = new LinkedHashMap<>();
// try classpath first
- allSdsOnClassPath(usedNames, ret);
+ allSdsOnClassPath(usedNames, schemas);
- for (File bundle : dpChains.listFiles(new FilenameFilter() {
- @Override
- public boolean accept(File dir, String name) {
- return name.endsWith(".jar");
- }})) {
+ for (File bundle : dpChains.listFiles((File dir, String name) -> name.endsWith(".jar"))) {
for(Map.Entry<String, String> entry : ApplicationPackage.getBundleSdFiles("", new JarFile(bundle)).entrySet()) {
String sdName = entry.getKey();
if (usedNames.contains(sdName)) {
- throw new IllegalArgumentException("The search definition name '"+sdName+"' used in bundle '"+
- bundle.getName()+"' is already used in classpath or previous bundle.");
+ throw new IllegalArgumentException("The search definition name '" + sdName + "' used in bundle '"+
+ bundle.getName()+ "' is already used in classpath or previous bundle.");
}
usedNames.add(sdName);
String sdPayload = entry.getValue();
- ret.put(sdName, sdPayload);
+ schemas.put(sdName, sdPayload);
}
}
- return ret;
+ return schemas;
}
- private static void allSdsOnClassPath(List<String> usedNames, Map<String, String> ret) throws IOException {
- Enumeration<java.net.URL> resources = FilesApplicationPackage.class.getClassLoader().getResources(ApplicationPackage.SEARCH_DEFINITIONS_DIR.getRelative());
-
- while(resources.hasMoreElements()) {
- URL resource = resources.nextElement();
-
- String protocol = resource.getProtocol();
+ private static void allSdsOnClassPath(Set<String> usedNames, Map<String, String> schemas) {
+ ClassLoader cl = FilesApplicationPackage.class.getClassLoader();
+ Stream<URL> resources = Stream.concat(cl.resources(ApplicationPackage.SEARCH_DEFINITIONS_DIR.getRelative()),
+ cl.resources(ApplicationPackage.SCHEMAS_DIR.getRelative()));
+ resources.forEach(resource -> addSchemaFrom(resource, schemas, usedNames));
+ }
- if ("file".equals(protocol)) {
- File file;
- try {
- file = new File(resource.toURI());
- } catch (URISyntaxException e) {
- continue;
- }
- // only interested in directories
- if (file.isDirectory()) {
- List<File> sdFiles = getSearchDefinitionFiles(file);
- for (File sdFile : sdFiles) {
- String sdName = sdFile.getName();
+ private static void addSchemaFrom(URL resource, Map<String, String> schemas, Set<String> usedNames) {
+ try {
+ switch (resource.getProtocol()) {
+ case "file":
+ File file = new File(resource.toURI());
+ if (file.isDirectory()) {
+ List<File> sdFiles = getSearchDefinitionFiles(file);
+ for (File sdFile : sdFiles) {
+ String sdName = sdFile.getName();
+ if (usedNames.contains(sdName)) {
+ throw new IllegalArgumentException("The search definition name '" + sdName +
+ "' found in classpath already used earlier in classpath.");
+ }
+ usedNames.add(sdName);
+ String contents = IOUtils.readAll(new FileReader(sdFile));
+ schemas.put(sdFile.getName(), contents);
+ }
+ }
+ break;
+ case "jar":
+ JarURLConnection jarConnection = (JarURLConnection) resource.openConnection();
+ JarFile jarFile = jarConnection.getJarFile();
+ for (Map.Entry<String, String> entry : ApplicationPackage.getBundleSdFiles("", jarFile).entrySet()) {
+ String sdName = entry.getKey();
if (usedNames.contains(sdName)) {
- throw new IllegalArgumentException("The search definition name '"+sdName+
- "' found in classpath already used earlier in classpath.");
+ throw new IllegalArgumentException("The search definitions name '" + sdName +
+ "' used in bundle '" + jarFile.getName() + "' " +
+ "is already used in classpath or previous bundle.");
}
usedNames.add(sdName);
- String contents = IOUtils.readAll(new FileReader(sdFile));
- ret.put(sdFile.getName(), contents);
- }
- }
- }
- else if ("jar".equals(protocol)) {
- JarURLConnection jarConnection = (JarURLConnection) resource.openConnection();
- JarFile jarFile = jarConnection.getJarFile();
- for(Map.Entry<String, String> entry : ApplicationPackage.getBundleSdFiles("", jarFile).entrySet()) {
- String sdName = entry.getKey();
- if (usedNames.contains(sdName)) {
- throw new IllegalArgumentException("The search definitions name '"+sdName+
- "' used in bundle '"+jarFile.getName()+"' " +
- "is already used in classpath or previous bundle.");
+ String sdPayload = entry.getValue();
+ schemas.put(sdName, sdPayload);
}
- usedNames.add(sdName);
- String sdPayload = entry.getValue();
- ret.put(sdName, sdPayload);
- }
+ break;
}
}
+ catch (IOException | URISyntaxException e) {
+ throw new IllegalArgumentException("Could not read schema from '" + resource + "'", e);
+ }
}
/**
@@ -462,11 +459,7 @@ public class FilesApplicationPackage implements ApplicationPackage {
if (! configDefsDir.isDirectory()) return;
log.log(LogLevel.DEBUG, "Getting all config definitions from '" + configDefsDir + "'");
- for (File def : configDefsDir.listFiles(
- new FilenameFilter() { @Override public boolean accept(File dir, String name) { // TODO: Fix
- return name.matches(".*\\.def");}})) {
-
- log.log(LogLevel.DEBUG, "Processing config definition '" + def + "'");
+ for (File def : configDefsDir.listFiles((File dir, String name) -> name.matches(".*\\.def"))) {
String[] nv = def.getName().split("\\.def");
ConfigDefinitionKey key;
try {
@@ -521,30 +514,25 @@ public class FilesApplicationPackage implements ApplicationPackage {
}
}
- //Only intended for DeployProcessor, others should use the member version
static List<File> getSearchDefinitionFiles(File appDir) {
- //The dot is escaped later in this method:
- assert (ApplicationPackage.SD_NAME_SUFFIX.charAt(0) == '.');
+ List<File> schemaFiles = new ArrayList<>();
+
+ File sdDir = new File(appDir, ApplicationPackage.SEARCH_DEFINITIONS_DIR.getRelative());
+ if (sdDir.isDirectory())
+ schemaFiles.addAll(Arrays.asList(sdDir.listFiles((dir, name) -> name.matches(".*\\" + ApplicationPackage.SD_NAME_SUFFIX))));
- List<File> ret = new ArrayList<>();
- File sdDir;
+ sdDir = new File(appDir, ApplicationPackage.SCHEMAS_DIR.getRelative());
+ if (sdDir.isDirectory())
+ schemaFiles.addAll(Arrays.asList(sdDir.listFiles((dir, name) -> name.matches(".*\\" + ApplicationPackage.SD_NAME_SUFFIX))));
- sdDir = new File(appDir, ApplicationPackage.SEARCH_DEFINITIONS_DIR.getRelative());
- if (!sdDir.isDirectory()) {
- return ret;
- }
- ret.addAll(Arrays.asList(
- sdDir.listFiles(
- new FilenameFilter() { @Override public boolean accept(File dir, String name) {
- return name.matches(".*\\" + ApplicationPackage.SD_NAME_SUFFIX);}})));
- return ret;
+ return schemaFiles;
}
public List<File> getSearchDefinitionFiles() {
return getSearchDefinitionFiles(appDir);
}
- //Only for use by deploy processor
+ // Only for use by deploy processor
public static List<Component> getComponents(File appDir) {
List<Component> components = new ArrayList<>();
for (Bundle bundle : Bundle.getBundles(new File(appDir, ApplicationPackage.COMPONENT_DIR))) {
@@ -622,6 +610,7 @@ public class FilesApplicationPackage implements ApplicationPackage {
public Bundle getBundle() {
return bundle;
}
+
} // class Component
/**
@@ -643,12 +632,14 @@ public class FilesApplicationPackage implements ApplicationPackage {
}
private File expressionFileNameToFile(String name) {
- File expressionFile = new File(name);
- if (expressionFile.isAbsolute()) {
+ if (new File(name).isAbsolute())
throw new IllegalArgumentException("Absolute path to ranking expression file is not allowed: " + name);
- }
- File sdDir = new File(appDir, ApplicationPackage.SEARCH_DEFINITIONS_DIR.getRelative());
- return new File(sdDir, name);
+
+ File sdDir = new File(appDir, ApplicationPackage.SCHEMAS_DIR.getRelative());
+ File expressionFile = new File(sdDir, name);
+ if ( !expressionFile.exists())
+ expressionFile = new File(appDir, ApplicationPackage.SEARCH_DEFINITIONS_DIR.getRelative());
+ return expressionFile;
}
@Override
@@ -700,9 +691,8 @@ public class FilesApplicationPackage implements ApplicationPackage {
! name.equals(HOSTS) &&
! name.equals(CONFIG_DEFINITIONS_DIR));
preprocessXML(new File(preprocessedDir, SERVICES), getServicesFile(), zone);
- if (getHostsFile().exists()) {
+ if (getHostsFile().exists())
preprocessXML(new File(preprocessedDir, HOSTS), getHostsFile(), zone);
- }
FilesApplicationPackage preprocessed = FilesApplicationPackage.fromFile(preprocessedDir, includeSourceFiles);
preprocessed.copyUserDefsIntoApplication();
return preprocessed;
@@ -742,11 +732,12 @@ public class FilesApplicationPackage implements ApplicationPackage {
/**
* Adds the given path to the digest, or does nothing if path is neither file nor dir
+ *
* @param path path to add to message digest
* @param suffix only files with this suffix are considered
* @param digest the {link @MessageDigest} to add the file paths to
* @param recursive whether to recursively find children in the paths
- * @param fullPathNames Whether to include the full paths in checksum or only the names
+ * @param fullPathNames whether to include the full paths in checksum or only the names
* @throws java.io.IOException if adding path to digest fails when reading files from path
*/
private static void addPathToDigest(File path, String suffix, MessageDigest digest, boolean recursive, boolean fullPathNames) throws IOException {
@@ -773,16 +764,17 @@ public class FilesApplicationPackage implements ApplicationPackage {
}
private static final int MD5_BUFFER_SIZE = 65536;
+
private static void addToDigest(InputStream is, MessageDigest digest) throws IOException {
- if (is==null) return;
+ if (is == null) return;
byte[] buffer = new byte[MD5_BUFFER_SIZE];
int i;
do {
- i=is.read(buffer);
+ i = is.read(buffer);
if (i > 0) {
digest.update(buffer, 0, i);
}
- } while(i!=-1);
+ } while(i != -1);
}
/**
diff --git a/config-model-api/abi-spec.json b/config-model-api/abi-spec.json
index 8556fd4a40b..4a7d929fd3e 100644
--- a/config-model-api/abi-spec.json
+++ b/config-model-api/abi-spec.json
@@ -137,6 +137,7 @@
"fields": [
"public static final java.lang.String HOSTS",
"public static final java.lang.String SERVICES",
+ "public static final com.yahoo.path.Path SCHEMAS_DIR",
"public static final com.yahoo.path.Path SEARCH_DEFINITIONS_DIR",
"public static final java.lang.String COMPONENT_DIR",
"public static final java.lang.String SEARCHCHAINS_DIR",
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 db3d391d19b..174f9bb54d7 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
@@ -36,8 +36,6 @@ import java.util.jar.JarFile;
* The class hides detail as to whether the source is local files or ZooKeeper
* data in config server.
*
- * Anyone wanting to access application data should use this interface.
- *
* @author Vegard Havdal
*/
public interface ApplicationPackage {
@@ -47,7 +45,8 @@ public interface ApplicationPackage {
String HOSTS = "hosts.xml";
String SERVICES = "services.xml";
- Path SEARCH_DEFINITIONS_DIR = Path.fromString("searchdefinitions");
+ Path SCHEMAS_DIR = Path.fromString("schemas");
+ Path SEARCH_DEFINITIONS_DIR = Path.fromString("searchdefinitions"); // Legacy addition to schemas
String COMPONENT_DIR = "components";
String SEARCHCHAINS_DIR = "search/chains";
String DOCPROCCHAINS_DIR = "docproc/chains";
@@ -168,7 +167,7 @@ public interface ApplicationPackage {
}
/**
- * Returns inforamtion about a file
+ * Returns information about a file
*
* @param relativePath the relative path of the file within this application package.
* @return information abut the file, returned whether or not the file exists
@@ -206,23 +205,26 @@ public interface ApplicationPackage {
Reader getRankingExpression(String name);
/**
- * Returns the name-payload pairs of any sd files under path/searchdefinitions/ in the given jar bundle
- * @param bundle The jar file, which will be closed afterwards by this method.
- * @param path For example 'complex/'
+ * Returns the name-payload pairs of any sd files under path/schemas and path/searchdefinitions/
+ * in the given jar bundle.
+ *
+ * @param bundle the jar file, which will be closed afterwards by this method
+ * @param path for example 'complex/'
* @return map of the SD payloads
* @throws IOException if it is reading sd files fails
*/
static Map<String, String> getBundleSdFiles(String path, JarFile bundle) throws IOException {
- Map<String,String> ret = new LinkedHashMap<>();
+ Map<String, String> schemas = new LinkedHashMap<>();
for (Enumeration<JarEntry> e = bundle.entries(); e.hasMoreElements();) {
- JarEntry je=e.nextElement();
- if (je.getName().startsWith(path+SEARCH_DEFINITIONS_DIR+"/") && je.getName().endsWith(SD_NAME_SUFFIX)) {
- String contents = IOUtils.readAll(new InputStreamReader(bundle.getInputStream(je)));
- ret.put(getFileName(je), contents);
+ JarEntry entry = e.nextElement();
+ if ((entry.getName().startsWith(path + SCHEMAS_DIR + "/") || entry.getName().startsWith(path + SEARCH_DEFINITIONS_DIR + "/"))
+ && entry.getName().endsWith(SD_NAME_SUFFIX)) {
+ String contents = IOUtils.readAll(new InputStreamReader(bundle.getInputStream(entry)));
+ schemas.put(getFileName(entry), contents);
}
}
bundle.close();
- return ret;
+ return schemas;
}
/**
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/SuperModelListener.java b/config-model-api/src/main/java/com/yahoo/config/model/api/SuperModelListener.java
index e66a7e1ef7e..930c3c94907 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/SuperModelListener.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/SuperModelListener.java
@@ -7,6 +7,7 @@ import com.yahoo.config.provision.ApplicationId;
* Interface for those wanting to be notified about changes to the SuperModel.
*/
public interface SuperModelListener {
+
/**
* Application has been activated: Either deployed the first time,
* internally redeployed, or externally triggered redeploy.
@@ -22,7 +23,7 @@ public interface SuperModelListener {
* Invoked once all applications that were supposed to be deployed on bootstrap
* have been activated (and the respective {@link #applicationActivated(SuperModel, ApplicationInfo)
* applicationActivated} have been invoked). The SuperModel is then said to be "complete".
- * @param superModel
*/
void notifyOfCompleteness(SuperModel superModel);
+
}
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
index a9b4e06ae1b..23983fda413 100644
--- a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
+++ b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
@@ -417,20 +417,18 @@ public class DeployState implements ConfigDefinitionStore {
for (NamedReader reader : readers) {
try {
String readerName = reader.getName();
- String searchName = builder.importReader(reader, readerName, logger);
+ String topLevelName = builder.importReader(reader, readerName, logger);
String sdName = stripSuffix(readerName, ApplicationPackage.SD_NAME_SUFFIX);
- names.put(searchName, sdName);
- if ( ! sdName.equals(searchName)) {
- throw new IllegalArgumentException("Search definition file name ('" + sdName + "') and name of " +
- "search element ('" + searchName +
+ names.put(topLevelName, sdName);
+ if ( ! sdName.equals(topLevelName)) {
+ throw new IllegalArgumentException("Schema definition file name ('" + sdName + "') and name of " +
+ "top level element ('" + topLevelName +
"') are not equal for file '" + readerName + "'");
}
} catch (ParseException e) {
- throw new IllegalArgumentException("Could not parse search definition file '" +
- getSearchDefinitionRelativePath(reader.getName()) + "': " + e.getMessage(), e);
+ throw new IllegalArgumentException("Could not parse sd file '" + reader.getName(), e);
} catch (IOException e) {
- throw new IllegalArgumentException("Could not read search definition file '" +
- getSearchDefinitionRelativePath(reader.getName()) + "': " + e.getMessage(), e);
+ throw new IllegalArgumentException("Could not read sd file '" + reader.getName(), e);
} finally {
closeIgnoreException(reader.getReader());
}
@@ -439,10 +437,6 @@ public class DeployState implements ConfigDefinitionStore {
return SearchDocumentModel.fromBuilderAndNames(builder, names);
}
- private String getSearchDefinitionRelativePath(String name) {
- return ApplicationPackage.SEARCH_DEFINITIONS_DIR + File.separator + name;
- }
-
private static String stripSuffix(String nodeName, String postfix) {
assert (nodeName.endsWith(postfix));
return nodeName.substring(0, nodeName.length() - postfix.length());
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 cb1577417b4..099ff83774f 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
@@ -72,21 +72,18 @@ public class ApplicationDeployTest {
break;
case "product":
assertTrue(s instanceof DocumentOnlySearch);
- assertEquals(s.getDocument().getField("title").getDataType(), DataType.STRING);
+ assertEquals(DataType.STRING, s.getDocument().getField("title").getDataType());
break;
default:
fail();
}
}
- File[] truth = new File[]{new File(TESTSDDIR + "laptop.sd"),
- new File(TESTSDDIR + "music.sd"),
- new File(TESTSDDIR + "pc.sd"),
- new File(TESTSDDIR + "product.sd"),
- new File(TESTSDDIR + "sock.sd")};
- Arrays.sort(truth);
- List<File> appSdFiles = tester.app().getSearchDefinitionFiles();
- Collections.sort(appSdFiles);
- assertEquals(appSdFiles, Arrays.asList(truth));
+ assertEquals(Set.of(new File(TESTSDDIR + "laptop.sd"),
+ new File(TESTSDDIR + "music.sd"),
+ new File(TESTSDDIR + "pc.sd"),
+ new File(TESTSDDIR + "product.sd"),
+ new File(TESTSDDIR + "sock.sd")),
+ new HashSet<>(tester.app().getSearchDefinitionFiles()));
List<FilesApplicationPackage.Component> components = tester.app().getComponents();
assertEquals(1, components.size());
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClient.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClient.java
index 13ef19f5f5d..9cb97b9cfb5 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClient.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ZooKeeperClient.java
@@ -87,17 +87,16 @@ public class ZooKeeperClient {
/** Sets the app id and attempts to set up zookeeper. The app id must be ordered for purge to work OK. */
private void createZooKeeperNodes() {
- if (!configCurator.exists(rootPath.getAbsolute())) {
+ if ( ! configCurator.exists(rootPath.getAbsolute()))
configCurator.createNode(rootPath.getAbsolute());
- }
- for (String subPath : Arrays.asList(
- ConfigCurator.DEFCONFIGS_ZK_SUBPATH,
- ConfigCurator.USER_DEFCONFIGS_ZK_SUBPATH,
- ConfigCurator.USERAPP_ZK_SUBPATH,
- ZKApplicationPackage.fileRegistryNode)) {
- // TODO The replaceFirst below is hackish.
- configCurator.createNode(getZooKeeperAppPath(null).getAbsolute(), subPath.replaceFirst("/", ""));
+ for (String subPath : Arrays.asList(ConfigCurator.DEFCONFIGS_ZK_SUBPATH,
+ ConfigCurator.USER_DEFCONFIGS_ZK_SUBPATH,
+ ConfigCurator.USERAPP_ZK_SUBPATH,
+ ZKApplicationPackage.fileRegistryNode)) {
+ // TODO: The replaceFirst below is hackish.
+ configCurator.createNode(getZooKeeperAppPath(null).getAbsolute(),
+ subPath.replaceFirst("/", ""));
}
}
@@ -108,7 +107,6 @@ public class ZooKeeperClient {
*/
void write(ApplicationPackage app) {
logFine("Feeding application config into ZooKeeper");
- // gives lots and lots of debug output: // BasicConfigurator.configure();
try {
logFine("Feeding user def files into ZooKeeper");
writeUserDefs(app);
@@ -121,43 +119,33 @@ public class ZooKeeperClient {
write(app.getMetaData());
} catch (Exception e) {
throw new IllegalStateException("Unable to write vespa model to config server(s) " + System.getProperty("configsources") + "\n" +
- "Please ensure that cloudconfig_server is started on the config server node(s), " +
- "and check the vespa log for configserver errors. ", e);
+ "Please ensure that cloudconfig_server is started on the config server node(s), " +
+ "and check the vespa log for configserver errors. ", e);
}
}
private void writeSearchDefinitions(ApplicationPackage app) throws IOException {
Collection<NamedReader> sds = app.getSearchDefinitions();
- if (sds.isEmpty()) {
- return;
- }
- Path zkPath = getZooKeeperAppPath(ConfigCurator.USERAPP_ZK_SUBPATH).append(ApplicationPackage.SEARCH_DEFINITIONS_DIR);
+ if (sds.isEmpty()) return;
+
+ Path zkPath = getZooKeeperAppPath(ConfigCurator.USERAPP_ZK_SUBPATH).append(ApplicationPackage.SCHEMAS_DIR);
configCurator.createNode(zkPath.getAbsolute());
- // Ensures that ranking expressions and other files are also fed.
+ // Ensures that ranking expressions and other files are also written
writeDir(app.getFile(ApplicationPackage.SEARCH_DEFINITIONS_DIR), zkPath, false);
+ writeDir(app.getFile(ApplicationPackage.SCHEMAS_DIR), zkPath, false);
for (NamedReader sd : sds) {
- String name = sd.getName();
- Reader reader = sd.getReader();
- String data = com.yahoo.io.IOUtils.readAll(reader);
- reader.close();
- configCurator.putData(zkPath.getAbsolute(), name, data);
+ configCurator.putData(zkPath.getAbsolute(), sd.getName(), com.yahoo.io.IOUtils.readAll(sd.getReader()));
+ sd.getReader().close();
}
}
/**
* Puts some of the application package files into ZK - see write(app).
*
- * @param app The application package to use as input.
- * @throws java.io.IOException if not able to write to Zookeeper
+ * @param app the application package to use as input.
+ * @throws java.io.IOException if not able to write to Zookeeper
*/
private void writeSomeOf(ApplicationPackage app) throws IOException {
- ApplicationFile.PathFilter srFilter = new ApplicationFile.PathFilter() {
- @Override
- public boolean accept(Path path) {
- return path.getName().endsWith(ApplicationPackage.RULES_NAME_SUFFIX);
- }
- };
- // Copy app package files and subdirs into zk
// TODO: We should have a way of doing this which doesn't require repeating all the content
writeFile(app.getFile(Path.fromString(ApplicationPackage.SERVICES)),
getZooKeeperAppPath(ConfigCurator.USERAPP_ZK_SUBPATH));
@@ -169,7 +157,8 @@ public class ZooKeeperClient {
getZooKeeperAppPath(ConfigCurator.USERAPP_ZK_SUBPATH));
writeDir(app.getFile(ApplicationPackage.RULES_DIR),
getZooKeeperAppPath(ConfigCurator.USERAPP_ZK_SUBPATH).append(ApplicationPackage.RULES_DIR),
- srFilter, true);
+ (path) -> path.getName().endsWith(ApplicationPackage.RULES_NAME_SUFFIX),
+ true);
writeDir(app.getFile(ApplicationPackage.QUERY_PROFILES_DIR),
getZooKeeperAppPath(ConfigCurator.USERAPP_ZK_SUBPATH).append(ApplicationPackage.QUERY_PROFILES_DIR),
xmlFilter, true);
@@ -194,20 +183,12 @@ public class ZooKeeperClient {
}
private void writeDir(ApplicationFile file, Path zooKeeperAppPath, boolean recurse) throws IOException {
- writeDir(file, zooKeeperAppPath, new ApplicationFile.PathFilter() {
- @Override
- public boolean accept(Path path) {
- return true;
- }
- }, recurse);
+ writeDir(file, zooKeeperAppPath, (__) -> true, recurse);
}
private void writeDir(ApplicationFile dir, Path path, ApplicationFile.PathFilter filenameFilter, boolean recurse) throws IOException {
- if (!dir.isDirectory()) {
- logger.log(LogLevel.FINE, dir.getPath().getAbsolute()+" is not a directory. Not feeding the files into ZooKeeper.");
- return;
- }
- for (ApplicationFile file: listFiles(dir, filenameFilter)) {
+ if ( ! dir.isDirectory()) return;
+ for (ApplicationFile file : listFiles(dir, filenameFilter)) {
String name = file.getPath().getName();
if (name.startsWith(".")) continue; //.svn , .git ...
if ("CVS".equals(name)) continue;
@@ -223,7 +204,8 @@ public class ZooKeeperClient {
}
/**
- * Like {@link ApplicationFile#listFiles(com.yahoo.config.application.api.ApplicationFile.PathFilter)} with a slightly different semantic. Never filter out directories.
+ * Like {@link ApplicationFile#listFiles(com.yahoo.config.application.api.ApplicationFile.PathFilter)}
+ * with slightly different semantics: Never filter out directories.
*/
private List<ApplicationFile> listFiles(ApplicationFile dir, ApplicationFile.PathFilter filter) {
List<ApplicationFile> rawList = dir.listFiles();
@@ -243,9 +225,8 @@ public class ZooKeeperClient {
}
private void writeFile(ApplicationFile file, Path zkPath) throws IOException {
- if (!file.exists()) {
- return;
- }
+ if ( ! file.exists()) return;
+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (InputStream inputStream = file.createInputStream()) {
inputStream.transferTo(baos);
@@ -292,8 +273,8 @@ public class ZooKeeperClient {
String exportedRegistry = PreGeneratedFileRegistry.exportRegistry(fileRegistry);
configCurator.putData(getZooKeeperAppPath(null).append(ZKApplicationPackage.fileRegistryNode).getAbsolute(),
- vespaVersion.toFullString(),
- exportedRegistry);
+ vespaVersion.toFullString(),
+ exportedRegistry);
}
/**
@@ -343,9 +324,8 @@ public class ZooKeeperClient {
}
public void write(AllocatedHosts hosts) throws IOException {
- configCurator.putData(
- rootPath.append(ZKApplicationPackage.allocatedHostsNode).getAbsolute(),
- AllocatedHostsSerializer.toJson(hosts));
+ configCurator.putData(rootPath.append(ZKApplicationPackage.allocatedHostsNode).getAbsolute(),
+ AllocatedHostsSerializer.toJson(hosts));
}
public void write(Map<Version, FileRegistry> fileRegistryMap) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplication.java b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplication.java
index 3ae678969eb..5f180bdaee1 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplication.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/zookeeper/ZKApplication.java
@@ -9,14 +9,12 @@ import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Optional;
/**
* Responsible for providing data from an application subtree in zookeeper.
* (i.e. /config/v2/tenants/x/session/&lt;session id for an application&gt;/).
*
- * Takes care of
- *
- *
* @author Tony Vaagenes
*/
public class ZKApplication {
@@ -84,6 +82,10 @@ public class ZKApplication {
return reader(data);
}
+ Optional<Reader> getOptionalDataReader(String path, String node) {
+ return Optional.ofNullable(getData(path, node)).map(data -> reader(data));
+ }
+
public String getData(String path, String node) {
try {
return zk.getData(getFullPath(path), node);
@@ -181,10 +183,9 @@ public class ZKApplication {
}
Reader getDataReader(String path) {
- final String data = getData(path);
- if (data == null) {
+ String data = getData(path);
+ if (data == null)
throw new IllegalArgumentException("No node for " + getFullPath(path) + " exists");
- }
return reader(data);
}
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 bcb958c4b58..c7ec2657996 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
@@ -139,13 +139,16 @@ public class ZKApplicationPackage implements ApplicationPackage {
@Override
public List<NamedReader> searchDefinitionContents() {
- List<NamedReader> ret = new ArrayList<>();
- for (String sd : zkApplication.getChildren(ConfigCurator.USERAPP_ZK_SUBPATH+"/"+SEARCH_DEFINITIONS_DIR)) {
- if (sd.endsWith(ApplicationPackage.SD_NAME_SUFFIX)) {
- ret.add(new NamedReader(sd, new StringReader(zkApplication.getData(ConfigCurator.USERAPP_ZK_SUBPATH+"/"+SEARCH_DEFINITIONS_DIR, sd))));
- }
+ List<NamedReader> schemas = new ArrayList<>();
+ for (String sd : zkApplication.getChildren(ConfigCurator.USERAPP_ZK_SUBPATH + "/" + SEARCH_DEFINITIONS_DIR)) {
+ if (sd.endsWith(ApplicationPackage.SD_NAME_SUFFIX))
+ schemas.add(new NamedReader(sd, new StringReader(zkApplication.getData(ConfigCurator.USERAPP_ZK_SUBPATH + "/" + SEARCH_DEFINITIONS_DIR, sd))));
}
- return ret;
+ for (String sd : zkApplication.getChildren(ConfigCurator.USERAPP_ZK_SUBPATH + "/" + SCHEMAS_DIR)) {
+ if (sd.endsWith(ApplicationPackage.SD_NAME_SUFFIX))
+ schemas.add(new NamedReader(sd, new StringReader(zkApplication.getData(ConfigCurator.USERAPP_ZK_SUBPATH + "/" + SCHEMAS_DIR, sd))));
+ }
+ return schemas;
}
@Override
@@ -176,7 +179,7 @@ public class ZKApplicationPackage implements ApplicationPackage {
try {
return zkApplication.getDataReader(ConfigCurator.DEFCONFIGS_ZK_SUBPATH, def);
} catch (IllegalArgumentException e) {
- throw new IllegalArgumentException("Could not retrieve config definition " + def + ".", e);
+ throw new IllegalArgumentException("Could not retrieve config definition " + def, e);
}
}
@@ -264,7 +267,10 @@ public class ZKApplicationPackage implements ApplicationPackage {
@Override
public Reader getRankingExpression(String name) {
- return zkApplication.getDataReader(ConfigCurator.USERAPP_ZK_SUBPATH+"/"+SEARCH_DEFINITIONS_DIR, name);
+ Optional<Reader> reader = zkApplication.getOptionalDataReader(ConfigCurator.USERAPP_ZK_SUBPATH + "/" + SCHEMAS_DIR, name);
+ if (reader.isPresent())
+ return reader.get();
+ return zkApplication.getDataReader(ConfigCurator.USERAPP_ZK_SUBPATH + "/" + SEARCH_DEFINITIONS_DIR, name);
}
@Override
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 14fa0cb2dbe..91d59bbeb4e 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
@@ -170,16 +170,16 @@ public class ZooKeeperClientTest {
@Test
public void search_definitions_written_to_ZK() {
- assertTrue(zk.exists(appPath().append(ApplicationPackage.SEARCH_DEFINITIONS_DIR).append("music.sd").getAbsolute()));
- assertTrue(zk.exists(appPath().append(ApplicationPackage.SEARCH_DEFINITIONS_DIR).append("base.sd").getAbsolute()));
- assertTrue(zk.exists(appPath().append(ApplicationPackage.SEARCH_DEFINITIONS_DIR).append("video.sd").getAbsolute()));
- assertTrue(zk.exists(appPath().append(ApplicationPackage.SEARCH_DEFINITIONS_DIR).append("book.sd").getAbsolute()));
- assertTrue(zk.exists(appPath().append(ApplicationPackage.SEARCH_DEFINITIONS_DIR).append("pc.sd").getAbsolute()));
- assertTrue(zk.exists(appPath().append(ApplicationPackage.SEARCH_DEFINITIONS_DIR).append("laptop.sd").getAbsolute()));
- assertTrue(zk.exists(appPath().append(ApplicationPackage.SEARCH_DEFINITIONS_DIR).append("product.sd").getAbsolute()));
- assertTrue(zk.exists(appPath().append(ApplicationPackage.SEARCH_DEFINITIONS_DIR).append("sock.sd").getAbsolute()));
- assertTrue(zk.exists(appPath().append(ApplicationPackage.SEARCH_DEFINITIONS_DIR).append("foo.expression").getAbsolute()));
- assertTrue(zk.exists(appPath().append(ApplicationPackage.SEARCH_DEFINITIONS_DIR).append("bar.expression").getAbsolute()));
+ assertTrue(zk.exists(appPath().append(ApplicationPackage.SCHEMAS_DIR).append("music.sd").getAbsolute()));
+ assertTrue(zk.exists(appPath().append(ApplicationPackage.SCHEMAS_DIR).append("base.sd").getAbsolute()));
+ assertTrue(zk.exists(appPath().append(ApplicationPackage.SCHEMAS_DIR).append("video.sd").getAbsolute()));
+ assertTrue(zk.exists(appPath().append(ApplicationPackage.SCHEMAS_DIR).append("book.sd").getAbsolute()));
+ assertTrue(zk.exists(appPath().append(ApplicationPackage.SCHEMAS_DIR).append("pc.sd").getAbsolute()));
+ assertTrue(zk.exists(appPath().append(ApplicationPackage.SCHEMAS_DIR).append("laptop.sd").getAbsolute()));
+ assertTrue(zk.exists(appPath().append(ApplicationPackage.SCHEMAS_DIR).append("product.sd").getAbsolute()));
+ assertTrue(zk.exists(appPath().append(ApplicationPackage.SCHEMAS_DIR).append("sock.sd").getAbsolute()));
+ assertTrue(zk.exists(appPath().append(ApplicationPackage.SCHEMAS_DIR).append("foo.expression").getAbsolute()));
+ assertTrue(zk.exists(appPath().append(ApplicationPackage.SCHEMAS_DIR).append("bar.expression").getAbsolute()));
}
private Path appPath() {