You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by sh...@apache.org on 2017/06/21 07:10:41 UTC
[15/50] [abbrv] lucene-solr:feature/autoscaling: SOLR-10882:
ArrayEvaluator now works with all types and allows sorts (deleted
ArraySortEvaluator)
SOLR-10882: ArrayEvaluator now works with all types and allows sorts (deleted ArraySortEvaluator)
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/113459a8
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/113459a8
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/113459a8
Branch: refs/heads/feature/autoscaling
Commit: 113459a840e8ca3482ebd36a76dda551fac885ec
Parents: 5fca6a4
Author: Dennis Gove <dp...@gmail.com>
Authored: Thu Jun 15 22:10:37 2017 -0400
Committer: Dennis Gove <dp...@gmail.com>
Committed: Sun Jun 18 11:50:58 2017 -0400
----------------------------------------------------------------------
.../org/apache/solr/handler/StreamHandler.java | 479 +++++++++----------
.../client/solrj/io/eval/ArrayEvaluator.java | 48 +-
.../solrj/io/eval/ArraySortEvaluator.java | 77 ---
.../client/solrj/io/eval/ComplexEvaluator.java | 18 +-
.../io/stream/eval/ArrayEvaluatorTest.java | 155 ++++++
5 files changed, 452 insertions(+), 325 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/113459a8/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/handler/StreamHandler.java b/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
index 7889bf7..4616204 100644
--- a/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/StreamHandler.java
@@ -77,7 +77,7 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
private StreamFactory streamFactory = new StreamFactory();
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private String coreName;
- private Map<String, DaemonStream> daemons = Collections.synchronizedMap(new HashMap());
+ private Map<String,DaemonStream> daemons = Collections.synchronizedMap(new HashMap());
@Override
public PermissionNameProvider.Name getPermissionName(AuthorizationContext request) {
@@ -89,202 +89,202 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
}
public void inform(SolrCore core) {
-
- /* The stream factory will always contain the zkUrl for the given collection
- * Adds default streams with their corresponding function names. These
- * defaults can be overridden or added to in the solrConfig in the stream
- * RequestHandler def. Example config override
- * <lst name="streamFunctions">
- * <str name="group">org.apache.solr.client.solrj.io.stream.ReducerStream</str>
- * <str name="count">org.apache.solr.client.solrj.io.stream.RecordCountStream</str>
- * </lst>
- * */
+
+ /*
+ * The stream factory will always contain the zkUrl for the given collection Adds default streams with their
+ * corresponding function names. These defaults can be overridden or added to in the solrConfig in the stream
+ * RequestHandler def. Example config override
+ * <lst name="streamFunctions">
+ * <str name="group">org.apache.solr.client.solrj.io.stream.ReducerStream</str>
+ * <str name="count">org.apache.solr.client.solrj.io.stream.RecordCountStream</str>
+ * </lst>
+ */
String defaultCollection;
String defaultZkhost;
CoreContainer coreContainer = core.getCoreContainer();
this.coreName = core.getName();
- if(coreContainer.isZooKeeperAware()) {
+ if (coreContainer.isZooKeeperAware()) {
defaultCollection = core.getCoreDescriptor().getCollectionName();
defaultZkhost = core.getCoreContainer().getZkController().getZkServerAddress();
streamFactory.withCollectionZkHost(defaultCollection, defaultZkhost);
streamFactory.withDefaultZkHost(defaultZkhost);
modelCache = new ModelCache(250,
- defaultZkhost,
- clientCache);
- }
-
- streamFactory
- // source streams
- .withFunctionName("search", CloudSolrStream.class)
- .withFunctionName("facet", FacetStream.class)
- .withFunctionName("update", UpdateStream.class)
- .withFunctionName("jdbc", JDBCStream.class)
- .withFunctionName("topic", TopicStream.class)
- .withFunctionName("commit", CommitStream.class)
- .withFunctionName("random", RandomStream.class)
- .withFunctionName("knn", KnnStream.class)
-
- // decorator streams
- .withFunctionName("merge", MergeStream.class)
- .withFunctionName("unique", UniqueStream.class)
- .withFunctionName("top", RankStream.class)
- .withFunctionName("group", GroupOperation.class)
- .withFunctionName("reduce", ReducerStream.class)
- .withFunctionName("parallel", ParallelStream.class)
- .withFunctionName("rollup", RollupStream.class)
- .withFunctionName("stats", StatsStream.class)
- .withFunctionName("innerJoin", InnerJoinStream.class)
- .withFunctionName("leftOuterJoin", LeftOuterJoinStream.class)
- .withFunctionName("hashJoin", HashJoinStream.class)
- .withFunctionName("outerHashJoin", OuterHashJoinStream.class)
- .withFunctionName("intersect", IntersectStream.class)
- .withFunctionName("complement", ComplementStream.class)
- .withFunctionName(SORT, SortStream.class)
- .withFunctionName("train", TextLogitStream.class)
- .withFunctionName("features", FeaturesSelectionStream.class)
- .withFunctionName("daemon", DaemonStream.class)
- .withFunctionName("shortestPath", ShortestPathStream.class)
- .withFunctionName("gatherNodes", GatherNodesStream.class)
- .withFunctionName("nodes", GatherNodesStream.class)
- .withFunctionName("select", SelectStream.class)
- .withFunctionName("shortestPath", ShortestPathStream.class)
- .withFunctionName("gatherNodes", GatherNodesStream.class)
- .withFunctionName("nodes", GatherNodesStream.class)
- .withFunctionName("scoreNodes", ScoreNodesStream.class)
- .withFunctionName("model", ModelStream.class)
- .withFunctionName("classify", ClassifyStream.class)
- .withFunctionName("fetch", FetchStream.class)
- .withFunctionName("executor", ExecutorStream.class)
- .withFunctionName("null", NullStream.class)
- .withFunctionName("priority", PriorityStream.class)
- .withFunctionName("significantTerms", SignificantTermsStream.class)
- .withFunctionName("cartesianProduct", CartesianProductStream.class)
- .withFunctionName("shuffle", ShuffleStream.class)
- .withFunctionName("calc", CalculatorStream.class)
- .withFunctionName("eval",EvalStream.class)
- .withFunctionName("echo", EchoStream.class)
- .withFunctionName("cell", CellStream.class)
- .withFunctionName("list", ListStream.class)
- .withFunctionName("let", LetStream.class)
- .withFunctionName("get", GetStream.class)
- .withFunctionName("timeseries", TimeSeriesStream.class)
- .withFunctionName("tuple", TupStream.class)
- .withFunctionName("sql", SqlStream.class)
- .withFunctionName("col", ColumnEvaluator.class)
- .withFunctionName("predict", PredictEvaluator.class)
- .withFunctionName("regress", RegressionEvaluator.class)
- .withFunctionName("cov", CovarianceEvaluator.class)
- .withFunctionName("conv", ConvolutionEvaluator.class)
- .withFunctionName("normalize", NormalizeEvaluator.class)
- .withFunctionName("rev", ReverseEvaluator.class)
- .withFunctionName("length", LengthEvaluator.class)
- .withFunctionName("rank", RankEvaluator.class)
- .withFunctionName("scale", ScaleEvaluator.class)
- .withFunctionName("distance", DistanceEvaluator.class)
- .withFunctionName("copyOf", CopyOfEvaluator.class)
- .withFunctionName("copyOfRange", CopyOfRangeEvaluator.class)
- .withFunctionName("percentile", PercentileEvaluator.class)
- .withFunctionName("empiricalDistribution", EmpiricalDistributionEvaluator.class)
- .withFunctionName("cumulativeProbability", CumulativeProbabilityEvaluator.class)
- .withFunctionName("describe", DescribeEvaluator.class)
- .withFunctionName("finddelay", FindDelayEvaluator.class)
- .withFunctionName("sequence", SequenceEvaluator.class)
- .withFunctionName("array", ArrayEvaluator.class)
- .withFunctionName("hist", HistogramEvaluator.class)
- .withFunctionName("anova", AnovaEvaluator.class)
- .withFunctionName("movingAvg", MovingAverageEvaluator.class)
- .withFunctionName("arraySort", ArraySortEvaluator.class)
-
- // metrics
- .withFunctionName("min", MinMetric.class)
- .withFunctionName("max", MaxMetric.class)
- .withFunctionName("avg", MeanMetric.class)
- .withFunctionName("sum", SumMetric.class)
- .withFunctionName("count", CountMetric.class)
-
- // tuple manipulation operations
- .withFunctionName("replace", ReplaceOperation.class)
- .withFunctionName("concat", ConcatOperation.class)
-
- // stream reduction operations
- .withFunctionName("group", GroupOperation.class)
- .withFunctionName("distinct", DistinctOperation.class)
- .withFunctionName("having", HavingStream.class)
-
- // Stream Evaluators
- .withFunctionName("val", RawValueEvaluator.class)
-
- // Boolean Stream Evaluators
- .withFunctionName("and", AndEvaluator.class)
- .withFunctionName("eor", ExclusiveOrEvaluator.class)
- .withFunctionName("eq", EqualsEvaluator.class)
- .withFunctionName("gt", GreaterThanEvaluator.class)
- .withFunctionName("gteq", GreaterThanEqualToEvaluator.class)
- .withFunctionName("lt", LessThanEvaluator.class)
- .withFunctionName("lteq", LessThanEqualToEvaluator.class)
- .withFunctionName("not", NotEvaluator.class)
- .withFunctionName("or", OrEvaluator.class)
-
- // Date Time Evaluators
- .withFunctionName(TemporalEvaluatorYear.FUNCTION_NAME, TemporalEvaluatorYear.class)
- .withFunctionName(TemporalEvaluatorMonth.FUNCTION_NAME, TemporalEvaluatorMonth.class)
- .withFunctionName(TemporalEvaluatorDay.FUNCTION_NAME, TemporalEvaluatorDay.class)
- .withFunctionName(TemporalEvaluatorDayOfYear.FUNCTION_NAME, TemporalEvaluatorDayOfYear.class)
- .withFunctionName(TemporalEvaluatorHour.FUNCTION_NAME, TemporalEvaluatorHour.class)
- .withFunctionName(TemporalEvaluatorMinute.FUNCTION_NAME, TemporalEvaluatorMinute.class)
- .withFunctionName(TemporalEvaluatorSecond.FUNCTION_NAME, TemporalEvaluatorSecond.class)
- .withFunctionName(TemporalEvaluatorEpoch.FUNCTION_NAME, TemporalEvaluatorEpoch.class)
- .withFunctionName(TemporalEvaluatorWeek.FUNCTION_NAME, TemporalEvaluatorWeek.class)
- .withFunctionName(TemporalEvaluatorQuarter.FUNCTION_NAME, TemporalEvaluatorQuarter.class)
- .withFunctionName(TemporalEvaluatorDayOfQuarter.FUNCTION_NAME, TemporalEvaluatorDayOfQuarter.class)
-
- // Number Stream Evaluators
- .withFunctionName("abs", AbsoluteValueEvaluator.class)
- .withFunctionName("add", AddEvaluator.class)
- .withFunctionName("div", DivideEvaluator.class)
- .withFunctionName("mult", MultiplyEvaluator.class)
- .withFunctionName("sub", SubtractEvaluator.class)
- .withFunctionName("log", NaturalLogEvaluator.class)
- .withFunctionName("pow", PowerEvaluator.class)
- .withFunctionName("mod", ModuloEvaluator.class)
- .withFunctionName("ceil", CeilingEvaluator.class)
- .withFunctionName("floor", FloorEvaluator.class)
- .withFunctionName("sin", SineEvaluator.class)
- .withFunctionName("asin", ArcSineEvaluator.class)
- .withFunctionName("sinh", HyperbolicSineEvaluator.class)
- .withFunctionName("cos", CosineEvaluator.class)
- .withFunctionName("acos", ArcCosineEvaluator.class)
- .withFunctionName("cosh", HyperbolicCosineEvaluator.class)
- .withFunctionName("tan", TangentEvaluator.class)
- .withFunctionName("atan", ArcTangentEvaluator.class)
- .withFunctionName("tanh", HyperbolicTangentEvaluator.class)
- .withFunctionName("round", RoundEvaluator.class)
- .withFunctionName("sqrt", SquareRootEvaluator.class)
- .withFunctionName("cbrt", CubedRootEvaluator.class)
- .withFunctionName("coalesce", CoalesceEvaluator.class)
- .withFunctionName("uuid", UuidEvaluator.class)
- .withFunctionName("corr", CorrelationEvaluator.class)
-
-
- // Conditional Stream Evaluators
- .withFunctionName("if", IfThenElseEvaluator.class)
- .withFunctionName("analyze", AnalyzeEvaluator.class)
- .withFunctionName("convert", ConversionEvaluator.class)
- ;
-
- // This pulls all the overrides and additions from the config
- List<PluginInfo> pluginInfos = core.getSolrConfig().getPluginInfos(Expressible.class.getName());
- for (PluginInfo pluginInfo : pluginInfos) {
- Class<? extends Expressible> clazz = core.getMemClassLoader().findClass(pluginInfo.className, Expressible.class);
- streamFactory.withFunctionName(pluginInfo.name, clazz);
- }
+ defaultZkhost,
+ clientCache);
+ }
+
+ streamFactory
+ // source streams
+ .withFunctionName("search", CloudSolrStream.class)
+ .withFunctionName("facet", FacetStream.class)
+ .withFunctionName("update", UpdateStream.class)
+ .withFunctionName("jdbc", JDBCStream.class)
+ .withFunctionName("topic", TopicStream.class)
+ .withFunctionName("commit", CommitStream.class)
+ .withFunctionName("random", RandomStream.class)
+ .withFunctionName("knn", KnnStream.class)
+
+ // decorator streams
+ .withFunctionName("merge", MergeStream.class)
+ .withFunctionName("unique", UniqueStream.class)
+ .withFunctionName("top", RankStream.class)
+ .withFunctionName("group", GroupOperation.class)
+ .withFunctionName("reduce", ReducerStream.class)
+ .withFunctionName("parallel", ParallelStream.class)
+ .withFunctionName("rollup", RollupStream.class)
+ .withFunctionName("stats", StatsStream.class)
+ .withFunctionName("innerJoin", InnerJoinStream.class)
+ .withFunctionName("leftOuterJoin", LeftOuterJoinStream.class)
+ .withFunctionName("hashJoin", HashJoinStream.class)
+ .withFunctionName("outerHashJoin", OuterHashJoinStream.class)
+ .withFunctionName("intersect", IntersectStream.class)
+ .withFunctionName("complement", ComplementStream.class)
+ .withFunctionName(SORT, SortStream.class)
+ .withFunctionName("train", TextLogitStream.class)
+ .withFunctionName("features", FeaturesSelectionStream.class)
+ .withFunctionName("daemon", DaemonStream.class)
+ .withFunctionName("shortestPath", ShortestPathStream.class)
+ .withFunctionName("gatherNodes", GatherNodesStream.class)
+ .withFunctionName("nodes", GatherNodesStream.class)
+ .withFunctionName("select", SelectStream.class)
+ .withFunctionName("shortestPath", ShortestPathStream.class)
+ .withFunctionName("gatherNodes", GatherNodesStream.class)
+ .withFunctionName("nodes", GatherNodesStream.class)
+ .withFunctionName("scoreNodes", ScoreNodesStream.class)
+ .withFunctionName("model", ModelStream.class)
+ .withFunctionName("classify", ClassifyStream.class)
+ .withFunctionName("fetch", FetchStream.class)
+ .withFunctionName("executor", ExecutorStream.class)
+ .withFunctionName("null", NullStream.class)
+ .withFunctionName("priority", PriorityStream.class)
+ .withFunctionName("significantTerms", SignificantTermsStream.class)
+ .withFunctionName("cartesianProduct", CartesianProductStream.class)
+ .withFunctionName("shuffle", ShuffleStream.class)
+ .withFunctionName("calc", CalculatorStream.class)
+ .withFunctionName("eval", EvalStream.class)
+ .withFunctionName("echo", EchoStream.class)
+ .withFunctionName("cell", CellStream.class)
+ .withFunctionName("list", ListStream.class)
+ .withFunctionName("let", LetStream.class)
+ .withFunctionName("get", GetStream.class)
+ .withFunctionName("timeseries", TimeSeriesStream.class)
+ .withFunctionName("tuple", TupStream.class)
+ .withFunctionName("sql", SqlStream.class)
+
+ // metrics
+ .withFunctionName("min", MinMetric.class)
+ .withFunctionName("max", MaxMetric.class)
+ .withFunctionName("avg", MeanMetric.class)
+ .withFunctionName("sum", SumMetric.class)
+ .withFunctionName("count", CountMetric.class)
+
+ // tuple manipulation operations
+ .withFunctionName("replace", ReplaceOperation.class)
+ .withFunctionName("concat", ConcatOperation.class)
+
+ // stream reduction operations
+ .withFunctionName("group", GroupOperation.class)
+ .withFunctionName("distinct", DistinctOperation.class)
+ .withFunctionName("having", HavingStream.class)
+
+ // Stream Evaluators
+ .withFunctionName("val", RawValueEvaluator.class)
+
+ // New Evaluators
+ .withFunctionName("anova", AnovaEvaluator.class)
+ .withFunctionName("array", ArrayEvaluator.class)
+ .withFunctionName("col", ColumnEvaluator.class)
+ .withFunctionName("conv", ConvolutionEvaluator.class)
+ .withFunctionName("copyOf", CopyOfEvaluator.class)
+ .withFunctionName("copyOfRange", CopyOfRangeEvaluator.class)
+ .withFunctionName("cov", CovarianceEvaluator.class)
+ .withFunctionName("cumulativeProbability", CumulativeProbabilityEvaluator.class)
+ .withFunctionName("describe", DescribeEvaluator.class)
+ .withFunctionName("distance", DistanceEvaluator.class)
+ .withFunctionName("empiricalDistribution", EmpiricalDistributionEvaluator.class)
+ .withFunctionName("finddelay", FindDelayEvaluator.class)
+ .withFunctionName("hist", HistogramEvaluator.class)
+ .withFunctionName("length", LengthEvaluator.class)
+ .withFunctionName("movingAvg", MovingAverageEvaluator.class)
+ .withFunctionName("normalize", NormalizeEvaluator.class)
+ .withFunctionName("percentile", PercentileEvaluator.class)
+ .withFunctionName("predict", PredictEvaluator.class)
+ .withFunctionName("rank", RankEvaluator.class)
+ .withFunctionName("regress", RegressionEvaluator.class)
+ .withFunctionName("rev", ReverseEvaluator.class)
+ .withFunctionName("scale", ScaleEvaluator.class)
+ .withFunctionName("sequence", SequenceEvaluator.class)
+
+ // Boolean Stream Evaluators
+ .withFunctionName("and", AndEvaluator.class)
+ .withFunctionName("eor", ExclusiveOrEvaluator.class)
+ .withFunctionName("eq", EqualsEvaluator.class)
+ .withFunctionName("gt", GreaterThanEvaluator.class)
+ .withFunctionName("gteq", GreaterThanEqualToEvaluator.class)
+ .withFunctionName("lt", LessThanEvaluator.class)
+ .withFunctionName("lteq", LessThanEqualToEvaluator.class)
+ .withFunctionName("not", NotEvaluator.class)
+ .withFunctionName("or", OrEvaluator.class)
+
+ // Date Time Evaluators
+ .withFunctionName(TemporalEvaluatorYear.FUNCTION_NAME, TemporalEvaluatorYear.class)
+ .withFunctionName(TemporalEvaluatorMonth.FUNCTION_NAME, TemporalEvaluatorMonth.class)
+ .withFunctionName(TemporalEvaluatorDay.FUNCTION_NAME, TemporalEvaluatorDay.class)
+ .withFunctionName(TemporalEvaluatorDayOfYear.FUNCTION_NAME, TemporalEvaluatorDayOfYear.class)
+ .withFunctionName(TemporalEvaluatorHour.FUNCTION_NAME, TemporalEvaluatorHour.class)
+ .withFunctionName(TemporalEvaluatorMinute.FUNCTION_NAME, TemporalEvaluatorMinute.class)
+ .withFunctionName(TemporalEvaluatorSecond.FUNCTION_NAME, TemporalEvaluatorSecond.class)
+ .withFunctionName(TemporalEvaluatorEpoch.FUNCTION_NAME, TemporalEvaluatorEpoch.class)
+ .withFunctionName(TemporalEvaluatorWeek.FUNCTION_NAME, TemporalEvaluatorWeek.class)
+ .withFunctionName(TemporalEvaluatorQuarter.FUNCTION_NAME, TemporalEvaluatorQuarter.class)
+ .withFunctionName(TemporalEvaluatorDayOfQuarter.FUNCTION_NAME, TemporalEvaluatorDayOfQuarter.class)
+
+ // Number Stream Evaluators
+ .withFunctionName("abs", AbsoluteValueEvaluator.class)
+ .withFunctionName("add", AddEvaluator.class)
+ .withFunctionName("div", DivideEvaluator.class)
+ .withFunctionName("mult", MultiplyEvaluator.class)
+ .withFunctionName("sub", SubtractEvaluator.class)
+ .withFunctionName("log", NaturalLogEvaluator.class)
+ .withFunctionName("pow", PowerEvaluator.class)
+ .withFunctionName("mod", ModuloEvaluator.class)
+ .withFunctionName("ceil", CeilingEvaluator.class)
+ .withFunctionName("floor", FloorEvaluator.class)
+ .withFunctionName("sin", SineEvaluator.class)
+ .withFunctionName("asin", ArcSineEvaluator.class)
+ .withFunctionName("sinh", HyperbolicSineEvaluator.class)
+ .withFunctionName("cos", CosineEvaluator.class)
+ .withFunctionName("acos", ArcCosineEvaluator.class)
+ .withFunctionName("cosh", HyperbolicCosineEvaluator.class)
+ .withFunctionName("tan", TangentEvaluator.class)
+ .withFunctionName("atan", ArcTangentEvaluator.class)
+ .withFunctionName("tanh", HyperbolicTangentEvaluator.class)
+ .withFunctionName("round", RoundEvaluator.class)
+ .withFunctionName("sqrt", SquareRootEvaluator.class)
+ .withFunctionName("cbrt", CubedRootEvaluator.class)
+ .withFunctionName("coalesce", CoalesceEvaluator.class)
+ .withFunctionName("uuid", UuidEvaluator.class)
+ .withFunctionName("corr", CorrelationEvaluator.class)
+
+ // Conditional Stream Evaluators
+ .withFunctionName("if", IfThenElseEvaluator.class)
+ .withFunctionName("analyze", AnalyzeEvaluator.class)
+ .withFunctionName("convert", ConversionEvaluator.class);
+
+ // This pulls all the overrides and additions from the config
+ List<PluginInfo> pluginInfos = core.getSolrConfig().getPluginInfos(Expressible.class.getName());
+ for (PluginInfo pluginInfo : pluginInfos) {
+ Class<? extends Expressible> clazz = core.getMemClassLoader().findClass(pluginInfo.className, Expressible.class);
+ streamFactory.withFunctionName(pluginInfo.name, clazz);
+ }
+
core.addCloseHook(new CloseHook() {
@Override
public void preClose(SolrCore core) {
- //To change body of implemented methods use File | Settings | File Templates.
+ // To change body of implemented methods use File | Settings | File Templates.
}
@Override
@@ -299,7 +299,7 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
params = adjustParams(params);
req.setParams(params);
- if(params.get("action") != null) {
+ if (params.get("action") != null) {
handleAdmin(req, rsp, params);
return;
}
@@ -308,7 +308,7 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
try {
StreamExpression streamExpression = StreamExpressionParser.parse(params.get("expr"));
- if(this.streamFactory.isEvaluator(streamExpression)) {
+ if (this.streamFactory.isEvaluator(streamExpression)) {
StreamExpression tupleExpression = new StreamExpression("tuple");
tupleExpression.addParameter(new StreamExpressionNamedParameter("return-value", streamExpression));
tupleStream = this.streamFactory.constructStream(tupleExpression);
@@ -316,7 +316,8 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
tupleStream = this.streamFactory.constructStream(streamExpression);
}
} catch (Exception e) {
- //Catch exceptions that occur while the stream is being created. This will include streaming expression parse rules.
+ // Catch exceptions that occur while the stream is being created. This will include streaming expression parse
+ // rules.
SolrException.log(logger, e);
rsp.add("result-set", new DummyErrorStream(e));
@@ -334,21 +335,21 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
context.put("core", this.coreName);
context.put("solr-core", req.getCore());
tupleStream.setStreamContext(context);
-
+
// if asking for explanation then go get it
- if(params.getBool("explain", false)){
+ if (params.getBool("explain", false)) {
rsp.add("explanation", tupleStream.toExplanation(this.streamFactory));
}
-
- if(tupleStream instanceof DaemonStream) {
- DaemonStream daemonStream = (DaemonStream)tupleStream;
- if(daemons.containsKey(daemonStream.getId())) {
+
+ if (tupleStream instanceof DaemonStream) {
+ DaemonStream daemonStream = (DaemonStream) tupleStream;
+ if (daemons.containsKey(daemonStream.getId())) {
daemons.remove(daemonStream.getId()).close();
}
daemonStream.setDaemons(daemons);
- daemonStream.open(); //This will start the deamonStream
+ daemonStream.open(); // This will start the deamonStream
daemons.put(daemonStream.getId(), daemonStream);
- rsp.add("result-set", new DaemonResponseStream("Deamon:"+daemonStream.getId()+" started on "+coreName));
+ rsp.add("result-set", new DaemonResponseStream("Deamon:" + daemonStream.getId() + " started on " + coreName));
} else {
rsp.add("result-set", new TimerStream(new ExceptionStream(tupleStream)));
}
@@ -356,10 +357,10 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
private void handleAdmin(SolrQueryRequest req, SolrQueryResponse rsp, SolrParams params) {
String action = params.get("action");
- if("stop".equalsIgnoreCase(action)) {
+ if ("stop".equalsIgnoreCase(action)) {
String id = params.get(ID);
DaemonStream d = daemons.get(id);
- if(d != null) {
+ if (d != null) {
d.close();
rsp.add("result-set", new DaemonResponseStream("Deamon:" + id + " stopped on " + coreName));
} else {
@@ -400,50 +401,46 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
return null;
}
-
public static class DummyErrorStream extends TupleStream {
private Exception e;
public DummyErrorStream(Exception e) {
this.e = e;
}
+
public StreamComparator getStreamSort() {
return null;
}
- public void close() {
- }
+ public void close() {}
- public void open() {
- }
+ public void open() {}
- public void setStreamContext(StreamContext context) {
- }
+ public void setStreamContext(StreamContext context) {}
public List<TupleStream> children() {
return null;
}
-
+
@Override
public Explanation toExplanation(StreamFactory factory) throws IOException {
return new StreamExplanation(getStreamNodeId().toString())
- .withFunctionName("error")
- .withImplementingClass(this.getClass().getName())
- .withExpressionType(ExpressionType.STREAM_DECORATOR)
- .withExpression("--non-expressible--");
+ .withFunctionName("error")
+ .withImplementingClass(this.getClass().getName())
+ .withExpressionType(ExpressionType.STREAM_DECORATOR)
+ .withExpression("--non-expressible--");
}
public Tuple read() {
String msg = e.getMessage();
Throwable t = e.getCause();
- while(t != null) {
+ while (t != null) {
msg = t.getMessage();
t = t.getCause();
}
-
Map m = new HashMap();
m.put("EOF", true);
m.put("EXCEPTION", msg);
@@ -457,18 +454,16 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
public DaemonCollectionStream(Collection<DaemonStream> col) {
this.it = col.iterator();
}
+
public StreamComparator getStreamSort() {
return null;
}
- public void close() {
- }
+ public void close() {}
- public void open() {
- }
+ public void open() {}
- public void setStreamContext(StreamContext context) {
- }
+ public void setStreamContext(StreamContext context) {}
public List<TupleStream> children() {
return null;
@@ -478,14 +473,14 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
public Explanation toExplanation(StreamFactory factory) throws IOException {
return new StreamExplanation(getStreamNodeId().toString())
- .withFunctionName("daemon-collection")
- .withImplementingClass(this.getClass().getName())
- .withExpressionType(ExpressionType.STREAM_DECORATOR)
- .withExpression("--non-expressible--");
+ .withFunctionName("daemon-collection")
+ .withImplementingClass(this.getClass().getName())
+ .withExpressionType(ExpressionType.STREAM_DECORATOR)
+ .withExpression("--non-expressible--");
}
-
+
public Tuple read() {
- if(it.hasNext()) {
+ if (it.hasNext()) {
return it.next().getInfo();
} else {
Map m = new HashMap();
@@ -502,18 +497,16 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
public DaemonResponseStream(String message) {
this.message = message;
}
+
public StreamComparator getStreamSort() {
return null;
}
- public void close() {
- }
+ public void close() {}
- public void open() {
- }
+ public void open() {}
- public void setStreamContext(StreamContext context) {
- }
+ public void setStreamContext(StreamContext context) {}
public List<TupleStream> children() {
return null;
@@ -523,10 +516,10 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
public Explanation toExplanation(StreamFactory factory) throws IOException {
return new StreamExplanation(getStreamNodeId().toString())
- .withFunctionName("daemon-response")
- .withImplementingClass(this.getClass().getName())
- .withExpressionType(ExpressionType.STREAM_DECORATOR)
- .withExpression("--non-expressible--");
+ .withFunctionName("daemon-response")
+ .withImplementingClass(this.getClass().getName())
+ .withExpressionType(ExpressionType.STREAM_DECORATOR)
+ .withExpression("--non-expressible--");
}
public Tuple read() {
@@ -537,7 +530,7 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
} else {
sendEOF = true;
Map m = new HashMap();
- m.put("DaemonOp",message);
+ m.put("DaemonOp", message);
return new Tuple(m);
}
}
@@ -577,15 +570,15 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
public Explanation toExplanation(StreamFactory factory) throws IOException {
return new StreamExplanation(getStreamNodeId().toString())
- .withFunctionName("timer")
- .withImplementingClass(this.getClass().getName())
- .withExpressionType(ExpressionType.STREAM_DECORATOR)
- .withExpression("--non-expressible--");
+ .withFunctionName("timer")
+ .withImplementingClass(this.getClass().getName())
+ .withExpressionType(ExpressionType.STREAM_DECORATOR)
+ .withExpression("--non-expressible--");
}
public Tuple read() throws IOException {
Tuple tuple = this.tupleStream.read();
- if(tuple.EOF) {
+ if (tuple.EOF) {
long totalTime = (System.nanoTime() - begin) / 1000000;
tuple.fields.put("RESPONSE_TIME", totalTime);
}
@@ -593,25 +586,25 @@ public class StreamHandler extends RequestHandlerBase implements SolrCoreAware,
}
}
- private Map<String, List<String>> getCollectionShards(SolrParams params) {
+ private Map<String,List<String>> getCollectionShards(SolrParams params) {
- Map<String, List<String>> collectionShards = new HashMap();
+ Map<String,List<String>> collectionShards = new HashMap();
Iterator<String> paramsIt = params.getParameterNamesIterator();
- while(paramsIt.hasNext()) {
+ while (paramsIt.hasNext()) {
String param = paramsIt.next();
- if(param.indexOf(".shards") > -1) {
+ if (param.indexOf(".shards") > -1) {
String collection = param.split("\\.")[0];
String shardString = params.get(param);
String[] shards = shardString.split(",");
List<String> shardList = new ArrayList();
- for(String shard : shards) {
+ for (String shard : shards) {
shardList.add(shard);
}
collectionShards.put(collection, shardList);
}
}
- if(collectionShards.size() > 0) {
+ if (collectionShards.size() > 0) {
return collectionShards;
} else {
return null;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/113459a8/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArrayEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArrayEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArrayEvaluator.java
index ed45ee9..065335b 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArrayEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArrayEvaluator.java
@@ -18,30 +18,72 @@ package org.apache.solr.client.solrj.io.eval;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.List;
+import java.util.Locale;
+import java.util.stream.Collectors;
import org.apache.solr.client.solrj.io.Tuple;
import org.apache.solr.client.solrj.io.stream.expr.Explanation;
import org.apache.solr.client.solrj.io.stream.expr.Explanation.ExpressionType;
import org.apache.solr.client.solrj.io.stream.expr.Expressible;
import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
+import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionNamedParameter;
import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionParameter;
+import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionValue;
import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
+import com.google.common.collect.Lists;
+
public class ArrayEvaluator extends ComplexEvaluator implements Expressible {
private static final long serialVersionUID = 1;
-
+ private String sortOrder;
+
public ArrayEvaluator(StreamExpression expression, StreamFactory factory) throws IOException {
- super(expression, factory);
+ super(expression, factory, Lists.newArrayList("sort"));
+
+ sortOrder = extractSortOrder(expression, factory);
+ }
+
+ private String extractSortOrder(StreamExpression expression, StreamFactory factory) throws IOException{
+ StreamExpressionNamedParameter sortParam = factory.getNamedOperand(expression, "sort");
+ if(null == sortParam){
+ return null; // this is ok
+ }
+
+ if(sortParam.getParameter() instanceof StreamExpressionValue){
+ String sortOrder = ((StreamExpressionValue)sortParam.getParameter()).getValue().trim().toLowerCase(Locale.ROOT);
+ if("asc".equals(sortOrder) || "desc".equals(sortOrder)){
+ return sortOrder;
+ }
+ }
+
+ throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - invalid 'sort' parameter - expecting either 'asc' or 'desc'", expression));
}
public List<Object> evaluate(Tuple tuple) throws IOException {
List<Object> list = new ArrayList<>();
for(StreamEvaluator subEvaluator : subEvaluators) {
- Object value = (Number)subEvaluator.evaluate(tuple);
+ Object value = subEvaluator.evaluate(tuple);
+
+ // if we want sorting but the evaluated value is not comparable then we have an error
+ if(null != sortOrder && !(value instanceof Comparable<?>)){
+ String message = String.format(Locale.ROOT,"Failed to evaluate to a comparable object - evaluator '%s' resulted in type '%s' and value '%s'",
+ subEvaluator.toExpression(constructingFactory),
+ value.getClass().getName(),
+ value.toString());
+ throw new IOException(message);
+ }
+
list.add(value);
}
+
+ if(null != sortOrder){
+ // Because of the type checking above we know that the value is at least Comparable
+ Comparator<Comparable> comparator = "asc".equals(sortOrder) ? (left,right) -> left.compareTo(right) : (left,right) -> right.compareTo(left);
+ list = list.stream().map(value -> (Comparable<Object>)value).sorted(comparator).collect(Collectors.toList());
+ }
return list;
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/113459a8/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArraySortEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArraySortEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArraySortEvaluator.java
deleted file mode 100644
index dabc615..0000000
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ArraySortEvaluator.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.solr.client.solrj.io.eval;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import org.apache.solr.client.solrj.io.Tuple;
-import org.apache.solr.client.solrj.io.stream.expr.Explanation;
-import org.apache.solr.client.solrj.io.stream.expr.Explanation.ExpressionType;
-import org.apache.solr.client.solrj.io.stream.expr.Expressible;
-import org.apache.solr.client.solrj.io.stream.expr.StreamExpression;
-import org.apache.solr.client.solrj.io.stream.expr.StreamExpressionParameter;
-import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
-
-public class ArraySortEvaluator extends ComplexEvaluator implements Expressible {
-
- private static final long serialVersionUID = 1;
-
- public ArraySortEvaluator(StreamExpression expression, StreamFactory factory) throws IOException {
- super(expression, factory);
- }
-
- public List<Number> evaluate(Tuple tuple) throws IOException {
-
- if(subEvaluators.size() != 1) {
- throw new IOException("Array sort evaluator expects 1 parameters found: "+subEvaluators.size());
- }
-
- StreamEvaluator colEval1 = subEvaluators.get(0);
-
- List<Number> numbers1 = (List<Number>)colEval1.evaluate(tuple);
- List<Number> numbers2 = new ArrayList();
- numbers2.addAll(numbers1);
- Collections.sort(numbers2, new Comparator<Number>() {
- @Override
- public int compare(Number o1, Number o2) {
- Double d1 = o1.doubleValue();
- Double d2 = o2.doubleValue();
- return d1.compareTo(d2);
- }
- });
- return numbers2;
- }
-
- @Override
- public StreamExpressionParameter toExpression(StreamFactory factory) throws IOException {
- StreamExpression expression = new StreamExpression(factory.getFunctionName(getClass()));
- return expression;
- }
-
- @Override
- public Explanation toExplanation(StreamFactory factory) throws IOException {
- return new Explanation(nodeId.toString())
- .withExpressionType(ExpressionType.EVALUATOR)
- .withFunctionName(factory.getFunctionName(getClass()))
- .withImplementingClass(getClass().getName())
- .withExpression(toExpression(factory).toString());
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/113459a8/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ComplexEvaluator.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ComplexEvaluator.java b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ComplexEvaluator.java
index ea4c88c..ca1f0de 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ComplexEvaluator.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/io/eval/ComplexEvaluator.java
@@ -20,7 +20,9 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
+import java.util.Set;
import java.util.UUID;
+import java.util.stream.Collectors;
import org.apache.solr.client.solrj.io.stream.StreamContext;
import org.apache.solr.client.solrj.io.stream.expr.Explanation;
@@ -40,6 +42,10 @@ public abstract class ComplexEvaluator implements StreamEvaluator {
protected List<StreamEvaluator> subEvaluators = new ArrayList<StreamEvaluator>();
public ComplexEvaluator(StreamExpression expression, StreamFactory factory) throws IOException{
+ this(expression, factory, new ArrayList<>());
+ }
+
+ public ComplexEvaluator(StreamExpression expression, StreamFactory factory, List<String> ignoredNamedParameters) throws IOException{
constructingFactory = factory;
// We have to do this because order of the parameters matter
@@ -75,8 +81,16 @@ public abstract class ComplexEvaluator implements StreamEvaluator {
}
}
- if(expression.getParameters().size() != subEvaluators.size()){
- throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - unknown operands found - expecting only StreamEvaluators or field names", expression));
+ Set<String> namedParameters = factory.getNamedOperands(expression).stream().map(param -> param.getName()).collect(Collectors.toSet());
+ long ignorableCount = ignoredNamedParameters.stream().filter(name -> namedParameters.contains(name)).count();
+
+ if(0 != expression.getParameters().size() - subEvaluators.size() - ignorableCount){
+ if(namedParameters.isEmpty()){
+ throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - unknown operands found - expecting only StreamEvaluators or field names", expression));
+ }
+ else{
+ throw new IOException(String.format(Locale.ROOT,"Invalid expression %s - unknown operands found - expecting only StreamEvaluators, field names, or named parameters [%s]", expression, namedParameters.stream().collect(Collectors.joining(","))));
+ }
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/113459a8/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArrayEvaluatorTest.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArrayEvaluatorTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArrayEvaluatorTest.java
new file mode 100644
index 0000000..36e5e78
--- /dev/null
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/io/stream/eval/ArrayEvaluatorTest.java
@@ -0,0 +1,155 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.solr.client.solrj.io.stream.eval;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.solr.client.solrj.io.Tuple;
+import org.apache.solr.client.solrj.io.eval.ArrayEvaluator;
+import org.apache.solr.client.solrj.io.eval.StreamEvaluator;
+import org.apache.solr.client.solrj.io.stream.StreamContext;
+import org.apache.solr.client.solrj.io.stream.expr.StreamFactory;
+import org.junit.Test;
+
+import junit.framework.Assert;
+
+public class ArrayEvaluatorTest extends LuceneTestCase {
+
+ StreamFactory factory;
+ Map<String, Object> values;
+
+ public ArrayEvaluatorTest() {
+ super();
+
+ factory = new StreamFactory()
+ .withFunctionName("array", ArrayEvaluator.class);
+ values = new HashMap<String,Object>();
+ }
+
+ @Test
+ public void arrayLongSortAscTest() throws IOException{
+ StreamEvaluator evaluator = factory.constructEvaluator("array(a,b,c, sort=asc)");
+ StreamContext context = new StreamContext();
+ evaluator.setStreamContext(context);
+ Object result;
+
+ values.put("a", 1L);
+ values.put("b", 3L);
+ values.put("c", 2L);
+
+ result = evaluator.evaluate(new Tuple(values));
+
+ Assert.assertTrue(result instanceof List<?>);
+
+ Assert.assertEquals(3, ((List<?>)result).size());
+ Assert.assertEquals(1L, ((List<?>)result).get(0));
+ Assert.assertEquals(2L, ((List<?>)result).get(1));
+ Assert.assertEquals(3L, ((List<?>)result).get(2));
+ }
+
+ @Test
+ public void arrayLongSortDescTest() throws IOException{
+ StreamEvaluator evaluator = factory.constructEvaluator("array(a,b,c, sort=desc)");
+ StreamContext context = new StreamContext();
+ evaluator.setStreamContext(context);
+ Object result;
+
+ values.put("a", 1L);
+ values.put("b", 3L);
+ values.put("c", 2L);
+
+ result = evaluator.evaluate(new Tuple(values));
+
+ Assert.assertTrue(result instanceof List<?>);
+
+ Assert.assertEquals(3, ((List<?>)result).size());
+ Assert.assertEquals(3L, ((List<?>)result).get(0));
+ Assert.assertEquals(2L, ((List<?>)result).get(1));
+ Assert.assertEquals(1L, ((List<?>)result).get(2));
+ }
+
+ @Test
+ public void arrayStringSortAscTest() throws IOException{
+ StreamEvaluator evaluator = factory.constructEvaluator("array(a,b,c, sort=asc)");
+ StreamContext context = new StreamContext();
+ evaluator.setStreamContext(context);
+ Object result;
+
+ values.put("a", "a");
+ values.put("b", "c");
+ values.put("c", "b");
+
+ result = evaluator.evaluate(new Tuple(values));
+
+ Assert.assertTrue(result instanceof List<?>);
+
+ Assert.assertEquals(3, ((List<?>)result).size());
+ Assert.assertEquals("a", ((List<?>)result).get(0));
+ Assert.assertEquals("b", ((List<?>)result).get(1));
+ Assert.assertEquals("c", ((List<?>)result).get(2));
+ }
+
+ @Test
+ public void arrayStringSortDescTest() throws IOException{
+ StreamEvaluator evaluator = factory.constructEvaluator("array(a,b,c, sort=desc)");
+ StreamContext context = new StreamContext();
+ evaluator.setStreamContext(context);
+ Object result;
+
+ values.put("a", "a");
+ values.put("b", "c");
+ values.put("c", "b");
+
+ result = evaluator.evaluate(new Tuple(values));
+
+ Assert.assertTrue(result instanceof List<?>);
+
+ Assert.assertEquals(3, ((List<?>)result).size());
+ Assert.assertEquals("c", ((List<?>)result).get(0));
+ Assert.assertEquals("b", ((List<?>)result).get(1));
+ Assert.assertEquals("a", ((List<?>)result).get(2));
+ }
+
+ @Test
+ public void arrayStringUnsortedTest() throws IOException{
+ StreamEvaluator evaluator = factory.constructEvaluator("array(a,b,c)");
+ StreamContext context = new StreamContext();
+ evaluator.setStreamContext(context);
+ Object result;
+
+ values.put("a", "a");
+ values.put("b", "c");
+ values.put("c", "b");
+
+ result = evaluator.evaluate(new Tuple(values));
+
+ Assert.assertTrue(result instanceof List<?>);
+
+ Assert.assertEquals(3, ((List<?>)result).size());
+ Assert.assertEquals("a", ((List<?>)result).get(0));
+ Assert.assertEquals("c", ((List<?>)result).get(1));
+ Assert.assertEquals("b", ((List<?>)result).get(2));
+ }
+
+
+
+
+}