diff options
8 files changed, 49 insertions, 91 deletions
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 804c677f9cf..b2a1507b424 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 @@ -617,7 +617,6 @@ public class FilesApplicationPackage implements ApplicationPackage { @Override public Reader getRankingExpression(String name) { try { - File file = expressionFileNameToFile(name); return IOUtils.createReader(expressionFileNameToFile(name), "utf-8"); } catch (IOException e) { diff --git a/config-model/src/test/derived/fieldlength/attributes.cfg b/config-model/src/test/derived/fieldlength/attributes.cfg deleted file mode 100644 index 136fb14eda9..00000000000 --- a/config-model/src/test/derived/fieldlength/attributes.cfg +++ /dev/null @@ -1,3 +0,0 @@ -attribute[].name "year" -attribute[].datatype INT32 -attribute[].collectiontype SINGLE diff --git a/config-model/src/test/derived/fieldlength/fieldlength.sd b/config-model/src/test/derived/fieldlength/fieldlength.sd deleted file mode 100644 index 92606e87114..00000000000 --- a/config-model/src/test/derived/fieldlength/fieldlength.sd +++ /dev/null @@ -1,73 +0,0 @@ -# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -search fieldlength { - - document fieldlength { - - field artist type string { - indexing: summary | index - # index-to: default - } - - field title type string { - indexing: summary | index - # index-to: default - } - - field song type string { - indexing: summary | index - # index-to: all, song - } - - field album type string { - indexing: summary | index - # index-to: all, album, all2 - } - - field composer type string { - indexing: summary | index - # index-to: all, composer, all2 - } - - field label type string { - indexing: summary | index - } - - field year type int { - indexing: summary | attribute - } - - } - - rank-profile default { - first-phase { - expression: classicRank - } - second-phase { - expression: if(3>2,4,2) - rerank-count: 10 - } - rank-features: attribute(baz).out sum(value(3)) - rank-features: classicRank - ignore-default-rank-features - - rank-properties { - foo: "bar, baz" - qux: "quux" - foo: "foobar" - } - - } - - rank-profile static { - first-phase { - expression: attribute - } - second-phase { - expression: file:../rankexpression/rankexpression - } - summary-features: sum(value(1),value(2)) - } - -} - - diff --git a/model-evaluation/src/main/java/ai/vespa/models/handler/ModelsEvaluationHandler.java b/model-evaluation/src/main/java/ai/vespa/models/handler/ModelsEvaluationHandler.java index ea2ce087bd8..4ae96bfd62f 100644 --- a/model-evaluation/src/main/java/ai/vespa/models/handler/ModelsEvaluationHandler.java +++ b/model-evaluation/src/main/java/ai/vespa/models/handler/ModelsEvaluationHandler.java @@ -45,15 +45,13 @@ public class ModelsEvaluationHandler extends ThreadedHttpRequestHandler { Optional<String> modelName = path.segment(2); try { - if ( ! apiName.isPresent() || ! apiName.get().equalsIgnoreCase(API_ROOT)) { + if ( apiName.isEmpty() || ! apiName.get().equalsIgnoreCase(API_ROOT)) throw new IllegalArgumentException("unknown API"); - } - if ( ! version.isPresent() || ! version.get().equalsIgnoreCase(VERSION_V1)) { + if ( version.isEmpty() || ! version.get().equalsIgnoreCase(VERSION_V1)) throw new IllegalArgumentException("unknown API version"); - } - if ( ! modelName.isPresent()) { + if ( modelName.isEmpty()) return listAllModels(request); - } + Model model = modelsEvaluator.requireModel(modelName.get()); Optional<Integer> evalSegment = path.lastIndexOf(EVALUATE); diff --git a/model-integration/src/main/java/ai/vespa/rankingexpression/importer/ImportedModel.java b/model-integration/src/main/java/ai/vespa/rankingexpression/importer/ImportedModel.java index 90529ccdca0..58962d1a5ff 100644 --- a/model-integration/src/main/java/ai/vespa/rankingexpression/importer/ImportedModel.java +++ b/model-integration/src/main/java/ai/vespa/rankingexpression/importer/ImportedModel.java @@ -4,10 +4,16 @@ package ai.vespa.rankingexpression.importer; import com.google.common.collect.ImmutableMap; import ai.vespa.rankingexpression.importer.configmodelview.ImportedMlFunction; import ai.vespa.rankingexpression.importer.configmodelview.ImportedMlModel; +import com.yahoo.config.application.api.ApplicationPackage; +import com.yahoo.io.IOUtils; import com.yahoo.searchlib.rankingexpression.RankingExpression; +import com.yahoo.searchlib.rankingexpression.parser.ParseException; import com.yahoo.tensor.Tensor; import com.yahoo.tensor.TensorType; +import java.io.File; +import java.io.IOException; +import java.io.StringReader; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -115,6 +121,41 @@ public class ImportedModel implements ImportedMlModel { public void expression(String name, RankingExpression expression) { expressions.put(name, expression); } public void function(String name, RankingExpression expression) { functions.put(name, expression); } + public void expression(String name, String expression) { + try { + expression = expression.trim(); + if ( expression.startsWith("file:")) { + String filePath = expression.substring("file:".length()).trim(); + if ( ! filePath.endsWith(ApplicationPackage.RANKEXPRESSION_NAME_SUFFIX)) + filePath = filePath + ApplicationPackage.RANKEXPRESSION_NAME_SUFFIX; + expression = IOUtils.readFile(relativeFile(filePath, "function '" + name + "'")); + } + expression(name, new RankingExpression(expression)); + } + catch (IOException e) { + throw new IllegalArgumentException("Could not read file referenced in '" + name + "'"); + } + catch (ParseException e) { + throw new IllegalArgumentException("Could not parse function '" + name + "'", e); + } + } + + /** + * Returns a reference to the File at a path given relative to the source root of this model + * + * @throws IllegalArgumentException if the path is illegal or non-existent + */ + public File relativeFile(String relativePath, String descriptionOfPath) { + File file = new File(new File(source()).getParent(), relativePath); + if (file.isAbsolute()) + throw new IllegalArgumentException(descriptionOfPath + " uses the absolute file path '" + relativePath + + "'. File paths must be relative to the directory referencing them"); + if ( ! file.exists()) + throw new IllegalArgumentException(descriptionOfPath + " references '" + relativePath + + "', but this file does not exist"); + return file; + } + /** * Returns all the output expressions of this indexed by name. The names consist of one or two parts * separated by dot, where the first part is the signature name diff --git a/model-integration/src/main/javacc/ModelParser.jj b/model-integration/src/main/javacc/ModelParser.jj index 5dde54e88e2..a7822cd1a00 100644 --- a/model-integration/src/main/javacc/ModelParser.jj +++ b/model-integration/src/main/javacc/ModelParser.jj @@ -180,12 +180,7 @@ void function() : ")" lbrace() expression = expression() (<NL>)* <RBRACE> ) { - try { - model.expression(name, new RankingExpression(expression)); - } - catch (com.yahoo.searchlib.rankingexpression.parser.ParseException e) { - throw new IllegalArgumentException("Could not parse function '" + name + "'", e); - } + model.expression(name, expression); } } @@ -280,7 +275,7 @@ Tensor largeConstantBody(String name) : )+ { try { - return JsonFormat.decode(type, IOUtils.readFileBytes(new File(new File(model.source()).getParent(), path))); + return JsonFormat.decode(type, IOUtils.readFileBytes(model.relativeFile(path, "constant '" + name + "'"))); } catch (Exception e) { throw new IllegalArgumentException("Could not read constant '" + name + "'", e); diff --git a/model-integration/src/test/models/vespa/example.model b/model-integration/src/test/models/vespa/example.model index 66d21cfc53f..6d660732db9 100644 --- a/model-integration/src/test/models/vespa/example.model +++ b/model-integration/src/test/models/vespa/example.model @@ -15,7 +15,7 @@ model example { } function foo1() { - expression: reduce(sum(input1 * input2, name) * constant1, max, x) * constant2 + expression: file:test.expression } function foo2() { diff --git a/model-integration/src/test/models/vespa/test.expression b/model-integration/src/test/models/vespa/test.expression new file mode 100644 index 00000000000..5db8a720498 --- /dev/null +++ b/model-integration/src/test/models/vespa/test.expression @@ -0,0 +1 @@ +reduce(sum(input1 * input2, name) * constant1, max, x) * constant2
\ No newline at end of file |