Pārlūkot izejas kodu

Factor expressions scripts out to lang-expression plugin

Robert Muir 10 gadi atpakaļ
vecāks
revīzija
689af1a6d6
51 mainītis faili ar 1042 papildinājumiem un 357 dzēšanām
  1. 0 5
      core/pom.xml
  2. 140 144
      core/src/main/java/org/elasticsearch/ElasticsearchException.java
  3. 1 0
      core/src/main/java/org/elasticsearch/plugins/PluginManager.java
  4. 0 8
      core/src/main/java/org/elasticsearch/script/ScriptModule.java
  5. 2 2
      core/src/main/java/org/elasticsearch/script/ScriptService.java
  6. 2 2
      core/src/main/java/org/elasticsearch/search/aggregations/pipeline/having/BucketSelectorPipelineAggregator.java
  7. 1 0
      core/src/main/resources/org/elasticsearch/plugins/plugin-install.help
  8. 1 0
      core/src/test/java/org/elasticsearch/plugins/PluginManagerIT.java
  9. 3 15
      core/src/test/java/org/elasticsearch/script/CustomScriptContextIT.java
  10. 0 32
      core/src/test/java/org/elasticsearch/script/IndexedScriptIT.java
  11. 0 47
      core/src/test/java/org/elasticsearch/script/OnDiskScriptIT.java
  12. 3 4
      core/src/test/java/org/elasticsearch/script/ScriptModesTests.java
  13. 6 19
      core/src/test/java/org/elasticsearch/script/ScriptServiceTests.java
  14. 1 0
      dev-tools/smoke_test_rc.py
  15. 2 0
      dev-tools/update_lucene.sh
  16. 0 5
      distribution/pom.xml
  17. 0 0
      plugins/lang-expression/licenses/antlr4-runtime-4.5.jar.sha1
  18. 0 0
      plugins/lang-expression/licenses/antlr4-runtime-LICENSE.txt
  19. 0 0
      plugins/lang-expression/licenses/antlr4-runtime-NOTICE.txt
  20. 0 0
      plugins/lang-expression/licenses/asm-5.0.4.jar.sha1
  21. 0 0
      plugins/lang-expression/licenses/asm-LICENSE.txt
  22. 0 0
      plugins/lang-expression/licenses/asm-NOTICE.txt
  23. 0 0
      plugins/lang-expression/licenses/asm-commons-5.0.4.jar.sha1
  24. 0 0
      plugins/lang-expression/licenses/asm-commons-LICENSE.txt
  25. 0 0
      plugins/lang-expression/licenses/asm-commons-NOTICE.txt
  26. 475 0
      plugins/lang-expression/licenses/lucene-LICENSE.txt
  27. 191 0
      plugins/lang-expression/licenses/lucene-NOTICE.txt
  28. 0 0
      plugins/lang-expression/licenses/lucene-expressions-5.4.0-snapshot-1702855.jar.sha1
  29. 41 0
      plugins/lang-expression/pom.xml
  30. 0 0
      plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/CountMethodFunctionValues.java
  31. 0 0
      plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/CountMethodValueSource.java
  32. 0 0
      plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/DateMethodFunctionValues.java
  33. 0 0
      plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/DateMethodValueSource.java
  34. 0 0
      plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/ExpressionExecutableScript.java
  35. 11 13
      plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/ExpressionPlugin.java
  36. 8 8
      plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/ExpressionScriptEngineService.java
  37. 1 1
      plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/ExpressionSearchScript.java
  38. 0 0
      plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/FieldDataFunctionValues.java
  39. 0 0
      plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/FieldDataValueSource.java
  40. 0 0
      plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/ReplaceableConstFunctionValues.java
  41. 0 0
      plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/ReplaceableConstValueSource.java
  42. 19 13
      plugins/lang-expression/src/test/java/org/elasticsearch/script/expression/ExpressionRestIT.java
  43. 1 1
      plugins/lang-expression/src/test/java/org/elasticsearch/script/expression/ExpressionTests.java
  44. 84 0
      plugins/lang-expression/src/test/java/org/elasticsearch/script/expression/IndexedExpressionTests.java
  45. 26 17
      plugins/lang-expression/src/test/java/org/elasticsearch/script/expression/MoreExpressionTests.java
  46. 14 0
      plugins/lang-expression/src/test/resources/rest-api-spec/test/lang_expression/10_basic.yaml
  47. 0 0
      plugins/lang-expression/src/test/resources/rest-api-spec/test/lang_expression/20_search.yaml
  48. 1 5
      plugins/pom.xml
  49. 0 6
      pom.xml
  50. 0 5
      qa/smoke-test-multinode/pom.xml
  51. 8 5
      qa/smoke-test-plugins/pom.xml

+ 0 - 5
core/pom.xml

@@ -86,11 +86,6 @@
             <groupId>org.apache.lucene</groupId>
             <artifactId>lucene-spatial</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.apache.lucene</groupId>
-            <artifactId>lucene-expressions</artifactId>
-            <optional>true</optional>
-        </dependency>
         <dependency>
             <groupId>com.spatial4j</groupId>
             <artifactId>spatial4j</artifactId>

+ 140 - 144
core/src/main/java/org/elasticsearch/ElasticsearchException.java

@@ -464,152 +464,148 @@ public class ElasticsearchException extends RuntimeException implements ToXConte
         // to deserialize the exception coming from another node or from an corruption marker on
         // a corrupted index.
         final Map<Class<? extends ElasticsearchException>, Integer> exceptions = new HashMap<>();
-        exceptions.put(org.elasticsearch.index.snapshots.IndexShardSnapshotFailedException.class, 0);
-        exceptions.put(org.elasticsearch.search.dfs.DfsPhaseExecutionException.class, 1);
-        exceptions.put(org.elasticsearch.common.util.CancellableThreads.ExecutionCancelledException.class, 2);
-        exceptions.put(org.elasticsearch.discovery.MasterNotDiscoveredException.class, 3);
-        exceptions.put(org.elasticsearch.ElasticsearchSecurityException.class, 4);
-        exceptions.put(org.elasticsearch.index.snapshots.IndexShardRestoreException.class, 5);
-        exceptions.put(org.elasticsearch.indices.IndexClosedException.class, 6);
-        exceptions.put(org.elasticsearch.http.BindHttpException.class, 7);
-        exceptions.put(org.elasticsearch.action.search.ReduceSearchPhaseException.class, 8);
-        exceptions.put(org.elasticsearch.node.NodeClosedException.class, 9);
-        exceptions.put(org.elasticsearch.index.engine.SnapshotFailedEngineException.class, 10);
-        exceptions.put(org.elasticsearch.index.shard.ShardNotFoundException.class, 11);
-        exceptions.put(org.elasticsearch.transport.ConnectTransportException.class, 12);
-        exceptions.put(org.elasticsearch.transport.NotSerializableTransportException.class, 13);
-        exceptions.put(org.elasticsearch.transport.ResponseHandlerFailureTransportException.class, 14);
-        exceptions.put(org.elasticsearch.indices.IndexCreationException.class, 15);
-        exceptions.put(org.elasticsearch.index.IndexNotFoundException.class, 16);
-        exceptions.put(org.elasticsearch.cluster.routing.IllegalShardRoutingStateException.class, 17);
-        exceptions.put(org.elasticsearch.action.support.broadcast.BroadcastShardOperationFailedException.class, 18);
-        exceptions.put(org.elasticsearch.ResourceNotFoundException.class, 19);
-        exceptions.put(org.elasticsearch.transport.ActionTransportException.class, 20);
-        exceptions.put(org.elasticsearch.ElasticsearchGenerationException.class, 21);
-        exceptions.put(org.elasticsearch.index.engine.CreateFailedEngineException.class, 22);
-        exceptions.put(org.elasticsearch.index.shard.IndexShardStartedException.class, 23);
-        exceptions.put(org.elasticsearch.search.SearchContextMissingException.class, 24);
-        exceptions.put(org.elasticsearch.script.ScriptException.class, 25);
-        exceptions.put(org.elasticsearch.index.shard.TranslogRecoveryPerformer.BatchOperationException.class, 26);
-        exceptions.put(org.elasticsearch.snapshots.SnapshotCreationException.class, 27);
-        exceptions.put(org.elasticsearch.index.engine.DeleteFailedEngineException.class, 28);
-        exceptions.put(org.elasticsearch.index.engine.DocumentMissingException.class, 29);
-        exceptions.put(org.elasticsearch.snapshots.SnapshotException.class, 30);
-        exceptions.put(org.elasticsearch.indices.InvalidAliasNameException.class, 31);
-        exceptions.put(org.elasticsearch.indices.InvalidIndexNameException.class, 32);
-        exceptions.put(org.elasticsearch.indices.IndexPrimaryShardNotAllocatedException.class, 33);
-        exceptions.put(org.elasticsearch.transport.TransportException.class, 34);
-        exceptions.put(org.elasticsearch.ElasticsearchParseException.class, 35);
-        exceptions.put(org.elasticsearch.search.SearchException.class, 36);
-        exceptions.put(org.elasticsearch.index.mapper.MapperException.class, 37);
-        exceptions.put(org.elasticsearch.indices.InvalidTypeNameException.class, 38);
-        exceptions.put(org.elasticsearch.snapshots.SnapshotRestoreException.class, 39);
-        exceptions.put(org.elasticsearch.common.ParsingException.class, 40);
-        exceptions.put(org.elasticsearch.index.shard.IndexShardClosedException.class, 41);
-        exceptions.put(org.elasticsearch.script.expression.ExpressionScriptCompilationException.class, 42);
-        exceptions.put(org.elasticsearch.indices.recovery.RecoverFilesRecoveryException.class, 43);
-        exceptions.put(org.elasticsearch.index.translog.TruncatedTranslogException.class, 44);
-        exceptions.put(org.elasticsearch.indices.recovery.RecoveryFailedException.class, 45);
-        exceptions.put(org.elasticsearch.index.shard.IndexShardRelocatedException.class, 46);
-        exceptions.put(org.elasticsearch.transport.NodeShouldNotConnectException.class, 47);
-        exceptions.put(org.elasticsearch.indices.IndexTemplateAlreadyExistsException.class, 48);
-        exceptions.put(org.elasticsearch.index.translog.TranslogCorruptedException.class, 49);
-        exceptions.put(org.elasticsearch.cluster.block.ClusterBlockException.class, 50);
-        exceptions.put(org.elasticsearch.search.fetch.FetchPhaseExecutionException.class, 51);
-        exceptions.put(org.elasticsearch.index.IndexShardAlreadyExistsException.class, 52);
-        exceptions.put(org.elasticsearch.index.engine.VersionConflictEngineException.class, 53);
-        exceptions.put(org.elasticsearch.index.engine.EngineException.class, 54);
-        exceptions.put(org.elasticsearch.index.engine.DocumentAlreadyExistsException.class, 55);
-        exceptions.put(org.elasticsearch.action.NoSuchNodeException.class, 56);
-        exceptions.put(org.elasticsearch.common.settings.SettingsException.class, 57);
-        exceptions.put(org.elasticsearch.indices.IndexTemplateMissingException.class, 58);
-        exceptions.put(org.elasticsearch.transport.SendRequestTransportException.class, 59);
-        exceptions.put(org.elasticsearch.common.util.concurrent.EsRejectedExecutionException.class, 60);
-        exceptions.put(org.elasticsearch.common.lucene.Lucene.EarlyTerminationException.class, 61);
-        exceptions.put(org.elasticsearch.cluster.routing.RoutingValidationException.class, 62);
-        exceptions.put(org.elasticsearch.common.io.stream.NotSerializableExceptionWrapper.class, 63);
-        exceptions.put(org.elasticsearch.indices.AliasFilterParsingException.class, 64);
-        exceptions.put(org.elasticsearch.index.engine.DeleteByQueryFailedEngineException.class, 65);
-        exceptions.put(org.elasticsearch.gateway.GatewayException.class, 66);
-        exceptions.put(org.elasticsearch.index.shard.IndexShardNotRecoveringException.class, 67);
-        exceptions.put(org.elasticsearch.http.HttpException.class, 68);
-        exceptions.put(org.elasticsearch.ElasticsearchException.class, 69);
-        exceptions.put(org.elasticsearch.snapshots.SnapshotMissingException.class, 70);
-        exceptions.put(org.elasticsearch.action.PrimaryMissingActionException.class, 71);
-        exceptions.put(org.elasticsearch.action.FailedNodeException.class, 72);
-        exceptions.put(org.elasticsearch.search.SearchParseException.class, 73);
-        exceptions.put(org.elasticsearch.snapshots.ConcurrentSnapshotExecutionException.class, 74);
-        exceptions.put(org.elasticsearch.common.blobstore.BlobStoreException.class, 75);
-        exceptions.put(org.elasticsearch.cluster.IncompatibleClusterStateVersionException.class, 76);
-        exceptions.put(org.elasticsearch.index.engine.RecoveryEngineException.class, 77);
-        exceptions.put(org.elasticsearch.common.util.concurrent.UncategorizedExecutionException.class, 78);
-        exceptions.put(org.elasticsearch.action.TimestampParsingException.class, 79);
-        exceptions.put(org.elasticsearch.action.RoutingMissingException.class, 80);
-        exceptions.put(org.elasticsearch.index.engine.IndexFailedEngineException.class, 81);
-        exceptions.put(org.elasticsearch.index.snapshots.IndexShardRestoreFailedException.class, 82);
-        exceptions.put(org.elasticsearch.repositories.RepositoryException.class, 83);
-        exceptions.put(org.elasticsearch.transport.ReceiveTimeoutTransportException.class, 84);
-        exceptions.put(org.elasticsearch.transport.NodeDisconnectedException.class, 85);
-        exceptions.put(org.elasticsearch.index.AlreadyExpiredException.class, 86);
-        exceptions.put(org.elasticsearch.search.aggregations.AggregationExecutionException.class, 87);
-        exceptions.put(org.elasticsearch.index.mapper.MergeMappingException.class, 88);
-        exceptions.put(org.elasticsearch.indices.InvalidIndexTemplateException.class, 89);
-        exceptions.put(org.elasticsearch.percolator.PercolateException.class, 90);
-        exceptions.put(org.elasticsearch.index.engine.RefreshFailedEngineException.class, 91);
-        exceptions.put(org.elasticsearch.search.aggregations.AggregationInitializationException.class, 92);
-        exceptions.put(org.elasticsearch.indices.recovery.DelayRecoveryException.class, 93);
-        exceptions.put(org.elasticsearch.search.warmer.IndexWarmerMissingException.class, 94);
-        exceptions.put(org.elasticsearch.client.transport.NoNodeAvailableException.class, 95);
-        exceptions.put(org.elasticsearch.script.groovy.GroovyScriptCompilationException.class, 96);
-        exceptions.put(org.elasticsearch.snapshots.InvalidSnapshotNameException.class, 97);
-        exceptions.put(org.elasticsearch.index.shard.IllegalIndexShardStateException.class, 98);
-        exceptions.put(org.elasticsearch.index.snapshots.IndexShardSnapshotException.class, 99);
-        exceptions.put(org.elasticsearch.index.shard.IndexShardNotStartedException.class, 100);
-        exceptions.put(org.elasticsearch.action.search.SearchPhaseExecutionException.class, 101);
-        exceptions.put(org.elasticsearch.transport.ActionNotFoundTransportException.class, 102);
-        exceptions.put(org.elasticsearch.transport.TransportSerializationException.class, 103);
-        exceptions.put(org.elasticsearch.transport.RemoteTransportException.class, 104);
-        exceptions.put(org.elasticsearch.index.engine.EngineCreationFailureException.class, 105);
-        exceptions.put(org.elasticsearch.cluster.routing.RoutingException.class, 106);
-        exceptions.put(org.elasticsearch.index.shard.IndexShardRecoveryException.class, 107);
-        exceptions.put(org.elasticsearch.repositories.RepositoryMissingException.class, 108);
-        exceptions.put(org.elasticsearch.script.expression.ExpressionScriptExecutionException.class, 109);
-        exceptions.put(org.elasticsearch.index.percolator.PercolatorException.class, 110);
-        exceptions.put(org.elasticsearch.index.engine.DocumentSourceMissingException.class, 111);
-        exceptions.put(org.elasticsearch.index.engine.FlushNotAllowedEngineException.class, 112);
-        exceptions.put(org.elasticsearch.common.settings.NoClassSettingsException.class, 113);
-        exceptions.put(org.elasticsearch.transport.BindTransportException.class, 114);
-        exceptions.put(org.elasticsearch.rest.action.admin.indices.alias.delete.AliasesNotFoundException.class, 115);
-        exceptions.put(org.elasticsearch.index.shard.IndexShardRecoveringException.class, 116);
-        exceptions.put(org.elasticsearch.index.translog.TranslogException.class, 117);
-        exceptions.put(org.elasticsearch.cluster.metadata.ProcessClusterEventTimeoutException.class, 118);
-        exceptions.put(org.elasticsearch.action.support.replication.TransportReplicationAction.RetryOnPrimaryException.class, 119);
-        exceptions.put(org.elasticsearch.ElasticsearchTimeoutException.class, 120);
-        exceptions.put(org.elasticsearch.search.query.QueryPhaseExecutionException.class, 121);
-        exceptions.put(org.elasticsearch.repositories.RepositoryVerificationException.class, 122);
-        exceptions.put(org.elasticsearch.search.aggregations.InvalidAggregationPathException.class, 123);
-        exceptions.put(org.elasticsearch.script.groovy.GroovyScriptExecutionException.class, 124);
-        exceptions.put(org.elasticsearch.indices.IndexAlreadyExistsException.class, 125);
-        exceptions.put(org.elasticsearch.script.Script.ScriptParseException.class, 126);
-        exceptions.put(org.elasticsearch.transport.netty.SizeHeaderFrameDecoder.HttpOnTransportException.class, 127);
-        exceptions.put(org.elasticsearch.index.mapper.MapperParsingException.class, 128);
-        exceptions.put(org.elasticsearch.search.SearchContextException.class, 129);
-        exceptions.put(org.elasticsearch.search.builder.SearchSourceBuilderException.class, 130);
-        exceptions.put(org.elasticsearch.index.engine.EngineClosedException.class, 131);
-        exceptions.put(org.elasticsearch.action.NoShardAvailableActionException.class, 132);
-        exceptions.put(org.elasticsearch.action.UnavailableShardsException.class, 133);
-        exceptions.put(org.elasticsearch.index.engine.FlushFailedEngineException.class, 134);
-        exceptions.put(org.elasticsearch.common.breaker.CircuitBreakingException.class, 135);
-        exceptions.put(org.elasticsearch.transport.NodeNotConnectedException.class, 136);
-        exceptions.put(org.elasticsearch.index.mapper.StrictDynamicMappingException.class, 137);
-        exceptions.put(org.elasticsearch.action.support.replication.TransportReplicationAction.RetryOnReplicaException.class, 138);
-        exceptions.put(org.elasticsearch.indices.TypeMissingException.class, 139);
+        exceptions.put(org.elasticsearch.index.snapshots.IndexShardSnapshotFailedException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.search.dfs.DfsPhaseExecutionException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.common.util.CancellableThreads.ExecutionCancelledException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.discovery.MasterNotDiscoveredException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.ElasticsearchSecurityException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.snapshots.IndexShardRestoreException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.indices.IndexClosedException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.http.BindHttpException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.action.search.ReduceSearchPhaseException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.node.NodeClosedException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.SnapshotFailedEngineException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.shard.ShardNotFoundException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.transport.ConnectTransportException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.transport.NotSerializableTransportException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.transport.ResponseHandlerFailureTransportException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.indices.IndexCreationException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.IndexNotFoundException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.cluster.routing.IllegalShardRoutingStateException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.action.support.broadcast.BroadcastShardOperationFailedException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.ResourceNotFoundException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.transport.ActionTransportException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.ElasticsearchGenerationException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.CreateFailedEngineException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.shard.IndexShardStartedException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.search.SearchContextMissingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.script.ScriptException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.shard.TranslogRecoveryPerformer.BatchOperationException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.snapshots.SnapshotCreationException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.DeleteFailedEngineException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.DocumentMissingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.snapshots.SnapshotException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.indices.InvalidAliasNameException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.indices.InvalidIndexNameException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.indices.IndexPrimaryShardNotAllocatedException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.transport.TransportException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.ElasticsearchParseException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.search.SearchException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.mapper.MapperException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.indices.InvalidTypeNameException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.snapshots.SnapshotRestoreException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.common.ParsingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.shard.IndexShardClosedException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.indices.recovery.RecoverFilesRecoveryException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.translog.TruncatedTranslogException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.indices.recovery.RecoveryFailedException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.shard.IndexShardRelocatedException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.transport.NodeShouldNotConnectException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.indices.IndexTemplateAlreadyExistsException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.translog.TranslogCorruptedException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.cluster.block.ClusterBlockException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.search.fetch.FetchPhaseExecutionException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.IndexShardAlreadyExistsException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.VersionConflictEngineException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.EngineException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.DocumentAlreadyExistsException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.action.NoSuchNodeException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.common.settings.SettingsException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.indices.IndexTemplateMissingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.transport.SendRequestTransportException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.common.util.concurrent.EsRejectedExecutionException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.common.lucene.Lucene.EarlyTerminationException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.cluster.routing.RoutingValidationException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.common.io.stream.NotSerializableExceptionWrapper.class, exceptions.size());
+        exceptions.put(org.elasticsearch.indices.AliasFilterParsingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.DeleteByQueryFailedEngineException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.gateway.GatewayException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.shard.IndexShardNotRecoveringException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.http.HttpException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.ElasticsearchException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.snapshots.SnapshotMissingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.action.PrimaryMissingActionException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.action.FailedNodeException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.search.SearchParseException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.snapshots.ConcurrentSnapshotExecutionException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.common.blobstore.BlobStoreException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.cluster.IncompatibleClusterStateVersionException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.RecoveryEngineException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.common.util.concurrent.UncategorizedExecutionException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.action.TimestampParsingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.action.RoutingMissingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.IndexFailedEngineException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.snapshots.IndexShardRestoreFailedException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.repositories.RepositoryException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.transport.ReceiveTimeoutTransportException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.transport.NodeDisconnectedException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.AlreadyExpiredException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.search.aggregations.AggregationExecutionException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.mapper.MergeMappingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.indices.InvalidIndexTemplateException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.percolator.PercolateException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.RefreshFailedEngineException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.search.aggregations.AggregationInitializationException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.indices.recovery.DelayRecoveryException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.search.warmer.IndexWarmerMissingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.client.transport.NoNodeAvailableException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.script.groovy.GroovyScriptCompilationException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.snapshots.InvalidSnapshotNameException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.shard.IllegalIndexShardStateException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.snapshots.IndexShardSnapshotException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.shard.IndexShardNotStartedException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.action.search.SearchPhaseExecutionException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.transport.ActionNotFoundTransportException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.transport.TransportSerializationException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.transport.RemoteTransportException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.EngineCreationFailureException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.cluster.routing.RoutingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.shard.IndexShardRecoveryException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.repositories.RepositoryMissingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.percolator.PercolatorException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.DocumentSourceMissingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.FlushNotAllowedEngineException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.common.settings.NoClassSettingsException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.transport.BindTransportException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.rest.action.admin.indices.alias.delete.AliasesNotFoundException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.shard.IndexShardRecoveringException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.translog.TranslogException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.cluster.metadata.ProcessClusterEventTimeoutException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.action.support.replication.TransportReplicationAction.RetryOnPrimaryException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.ElasticsearchTimeoutException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.search.query.QueryPhaseExecutionException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.repositories.RepositoryVerificationException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.search.aggregations.InvalidAggregationPathException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.script.groovy.GroovyScriptExecutionException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.indices.IndexAlreadyExistsException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.script.Script.ScriptParseException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.transport.netty.SizeHeaderFrameDecoder.HttpOnTransportException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.mapper.MapperParsingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.search.SearchContextException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.search.builder.SearchSourceBuilderException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.EngineClosedException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.action.NoShardAvailableActionException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.action.UnavailableShardsException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.engine.FlushFailedEngineException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.common.breaker.CircuitBreakingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.transport.NodeNotConnectedException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.index.mapper.StrictDynamicMappingException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.action.support.replication.TransportReplicationAction.RetryOnReplicaException.class, exceptions.size());
+        exceptions.put(org.elasticsearch.indices.TypeMissingException.class, exceptions.size());
         // added in 3.x
-        exceptions.put(org.elasticsearch.discovery.Discovery.FailedToCommitClusterStateException.class, 140);
+        exceptions.put(org.elasticsearch.discovery.Discovery.FailedToCommitClusterStateException.class, exceptions.size());
 
-        final int maxOrd = 140;
-        assert exceptions.size() == maxOrd + 1;
-        Constructor<? extends ElasticsearchException>[] idToSupplier = new Constructor[maxOrd + 1];
+        Constructor<? extends ElasticsearchException>[] idToSupplier = new Constructor[exceptions.size()];
         for (Map.Entry<Class<? extends ElasticsearchException>, Integer> e : exceptions.entrySet()) {
             try {
                 Constructor<? extends ElasticsearchException> constructor = e.getKey().getDeclaredConstructor(StreamInput.class);

+ 1 - 0
core/src/main/java/org/elasticsearch/plugins/PluginManager.java

@@ -84,6 +84,7 @@ public class PluginManager {
                     "discovery-azure",
                     "discovery-ec2",
                     "discovery-multicast",
+                    "lang-expression",
                     "lang-javascript",
                     "lang-python",
                     "mapper-murmur3",

+ 0 - 8
core/src/main/java/org/elasticsearch/script/ScriptModule.java

@@ -24,7 +24,6 @@ import org.elasticsearch.common.inject.multibindings.MapBinder;
 import org.elasticsearch.common.inject.multibindings.Multibinder;
 import org.elasticsearch.common.logging.Loggers;
 import org.elasticsearch.common.settings.Settings;
-import org.elasticsearch.script.expression.ExpressionScriptEngineService;
 import org.elasticsearch.script.groovy.GroovyScriptEngineService;
 import org.elasticsearch.script.mustache.MustacheScriptEngineService;
 
@@ -92,13 +91,6 @@ public class ScriptModule extends AbstractModule {
             Loggers.getLogger(ScriptService.class, settings).debug("failed to load mustache", t);
         }
 
-        try {
-            Class.forName("org.apache.lucene.expressions.Expression");
-            multibinder.addBinding().to(ExpressionScriptEngineService.class).asEagerSingleton();
-        } catch (Throwable t) {
-            Loggers.getLogger(ScriptService.class, settings).debug("failed to load lucene expressions", t);
-        }
-
         for (Class<? extends ScriptEngineService> scriptEngine : scriptEngines) {
             multibinder.addBinding().to(scriptEngine).asEagerSingleton();
         }

+ 2 - 2
core/src/main/java/org/elasticsearch/script/ScriptService.java

@@ -58,7 +58,6 @@ import org.elasticsearch.common.xcontent.XContentParser;
 import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.env.Environment;
 import org.elasticsearch.index.query.TemplateQueryParser;
-import org.elasticsearch.script.expression.ExpressionScriptEngineService;
 import org.elasticsearch.script.groovy.GroovyScriptEngineService;
 import org.elasticsearch.search.internal.SearchContext;
 import org.elasticsearch.search.lookup.SearchLookup;
@@ -245,8 +244,9 @@ public class ScriptService extends AbstractComponent implements Closeable {
             throw new ScriptException("scripts of type [" + script.getType() + "], operation [" + scriptContext.getKey() + "] and lang [" + lang + "] are disabled");
         }
 
+        // TODO: fix this through some API or something, thats wrong
         // special exception to prevent expressions from compiling as update or mapping scripts
-        boolean expression = scriptEngineService instanceof ExpressionScriptEngineService;
+        boolean expression = "expression".equals(script.getLang());
         boolean notSupported = scriptContext.getKey().equals(ScriptContext.Standard.UPDATE.getKey()) ||
                                scriptContext.getKey().equals(ScriptContext.Standard.MAPPING.getKey());
         if (expression && notSupported) {

+ 2 - 2
core/src/main/java/org/elasticsearch/search/aggregations/pipeline/having/BucketSelectorPipelineAggregator.java

@@ -26,7 +26,6 @@ import org.elasticsearch.script.CompiledScript;
 import org.elasticsearch.script.ExecutableScript;
 import org.elasticsearch.script.Script;
 import org.elasticsearch.script.ScriptContext;
-import org.elasticsearch.script.expression.ExpressionScriptEngineService;
 import org.elasticsearch.search.aggregations.InternalAggregation;
 import org.elasticsearch.search.aggregations.InternalAggregation.ReduceContext;
 import org.elasticsearch.search.aggregations.InternalAggregation.Type;
@@ -105,7 +104,8 @@ public class BucketSelectorPipelineAggregator extends PipelineAggregator {
             ExecutableScript executableScript = reduceContext.scriptService().executable(compiledScript, vars);
             Object scriptReturnValue = executableScript.run();
             final boolean keepBucket;
-            if (ExpressionScriptEngineService.NAME.equals(script.getLang())) {
+            // TODO: WTF!!!!!
+            if ("expression".equals(script.getLang())) {
                 double scriptDoubleValue = (double) scriptReturnValue;
                 keepBucket = scriptDoubleValue == 1.0;
             } else {

+ 1 - 0
core/src/main/resources/org/elasticsearch/plugins/plugin-install.help

@@ -43,6 +43,7 @@ OFFICIAL PLUGINS
     - discovery-azure
     - discovery-ec2
     - discovery-multicast
+    - lang-expression
     - lang-javascript
     - lang-python
     - mapper-murmur3

+ 1 - 0
core/src/test/java/org/elasticsearch/plugins/PluginManagerIT.java

@@ -592,6 +592,7 @@ public class PluginManagerIT extends ESIntegTestCase {
         PluginManager.checkForOfficialPlugins("analysis-stempel");
         PluginManager.checkForOfficialPlugins("cloud-gce");
         PluginManager.checkForOfficialPlugins("delete-by-query");
+        PluginManager.checkForOfficialPlugins("lang-expression");
         PluginManager.checkForOfficialPlugins("lang-javascript");
         PluginManager.checkForOfficialPlugins("lang-python");
         PluginManager.checkForOfficialPlugins("mapper-murmur3");

+ 3 - 15
core/src/test/java/org/elasticsearch/script/CustomScriptContextIT.java

@@ -23,7 +23,6 @@ import com.google.common.collect.ImmutableSet;
 import org.elasticsearch.common.ContextAndHeaderHolder;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.plugins.Plugin;
-import org.elasticsearch.script.expression.ExpressionScriptEngineService;
 import org.elasticsearch.script.groovy.GroovyScriptEngineService;
 import org.elasticsearch.script.mustache.MustacheScriptEngineService;
 import org.elasticsearch.test.ESIntegTestCase;
@@ -34,9 +33,10 @@ import java.util.Collection;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.notNullValue;
 
+// TODO: this needs to be done with mock engines.
 public class CustomScriptContextIT extends ESIntegTestCase {
 
-    private static final ImmutableSet<String> LANG_SET = ImmutableSet.of(GroovyScriptEngineService.NAME, MustacheScriptEngineService.NAME, ExpressionScriptEngineService.NAME);
+    private static final ImmutableSet<String> LANG_SET = ImmutableSet.of(GroovyScriptEngineService.NAME, MustacheScriptEngineService.NAME);
 
     private static final String PLUGIN_NAME = "testplugin";
 
@@ -70,19 +70,7 @@ public class CustomScriptContextIT extends ESIntegTestCase {
             }
         }
 
-        try {
-            scriptService.compile(new Script("1", ScriptService.ScriptType.INLINE, "expression", null), new ScriptContext.Plugin(
-                    PLUGIN_NAME, "custom_exp_disabled_op"), contextAndHeaders);
-            fail("script compilation should have been rejected");
-        } catch(ScriptException e) {
-            assertThat(e.getMessage(), containsString("scripts of type [inline], operation [" + PLUGIN_NAME + "_custom_exp_disabled_op] and lang [expression] are disabled"));
-        }
-
-        CompiledScript compiledScript = scriptService.compile(new Script("1", ScriptService.ScriptType.INLINE, "expression", null),
-                randomFrom(new ScriptContext[] { ScriptContext.Standard.AGGS, ScriptContext.Standard.SEARCH }), contextAndHeaders);
-        assertThat(compiledScript, notNullValue());
-
-        compiledScript = scriptService.compile(new Script("1", ScriptService.ScriptType.INLINE, "mustache", null),
+        CompiledScript compiledScript = scriptService.compile(new Script("1", ScriptService.ScriptType.INLINE, "mustache", null),
                 new ScriptContext.Plugin(PLUGIN_NAME, "custom_exp_disabled_op"), contextAndHeaders);
         assertThat(compiledScript, notNullValue());
 

+ 0 - 32
core/src/test/java/org/elasticsearch/script/IndexedScriptIT.java

@@ -27,7 +27,6 @@ import org.elasticsearch.action.search.SearchResponse;
 import org.elasticsearch.common.bytes.BytesArray;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.common.unit.TimeValue;
-import org.elasticsearch.script.expression.ExpressionScriptEngineService;
 import org.elasticsearch.script.groovy.GroovyScriptEngineService;
 import org.elasticsearch.search.SearchHit;
 import org.elasticsearch.test.ESIntegTestCase;
@@ -148,35 +147,4 @@ public class IndexedScriptIT extends ESIntegTestCase {
         assertHitCount(searchResponse, 1);
         assertThat(searchResponse.getAggregations().get("test"), notNullValue());
     }
-
-    @Test
-    public void testAllOpsDisabledIndexedScripts() throws IOException {
-        if (randomBoolean()) {
-            client().preparePutIndexedScript(ExpressionScriptEngineService.NAME, "script1", "{\"script\":\"2\"}").get();
-        } else {
-            client().prepareIndex(ScriptService.SCRIPT_INDEX, ExpressionScriptEngineService.NAME, "script1").setSource("{\"script\":\"2\"}").get();
-        }
-        client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}").get();
-        try {
-            client().prepareUpdate("test", "scriptTest", "1")
-                    .setScript(new Script("script1", ScriptService.ScriptType.INDEXED, ExpressionScriptEngineService.NAME, null)).get();
-            fail("update script should have been rejected");
-        } catch(Exception e) {
-            assertThat(e.getMessage(), containsString("failed to execute script"));
-            assertThat(e.getCause().getMessage(), containsString("scripts of type [indexed], operation [update] and lang [expression] are disabled"));
-        }
-        try {
-            String query = "{ \"script_fields\" : { \"test1\" : { \"script_id\" : \"script1\", \"lang\":\"expression\" }}}";
-            client().prepareSearch().setSource(new BytesArray(query)).setIndices("test").setTypes("scriptTest").get();
-            fail("search script should have been rejected");
-        } catch(Exception e) {
-            assertThat(e.toString(), containsString("scripts of type [indexed], operation [search] and lang [expression] are disabled"));
-        }
-        try {
-            String source = "{\"aggs\": {\"test\": { \"terms\" : { \"script_id\":\"script1\", \"script_lang\":\"expression\" } } } }";
-            client().prepareSearch("test").setSource(new BytesArray(source)).get();
-        } catch(Exception e) {
-            assertThat(e.toString(), containsString("scripts of type [indexed], operation [aggs] and lang [expression] are disabled"));
-        }
-    }
 }

+ 0 - 47
core/src/test/java/org/elasticsearch/script/OnDiskScriptIT.java

@@ -71,53 +71,6 @@ public class OnDiskScriptIT extends ESIntegTestCase {
         assertThat((Integer)sh.field("test2").getValue(), equalTo(6));
     }
 
-    @Test
-    public void testOnDiskScriptsSameNameDifferentLang()  throws ExecutionException, InterruptedException {
-        List<IndexRequestBuilder> builders = new ArrayList<>();
-        builders.add(client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}"));
-        builders.add(client().prepareIndex("test", "scriptTest", "2").setSource("{\"theField\":\"foo 2\"}"));
-        builders.add(client().prepareIndex("test", "scriptTest", "3").setSource("{\"theField\":\"foo 3\"}"));
-        builders.add(client().prepareIndex("test", "scriptTest", "4").setSource("{\"theField\":\"foo 4\"}"));
-        builders.add(client().prepareIndex("test", "scriptTest", "5").setSource("{\"theField\":\"bar\"}"));
-        indexRandom(true, builders);
-
-        String query = "{ \"query\" : { \"match_all\": {}} , \"script_fields\" : { \"test1\" : { \"script_file\" : \"script1\" }, \"test2\" : { \"script_file\" : \"script1\", \"lang\":\"expression\"  }}, size:1}";
-        SearchResponse searchResponse = client().prepareSearch().setSource(new BytesArray(query)).setIndices("test").setTypes("scriptTest").get();
-        assertHitCount(searchResponse, 5);
-        assertTrue(searchResponse.getHits().hits().length == 1);
-        SearchHit sh = searchResponse.getHits().getAt(0);
-        assertThat((Integer)sh.field("test1").getValue(), equalTo(2));
-        assertThat((Double)sh.field("test2").getValue(), equalTo(10d));
-    }
-
-    @Test
-    public void testPartiallyDisabledOnDiskScripts() throws ExecutionException, InterruptedException {
-        //test that although aggs are disabled for expression, search scripts work fine
-        List<IndexRequestBuilder> builders = new ArrayList<>();
-        builders.add(client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}"));
-        builders.add(client().prepareIndex("test", "scriptTest", "2").setSource("{\"theField\":\"foo 2\"}"));
-        builders.add(client().prepareIndex("test", "scriptTest", "3").setSource("{\"theField\":\"foo 3\"}"));
-        builders.add(client().prepareIndex("test", "scriptTest", "4").setSource("{\"theField\":\"foo 4\"}"));
-        builders.add(client().prepareIndex("test", "scriptTest", "5").setSource("{\"theField\":\"bar\"}"));
-
-        indexRandom(true, builders);
-
-        String source = "{\"aggs\": {\"test\": { \"terms\" : { \"script_file\":\"script1\", \"lang\": \"expression\" } } } }";
-        try {
-            client().prepareSearch("test").setSource(new BytesArray(source)).get();
-            fail("aggs script should have been rejected");
-        } catch(Exception e) {
-            assertThat(e.toString(), containsString("scripts of type [file], operation [aggs] and lang [expression] are disabled"));
-        }
-
-        String query = "{ \"query\" : { \"match_all\": {}} , \"script_fields\" : { \"test1\" : { \"script_file\" : \"script1\", \"lang\":\"expression\" }}, size:1}";
-        SearchResponse searchResponse = client().prepareSearch().setSource(new BytesArray(query)).setIndices("test").setTypes("scriptTest").get();
-        assertHitCount(searchResponse, 5);
-        assertTrue(searchResponse.getHits().hits().length == 1);
-        SearchHit sh = searchResponse.getHits().getAt(0);
-        assertThat((Double)sh.field("test1").getValue(), equalTo(10d));
-    }
-
     @Test
     public void testAllOpsDisabledOnDiskScripts() {
         //whether we even compile or cache the on disk scripts doesn't change the end result (the returned error)

+ 3 - 4
core/src/test/java/org/elasticsearch/script/ScriptModesTests.java

@@ -24,7 +24,6 @@ import com.google.common.collect.ImmutableSet;
 import org.elasticsearch.common.Nullable;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.script.ScriptService.ScriptType;
-import org.elasticsearch.script.expression.ExpressionScriptEngineService;
 import org.elasticsearch.script.groovy.GroovyScriptEngineService;
 import org.elasticsearch.script.mustache.MustacheScriptEngineService;
 import org.elasticsearch.search.lookup.SearchLookup;
@@ -42,9 +41,10 @@ import java.util.Set;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.notNullValue;
 
+// TODO: this needs to be a base test class, and all scripting engines extend it
 public class ScriptModesTests extends ESTestCase {
 
-    private static final Set<String> ALL_LANGS = ImmutableSet.of(GroovyScriptEngineService.NAME, MustacheScriptEngineService.NAME, ExpressionScriptEngineService.NAME, "custom", "test");
+    private static final Set<String> ALL_LANGS = ImmutableSet.of(GroovyScriptEngineService.NAME, MustacheScriptEngineService.NAME, "custom", "test");
 
     static final String[] ENABLE_VALUES = new String[]{"on", "true", "yes", "1"};
     static final String[] DISABLE_VALUES = new String[]{"off", "false", "no", "0"};
@@ -74,7 +74,6 @@ public class ScriptModesTests extends ESTestCase {
         scriptEngines = buildScriptEnginesByLangMap(ImmutableSet.of(
                 new GroovyScriptEngineService(Settings.EMPTY),
                 new MustacheScriptEngineService(Settings.EMPTY),
-                new ExpressionScriptEngineService(Settings.EMPTY),
                 //add the native engine just to make sure it gets filtered out
                 new NativeScriptEngineService(Settings.EMPTY, Collections.<String, NativeScriptFactory>emptyMap()),
                 new CustomScriptEngineService()));
@@ -95,7 +94,7 @@ public class ScriptModesTests extends ESTestCase {
         if (assertScriptModesNonNull) {
             assertThat(scriptModes, notNullValue());
             //4 is the number of engines (native excluded), custom is counted twice though as it's associated with two different names
-            int numberOfSettings = 5 * ScriptType.values().length * scriptContextRegistry.scriptContexts().size();
+            int numberOfSettings = 4 * ScriptType.values().length * scriptContextRegistry.scriptContexts().size();
             assertThat(scriptModes.scriptModes.size(), equalTo(numberOfSettings));
             if (assertAllSettingsWereChecked) {
                 assertThat(checkedSettings.size(), equalTo(numberOfSettings));

+ 6 - 19
core/src/test/java/org/elasticsearch/script/ScriptServiceTests.java

@@ -26,7 +26,6 @@ import org.elasticsearch.common.io.Streams;
 import org.elasticsearch.common.settings.Settings;
 import org.elasticsearch.env.Environment;
 import org.elasticsearch.script.ScriptService.ScriptType;
-import org.elasticsearch.script.expression.ExpressionScriptEngineService;
 import org.elasticsearch.script.groovy.GroovyScriptEngineService;
 import org.elasticsearch.script.mustache.MustacheScriptEngineService;
 import org.elasticsearch.search.lookup.SearchLookup;
@@ -48,6 +47,7 @@ import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.hamcrest.Matchers.sameInstance;
 
+//TODO: this needs to be a base test class, and all scripting engines extend it
 public class ScriptServiceTests extends ESTestCase {
 
     private ResourceWatcherService resourceWatcherService;
@@ -76,7 +76,7 @@ public class ScriptServiceTests extends ESTestCase {
                 .build();
         resourceWatcherService = new ResourceWatcherService(baseSettings, null);
         scriptEngineServices = ImmutableSet.of(new TestEngineService(), new GroovyScriptEngineService(baseSettings),
-                new ExpressionScriptEngineService(baseSettings), new MustacheScriptEngineService(baseSettings));
+                                               new MustacheScriptEngineService(baseSettings));
         scriptEnginesByLangMap = ScriptModesTests.buildScriptEnginesByLangMap(scriptEngineServices);
         //randomly register custom script contexts
         int randomInt = randomIntBetween(0, 3);
@@ -159,15 +159,15 @@ public class ScriptServiceTests extends ESTestCase {
     public void testScriptsSameNameDifferentLanguage() throws IOException {
         ContextAndHeaderHolder contextAndHeaders = new ContextAndHeaderHolder();
         buildScriptService(Settings.EMPTY);
-        createFileScripts("groovy", "expression");
+        createFileScripts("groovy", "test");
         CompiledScript groovyScript = scriptService.compile(
                 new Script("file_script", ScriptType.FILE, GroovyScriptEngineService.NAME, null), randomFrom(scriptContexts),
                 contextAndHeaders);
         assertThat(groovyScript.lang(), equalTo(GroovyScriptEngineService.NAME));
-        CompiledScript expressionScript = scriptService.compile(new Script("file_script", ScriptType.FILE, ExpressionScriptEngineService.NAME,
+        CompiledScript expressionScript = scriptService.compile(new Script("file_script", ScriptType.FILE, "test",
  null), randomFrom(new ScriptContext[] { ScriptContext.Standard.AGGS,
                 ScriptContext.Standard.SEARCH }), contextAndHeaders);
-        assertThat(expressionScript.lang(), equalTo(ExpressionScriptEngineService.NAME));
+        assertThat(expressionScript.lang(), equalTo("test"));
     }
 
     @Test
@@ -219,20 +219,13 @@ public class ScriptServiceTests extends ESTestCase {
             builder.put("script.inline", ScriptMode.SANDBOX);
         }
         buildScriptService(builder.build());
-        createFileScripts("groovy", "expression", "mustache", "test");
+        createFileScripts("groovy", "mustache", "test");
 
         for (ScriptContext scriptContext : scriptContexts) {
             //groovy is not sandboxed, only file scripts are enabled by default
             assertCompileRejected(GroovyScriptEngineService.NAME, "script", ScriptType.INLINE, scriptContext, contextAndHeaders);
             assertCompileRejected(GroovyScriptEngineService.NAME, "script", ScriptType.INDEXED, scriptContext, contextAndHeaders);
             assertCompileAccepted(GroovyScriptEngineService.NAME, "file_script", ScriptType.FILE, scriptContext, contextAndHeaders);
-            //expression engine is sandboxed, all scripts are enabled by default
-            if (!scriptContext.getKey().equals(ScriptContext.Standard.MAPPING.getKey()) &&
-                    !scriptContext.getKey().equals(ScriptContext.Standard.UPDATE.getKey())) {
-                assertCompileAccepted(ExpressionScriptEngineService.NAME, "script", ScriptType.INLINE, scriptContext, contextAndHeaders);
-                assertCompileAccepted(ExpressionScriptEngineService.NAME, "script", ScriptType.INDEXED, scriptContext, contextAndHeaders);
-                assertCompileAccepted(ExpressionScriptEngineService.NAME, "file_script", ScriptType.FILE, scriptContext, contextAndHeaders);
-            }
             //mustache engine is sandboxed, all scripts are enabled by default
             assertCompileAccepted(MustacheScriptEngineService.NAME, "script", ScriptType.INLINE, scriptContext, contextAndHeaders);
             assertCompileAccepted(MustacheScriptEngineService.NAME, "script", ScriptType.INDEXED, scriptContext, contextAndHeaders);
@@ -335,12 +328,6 @@ public class ScriptServiceTests extends ESTestCase {
                 //Otherwise they are always considered file ones as they can be found in the static cache.
                 String script = scriptType == ScriptType.FILE ? "file_script" : "script";
                 for (ScriptContext scriptContext : this.scriptContexts) {
-                    // skip script contexts that aren't allowed for expressions
-                    if (scriptEngineService instanceof ExpressionScriptEngineService &&
-                            (scriptContext.getKey().equals(ScriptContext.Standard.MAPPING.getKey()) ||
-                             scriptContext.getKey().equals(ScriptContext.Standard.UPDATE.getKey()))) {
-                        continue;
-                    }
                     //fallback mechanism: 1) engine specific settings 2) op based settings 3) source based settings
                     ScriptMode scriptMode = engineSettings.get(scriptEngineService.types()[0] + "." + scriptType + "." + scriptContext.getKey());
                     if (scriptMode == null) {

+ 1 - 0
dev-tools/smoke_test_rc.py

@@ -67,6 +67,7 @@ DEFAULT_PLUGINS = ["analysis-icu",
                    "discovery-azure",
                    "discovery-ec2",
                    "discovery-multicast",
+                   "lang-expression",
                    "lang-javascript",
                    "lang-python",
                    "mapper-murmur3",

+ 2 - 0
dev-tools/update_lucene.sh

@@ -12,3 +12,5 @@ perl dev-tools/src/main/resources/license-check/check_license_and_sha.pl \
      --update plugins/analysis-smartcn/licenses/ plugins/analysis-smartcn/target/releases/analysis-smartcn-3.0.0-SNAPSHOT.zip analysis-smartcn-3.0.0-SNAPSHOT
 perl dev-tools/src/main/resources/license-check/check_license_and_sha.pl \
      --update plugins/analysis-stempel/licenses/ plugins/analysis-stempel/target/releases/analysis-stempel-3.0.0-SNAPSHOT.zip analysis-stempel-3.0.0-SNAPSHOT
+perl dev-tools/src/main/resources/license-check/check_license_and_sha.pl \
+     --update plugins/lang-expression/licenses/ plugins/lang-expression/target/releases/lang-expression-3.0.0-SNAPSHOT.zip lang-expression-3.0.0-SNAPSHOT

+ 0 - 5
distribution/pom.xml

@@ -76,11 +76,6 @@
             <artifactId>elasticsearch</artifactId>
         </dependency>
 
-        <dependency>
-            <groupId>org.apache.lucene</groupId>
-            <artifactId>lucene-expressions</artifactId>
-        </dependency>
-
         <dependency>
             <groupId>com.spatial4j</groupId>
             <artifactId>spatial4j</artifactId>

+ 0 - 0
distribution/licenses/antlr4-runtime-4.5.jar.sha1 → plugins/lang-expression/licenses/antlr4-runtime-4.5.jar.sha1


+ 0 - 0
distribution/licenses/antlr4-runtime-LICENSE.txt → plugins/lang-expression/licenses/antlr4-runtime-LICENSE.txt


+ 0 - 0
distribution/licenses/antlr4-runtime-NOTICE.txt → plugins/lang-expression/licenses/antlr4-runtime-NOTICE.txt


+ 0 - 0
distribution/licenses/asm-5.0.4.jar.sha1 → plugins/lang-expression/licenses/asm-5.0.4.jar.sha1


+ 0 - 0
distribution/licenses/asm-LICENSE.txt → plugins/lang-expression/licenses/asm-LICENSE.txt


+ 0 - 0
distribution/licenses/asm-NOTICE.txt → plugins/lang-expression/licenses/asm-NOTICE.txt


+ 0 - 0
distribution/licenses/asm-commons-5.0.4.jar.sha1 → plugins/lang-expression/licenses/asm-commons-5.0.4.jar.sha1


+ 0 - 0
distribution/licenses/asm-commons-LICENSE.txt → plugins/lang-expression/licenses/asm-commons-LICENSE.txt


+ 0 - 0
distribution/licenses/asm-commons-NOTICE.txt → plugins/lang-expression/licenses/asm-commons-NOTICE.txt


+ 475 - 0
plugins/lang-expression/licenses/lucene-LICENSE.txt

@@ -0,0 +1,475 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
+
+
+
+Some code in core/src/java/org/apache/lucene/util/UnicodeUtil.java was
+derived from unicode conversion examples available at
+http://www.unicode.org/Public/PROGRAMS/CVTUTF.  Here is the copyright
+from those sources:
+
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ * 
+ * Disclaimer
+ * 
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ * 
+ * Limitations on Rights to Redistribute This Code
+ * 
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+
+Some code in core/src/java/org/apache/lucene/util/ArrayUtil.java was
+derived from Python 2.4.2 sources available at
+http://www.python.org. Full license is here:
+
+  http://www.python.org/download/releases/2.4.2/license/
+
+Some code in core/src/java/org/apache/lucene/util/UnicodeUtil.java was
+derived from Python 3.1.2 sources available at
+http://www.python.org. Full license is here:
+
+  http://www.python.org/download/releases/3.1.2/license/
+
+Some code in core/src/java/org/apache/lucene/util/automaton was
+derived from Brics automaton sources available at
+www.brics.dk/automaton/. Here is the copyright from those sources:
+
+/*
+ * Copyright (c) 2001-2009 Anders Moeller
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+ 
+The levenshtein automata tables in core/src/java/org/apache/lucene/util/automaton 
+were automatically generated with the moman/finenight FSA package.
+Here is the copyright for those sources:
+
+# Copyright (c) 2010, Jean-Philippe Barrette-LaPierre, <jpb@rrette.com>
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation
+# files (the "Software"), to deal in the Software without
+# restriction, including without limitation the rights to use,
+# copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following
+# conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+Some code in core/src/java/org/apache/lucene/util/UnicodeUtil.java was
+derived from ICU (http://www.icu-project.org)
+The full license is available here: 
+  http://source.icu-project.org/repos/icu/icu/trunk/license.html
+
+/*
+ * Copyright (C) 1999-2010, International Business Machines
+ * Corporation and others.  All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy 
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights 
+ * to use, copy, modify, merge, publish, distribute, and/or sell copies of the 
+ * Software, and to permit persons to whom the Software is furnished to do so, 
+ * provided that the above copyright notice(s) and this permission notice appear 
+ * in all copies of the Software and that both the above copyright notice(s) and
+ * this permission notice appear in supporting documentation.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE 
+ * LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR 
+ * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 
+ * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Except as contained in this notice, the name of a copyright holder shall not 
+ * be used in advertising or otherwise to promote the sale, use or other 
+ * dealings in this Software without prior written authorization of the 
+ * copyright holder.
+ */
+ 
+The following license applies to the Snowball stemmers:
+
+Copyright (c) 2001, Dr Martin Porter
+Copyright (c) 2002, Richard Boulton
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+    * this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+    * notice, this list of conditions and the following disclaimer in the
+    * documentation and/or other materials provided with the distribution.
+    * Neither the name of the copyright holders nor the names of its contributors
+    * may be used to endorse or promote products derived from this software
+    * without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The following license applies to the KStemmer:
+
+Copyright © 2003,
+Center for Intelligent Information Retrieval,
+University of Massachusetts, Amherst.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+3. The names "Center for Intelligent Information Retrieval" and
+"University of Massachusetts" must not be used to endorse or promote products
+derived from this software without prior written permission. To obtain
+permission, contact info@ciir.cs.umass.edu.
+
+THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF MASSACHUSETTS AND OTHER CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+The following license applies to the Morfologik project:
+
+Copyright (c) 2006 Dawid Weiss
+Copyright (c) 2007-2011 Dawid Weiss, Marcin Miłkowski
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, 
+    this list of conditions and the following disclaimer.
+    
+    * Redistributions in binary form must reproduce the above copyright notice, 
+    this list of conditions and the following disclaimer in the documentation 
+    and/or other materials provided with the distribution.
+    
+    * Neither the name of Morfologik nor the names of its contributors 
+    may be used to endorse or promote products derived from this software 
+    without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+---
+
+The dictionary comes from Morfologik project. Morfologik uses data from 
+Polish ispell/myspell dictionary hosted at http://www.sjp.pl/slownik/en/ and 
+is licenced on the terms of (inter alia) LGPL and Creative Commons 
+ShareAlike. The part-of-speech tags were added in Morfologik project and
+are not found in the data from sjp.pl. The tagset is similar to IPI PAN
+tagset.
+
+---
+
+The following license applies to the Morfeusz project,
+used by org.apache.lucene.analysis.morfologik.
+
+BSD-licensed dictionary of Polish (SGJP)
+http://sgjp.pl/morfeusz/
+
+Copyright © 2011 Zygmunt Saloni, Włodzimierz Gruszczyński, 
+             Marcin Woliński, Robert Wołosz
+
+All rights reserved.
+
+Redistribution and  use in  source and binary  forms, with  or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the
+   distribution.
+
+THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS “AS IS” AND ANY EXPRESS
+OR  IMPLIED WARRANTIES,  INCLUDING, BUT  NOT LIMITED  TO,  THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED.  IN NO EVENT  SHALL COPYRIGHT  HOLDERS OR  CONTRIBUTORS BE
+LIABLE FOR  ANY DIRECT,  INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES  (INCLUDING, BUT NOT LIMITED  TO, PROCUREMENT OF
+SUBSTITUTE  GOODS OR  SERVICES;  LOSS  OF USE,  DATA,  OR PROFITS;  OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED  AND ON ANY THEORY OF LIABILITY,
+WHETHER IN  CONTRACT, STRICT LIABILITY, OR  TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 191 - 0
plugins/lang-expression/licenses/lucene-NOTICE.txt

@@ -0,0 +1,191 @@
+Apache Lucene
+Copyright 2014 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+Includes software from other Apache Software Foundation projects,
+including, but not limited to:
+ - Apache Ant
+ - Apache Jakarta Regexp
+ - Apache Commons
+ - Apache Xerces
+
+ICU4J, (under analysis/icu) is licensed under an MIT styles license
+and Copyright (c) 1995-2008 International Business Machines Corporation and others
+
+Some data files (under analysis/icu/src/data) are derived from Unicode data such
+as the Unicode Character Database. See http://unicode.org/copyright.html for more
+details.
+
+Brics Automaton (under core/src/java/org/apache/lucene/util/automaton) is 
+BSD-licensed, created by Anders Møller. See http://www.brics.dk/automaton/
+
+The levenshtein automata tables (under core/src/java/org/apache/lucene/util/automaton) were
+automatically generated with the moman/finenight FSA library, created by
+Jean-Philippe Barrette-LaPierre. This library is available under an MIT license,
+see http://sites.google.com/site/rrettesite/moman and 
+http://bitbucket.org/jpbarrette/moman/overview/
+
+The class org.apache.lucene.util.WeakIdentityMap was derived from
+the Apache CXF project and is Apache License 2.0.
+
+The Google Code Prettify is Apache License 2.0.
+See http://code.google.com/p/google-code-prettify/
+
+JUnit (junit-4.10) is licensed under the Common Public License v. 1.0
+See http://junit.sourceforge.net/cpl-v10.html
+
+This product includes code (JaspellTernarySearchTrie) from Java Spelling Checkin
+g Package (jaspell): http://jaspell.sourceforge.net/
+License: The BSD License (http://www.opensource.org/licenses/bsd-license.php)
+
+The snowball stemmers in
+  analysis/common/src/java/net/sf/snowball
+were developed by Martin Porter and Richard Boulton.
+The snowball stopword lists in
+  analysis/common/src/resources/org/apache/lucene/analysis/snowball
+were developed by Martin Porter and Richard Boulton.
+The full snowball package is available from
+  http://snowball.tartarus.org/
+
+The KStem stemmer in
+  analysis/common/src/org/apache/lucene/analysis/en
+was developed by Bob Krovetz and Sergio Guzman-Lara (CIIR-UMass Amherst)
+under the BSD-license.
+
+The Arabic,Persian,Romanian,Bulgarian, and Hindi analyzers (common) come with a default
+stopword list that is BSD-licensed created by Jacques Savoy.  These files reside in:
+analysis/common/src/resources/org/apache/lucene/analysis/ar/stopwords.txt,
+analysis/common/src/resources/org/apache/lucene/analysis/fa/stopwords.txt,
+analysis/common/src/resources/org/apache/lucene/analysis/ro/stopwords.txt,
+analysis/common/src/resources/org/apache/lucene/analysis/bg/stopwords.txt,
+analysis/common/src/resources/org/apache/lucene/analysis/hi/stopwords.txt
+See http://members.unine.ch/jacques.savoy/clef/index.html.
+
+The German,Spanish,Finnish,French,Hungarian,Italian,Portuguese,Russian and Swedish light stemmers
+(common) are based on BSD-licensed reference implementations created by Jacques Savoy and
+Ljiljana Dolamic. These files reside in:
+analysis/common/src/java/org/apache/lucene/analysis/de/GermanLightStemmer.java
+analysis/common/src/java/org/apache/lucene/analysis/de/GermanMinimalStemmer.java
+analysis/common/src/java/org/apache/lucene/analysis/es/SpanishLightStemmer.java
+analysis/common/src/java/org/apache/lucene/analysis/fi/FinnishLightStemmer.java
+analysis/common/src/java/org/apache/lucene/analysis/fr/FrenchLightStemmer.java
+analysis/common/src/java/org/apache/lucene/analysis/fr/FrenchMinimalStemmer.java
+analysis/common/src/java/org/apache/lucene/analysis/hu/HungarianLightStemmer.java
+analysis/common/src/java/org/apache/lucene/analysis/it/ItalianLightStemmer.java
+analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseLightStemmer.java
+analysis/common/src/java/org/apache/lucene/analysis/ru/RussianLightStemmer.java
+analysis/common/src/java/org/apache/lucene/analysis/sv/SwedishLightStemmer.java
+
+The Stempel analyzer (stempel) includes BSD-licensed software developed 
+by the Egothor project http://egothor.sf.net/, created by Leo Galambos, Martin Kvapil,
+and Edmond Nolan.
+
+The Polish analyzer (stempel) comes with a default
+stopword list that is BSD-licensed created by the Carrot2 project. The file resides
+in stempel/src/resources/org/apache/lucene/analysis/pl/stopwords.txt.
+See http://project.carrot2.org/license.html.
+
+The SmartChineseAnalyzer source code (smartcn) was
+provided by Xiaoping Gao and copyright 2009 by www.imdict.net.
+
+WordBreakTestUnicode_*.java (under modules/analysis/common/src/test/) 
+is derived from Unicode data such as the Unicode Character Database. 
+See http://unicode.org/copyright.html for more details.
+
+The Morfologik analyzer (morfologik) includes BSD-licensed software
+developed by Dawid Weiss and Marcin Miłkowski (http://morfologik.blogspot.com/).
+
+Morfologik uses data from Polish ispell/myspell dictionary
+(http://www.sjp.pl/slownik/en/) licenced on the terms of (inter alia)
+LGPL and Creative Commons ShareAlike.
+
+Morfologic includes data from BSD-licensed dictionary of Polish (SGJP)
+(http://sgjp.pl/morfeusz/)
+
+Servlet-api.jar and javax.servlet-*.jar are under the CDDL license, the original
+source code for this can be found at http://www.eclipse.org/jetty/downloads.php
+
+===========================================================================
+Kuromoji Japanese Morphological Analyzer - Apache Lucene Integration
+===========================================================================
+
+This software includes a binary and/or source version of data from
+
+  mecab-ipadic-2.7.0-20070801
+
+which can be obtained from
+
+  http://atilika.com/releases/mecab-ipadic/mecab-ipadic-2.7.0-20070801.tar.gz
+
+or
+
+  http://jaist.dl.sourceforge.net/project/mecab/mecab-ipadic/2.7.0-20070801/mecab-ipadic-2.7.0-20070801.tar.gz
+
+===========================================================================
+mecab-ipadic-2.7.0-20070801 Notice
+===========================================================================
+
+Nara Institute of Science and Technology (NAIST),
+the copyright holders, disclaims all warranties with regard to this
+software, including all implied warranties of merchantability and
+fitness, in no event shall NAIST be liable for
+any special, indirect or consequential damages or any damages
+whatsoever resulting from loss of use, data or profits, whether in an
+action of contract, negligence or other tortuous action, arising out
+of or in connection with the use or performance of this software.
+
+A large portion of the dictionary entries
+originate from ICOT Free Software.  The following conditions for ICOT
+Free Software applies to the current dictionary as well.
+
+Each User may also freely distribute the Program, whether in its
+original form or modified, to any third party or parties, PROVIDED
+that the provisions of Section 3 ("NO WARRANTY") will ALWAYS appear
+on, or be attached to, the Program, which is distributed substantially
+in the same form as set out herein and that such intended
+distribution, if actually made, will neither violate or otherwise
+contravene any of the laws and regulations of the countries having
+jurisdiction over the User or the intended distribution itself.
+
+NO WARRANTY
+
+The program was produced on an experimental basis in the course of the
+research and development conducted during the project and is provided
+to users as so produced on an experimental basis.  Accordingly, the
+program is provided without any warranty whatsoever, whether express,
+implied, statutory or otherwise.  The term "warranty" used herein
+includes, but is not limited to, any warranty of the quality,
+performance, merchantability and fitness for a particular purpose of
+the program and the nonexistence of any infringement or violation of
+any right of any third party.
+
+Each user of the program will agree and understand, and be deemed to
+have agreed and understood, that there is no warranty whatsoever for
+the program and, accordingly, the entire risk arising from or
+otherwise connected with the program is assumed by the user.
+
+Therefore, neither ICOT, the copyright holder, or any other
+organization that participated in or was otherwise related to the
+development of the program and their respective officials, directors,
+officers and other employees shall be held liable for any and all
+damages, including, without limitation, general, special, incidental
+and consequential damages, arising out of or otherwise in connection
+with the use or inability to use the program or any product, material
+or result produced or otherwise obtained by using the program,
+regardless of whether they have been advised of, or otherwise had
+knowledge of, the possibility of such damages at any time during the
+project or thereafter.  Each user will be deemed to have agreed to the
+foregoing by his or her commencement of use of the program.  The term
+"use" as used herein includes, but is not limited to, the use,
+modification, copying and distribution of the program and the
+production of secondary products from the program.
+
+In the case where the program, whether in its original form or
+modified, was distributed or delivered to or received by a user from
+any person, organization or entity other than ICOT, unless it makes or
+grants independently of ICOT any specific warranty to the user in
+writing, such person, organization or entity, will also be exempted
+from and not be held liable to the user for any such damages as noted
+above as far as the program is concerned.

+ 0 - 0
distribution/licenses/lucene-expressions-5.4.0-snapshot-1702855.jar.sha1 → plugins/lang-expression/licenses/lucene-expressions-5.4.0-snapshot-1702855.jar.sha1


+ 41 - 0
plugins/lang-expression/pom.xml

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.elasticsearch.plugin</groupId>
+        <artifactId>plugins</artifactId>
+        <version>3.0.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>lang-expression</artifactId>
+    <name>Plugin: Language: Expression</name>
+    <description>Lucene expressions integration for Elasticsearch</description>
+
+    <properties>
+        <elasticsearch.plugin.classname>org.elasticsearch.script.expression.ExpressionPlugin</elasticsearch.plugin.classname>
+        <tests.rest.suite>lang_expression</tests.rest.suite>
+        <tests.rest.load_packaged>false</tests.rest.load_packaged>
+        <xlint.options>-Xlint:-rawtypes,-serial</xlint.options>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.lucene</groupId>
+            <artifactId>lucene-expressions</artifactId>
+            <version>${lucene.maven.version}</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 0 - 0
core/src/main/java/org/elasticsearch/script/expression/CountMethodFunctionValues.java → plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/CountMethodFunctionValues.java


+ 0 - 0
core/src/main/java/org/elasticsearch/script/expression/CountMethodValueSource.java → plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/CountMethodValueSource.java


+ 0 - 0
core/src/main/java/org/elasticsearch/script/expression/DateMethodFunctionValues.java → plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/DateMethodFunctionValues.java


+ 0 - 0
core/src/main/java/org/elasticsearch/script/expression/DateMethodValueSource.java → plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/DateMethodValueSource.java


+ 0 - 0
core/src/main/java/org/elasticsearch/script/expression/ExpressionExecutableScript.java → plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/ExpressionExecutableScript.java


+ 11 - 13
core/src/main/java/org/elasticsearch/script/expression/ExpressionScriptExecutionException.java → plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/ExpressionPlugin.java

@@ -19,24 +19,22 @@
 
 package org.elasticsearch.script.expression;
 
-import org.elasticsearch.ElasticsearchException;
-import org.elasticsearch.common.io.stream.StreamInput;
+import org.elasticsearch.plugins.Plugin;
+import org.elasticsearch.script.ScriptModule;
 
-import java.io.IOException;
+public class ExpressionPlugin extends Plugin {
 
-/**
- * Exception used to wrap exceptions occuring while running expressions.
- */
-public class ExpressionScriptExecutionException extends ElasticsearchException {
-    public ExpressionScriptExecutionException(String msg, Throwable cause) {
-        super(msg, cause);
+    @Override
+    public String name() {
+        return "lang-expression";
     }
 
-    public ExpressionScriptExecutionException(StreamInput in) throws IOException {
-        super(in);
+    @Override
+    public String description() {
+        return "Lucene expressions integration for Elasticsearch";
     }
 
-    public ExpressionScriptExecutionException(String msg) {
-        super(msg);
+    public void onModule(ScriptModule module) {
+        module.addScriptEngine(ExpressionScriptEngineService.class);
     }
 }

+ 8 - 8
core/src/main/java/org/elasticsearch/script/expression/ExpressionScriptEngineService.java → plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/ExpressionScriptEngineService.java

@@ -95,7 +95,7 @@ public class ExpressionScriptEngineService extends AbstractComponent implements
             // NOTE: validation is delayed to allow runtime vars, and we don't have access to per index stuff here
             return JavascriptCompiler.compile(script);
         } catch (ParseException e) {
-            throw new ExpressionScriptCompilationException("Failed to parse expression: " + script, e);
+            throw new ScriptException("Failed to parse expression: " + script, e);
         }
     }
 
@@ -127,7 +127,7 @@ public class ExpressionScriptEngineService extends AbstractComponent implements
                     if (value instanceof Number) {
                         bindings.add(variable, new DoubleConstValueSource(((Number) value).doubleValue()));
                     } else {
-                        throw new ExpressionScriptCompilationException("Parameter [" + variable + "] must be a numeric type");
+                        throw new ScriptException("Parameter [" + variable + "] must be a numeric type");
                     }
 
                 } else {
@@ -135,10 +135,10 @@ public class ExpressionScriptEngineService extends AbstractComponent implements
                     String methodname = null;
                     VariableContext[] parts = VariableContext.parse(variable);
                     if (parts[0].text.equals("doc") == false) {
-                        throw new ExpressionScriptCompilationException("Unknown variable [" + parts[0].text + "] in expression");
+                        throw new ScriptException("Unknown variable [" + parts[0].text + "] in expression");
                     }
                     if (parts.length < 2 || parts[1].type != VariableContext.Type.STR_INDEX) {
-                        throw new ExpressionScriptCompilationException("Variable 'doc' in expression must be used with a specific field like: doc['myfield']");
+                        throw new ScriptException("Variable 'doc' in expression must be used with a specific field like: doc['myfield']");
                     } else {
                         fieldname = parts[1].text;
                     }
@@ -146,21 +146,21 @@ public class ExpressionScriptEngineService extends AbstractComponent implements
                         if (parts[2].type == VariableContext.Type.METHOD) {
                             methodname = parts[2].text;
                         } else if (parts[2].type != VariableContext.Type.MEMBER || !"value".equals(parts[2].text)) {
-                            throw new ExpressionScriptCompilationException("Only the member variable [value] or member methods may be accessed on a field when not accessing the field directly");
+                            throw new ScriptException("Only the member variable [value] or member methods may be accessed on a field when not accessing the field directly");
                         }
                     }
                     if (parts.length > 3) {
-                        throw new ExpressionScriptCompilationException("Variable [" + variable + "] does not follow an allowed format of either doc['field'] or doc['field'].method()");
+                        throw new ScriptException("Variable [" + variable + "] does not follow an allowed format of either doc['field'] or doc['field'].method()");
                     }
 
                     MappedFieldType fieldType = mapper.smartNameFieldType(fieldname);
 
                     if (fieldType == null) {
-                        throw new ExpressionScriptCompilationException("Field [" + fieldname + "] used in expression does not exist in mappings");
+                        throw new ScriptException("Field [" + fieldname + "] used in expression does not exist in mappings");
                     }
                     if (fieldType.isNumeric() == false) {
                         // TODO: more context (which expression?)
-                        throw new ExpressionScriptCompilationException("Field [" + fieldname + "] used in expression must be numeric");
+                        throw new ScriptException("Field [" + fieldname + "] used in expression must be numeric");
                     }
 
                     IndexFieldData<?> fieldData = lookup.doc().fieldDataService().getForField((NumberFieldMapper.NumberFieldType) fieldType);

+ 1 - 1
core/src/main/java/org/elasticsearch/script/expression/ExpressionSearchScript.java → plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/ExpressionSearchScript.java

@@ -122,7 +122,7 @@ class ExpressionSearchScript implements SearchScript {
                 if (value instanceof Number) {
                     specialValue.setValue(((Number)value).doubleValue());
                 } else {
-                    throw new ExpressionScriptExecutionException("Cannot use expression with text variable using " + compiledScript);
+                    throw new ScriptException("Cannot use expression with text variable using " + compiledScript);
                 }
             }
         };

+ 0 - 0
core/src/main/java/org/elasticsearch/script/expression/FieldDataFunctionValues.java → plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/FieldDataFunctionValues.java


+ 0 - 0
core/src/main/java/org/elasticsearch/script/expression/FieldDataValueSource.java → plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/FieldDataValueSource.java


+ 0 - 0
core/src/main/java/org/elasticsearch/script/expression/ReplaceableConstFunctionValues.java → plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/ReplaceableConstFunctionValues.java


+ 0 - 0
core/src/main/java/org/elasticsearch/script/expression/ReplaceableConstValueSource.java → plugins/lang-expression/src/main/java/org/elasticsearch/script/expression/ReplaceableConstValueSource.java


+ 19 - 13
core/src/main/java/org/elasticsearch/script/expression/ExpressionScriptCompilationException.java → plugins/lang-expression/src/test/java/org/elasticsearch/script/expression/ExpressionRestIT.java

@@ -19,24 +19,30 @@
 
 package org.elasticsearch.script.expression;
 
-import org.elasticsearch.ElasticsearchException;
-import org.elasticsearch.common.io.stream.StreamInput;
+import com.carrotsearch.randomizedtesting.annotations.Name;
+import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
+import org.elasticsearch.plugins.Plugin;
+import org.elasticsearch.test.rest.ESRestTestCase;
+import org.elasticsearch.test.rest.RestTestCandidate;
+import org.elasticsearch.test.rest.parser.RestTestParseException;
 
 import java.io.IOException;
-import java.text.ParseException;
+import java.util.Collection;
 
-/**
- * Exception representing a compilation error in an expression.
- */
-public class ExpressionScriptCompilationException extends ElasticsearchException {
-    public ExpressionScriptCompilationException(String msg, ParseException e) {
-        super(msg, e);
+public class ExpressionRestIT extends ESRestTestCase {
+
+    @Override
+    protected Collection<Class<? extends Plugin>> nodePlugins() {
+        return pluginList(ExpressionPlugin.class);
     }
-    public ExpressionScriptCompilationException(String msg) {
-        super(msg);
+
+    public ExpressionRestIT(@Name("yaml") RestTestCandidate testCandidate) {
+        super(testCandidate);
     }
 
-    public ExpressionScriptCompilationException(StreamInput in) throws IOException {
-        super(in);
+    @ParametersFactory
+    public static Iterable<Object[]> parameters() throws IOException, RestTestParseException {
+        return ESRestTestCase.createParameters(0, 1);
     }
 }
+

+ 1 - 1
core/src/test/java/org/elasticsearch/script/expression/ExpressionScriptTests.java → plugins/lang-expression/src/test/java/org/elasticsearch/script/expression/ExpressionTests.java

@@ -29,7 +29,7 @@ import org.elasticsearch.test.ESSingleNodeTestCase;
 
 import java.util.Collections;
 
-public class ExpressionScriptTests extends ESSingleNodeTestCase {
+public class ExpressionTests extends ESSingleNodeTestCase {
 
     public void testNeedsScores() {
         IndexService index = createIndex("test", Settings.EMPTY, "type", "d", "type=double");

+ 84 - 0
plugins/lang-expression/src/test/java/org/elasticsearch/script/expression/IndexedExpressionTests.java

@@ -0,0 +1,84 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch 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.elasticsearch.script.expression;
+
+import org.elasticsearch.common.bytes.BytesArray;
+import org.elasticsearch.common.settings.Settings;
+import org.elasticsearch.plugins.Plugin;
+import org.elasticsearch.script.Script;
+import org.elasticsearch.script.ScriptService;
+import org.elasticsearch.test.ESIntegTestCase;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+
+import static org.hamcrest.Matchers.containsString;
+
+//TODO: please convert to unit tests!
+public class IndexedExpressionTests extends ESIntegTestCase {
+    
+    @Override
+    protected Settings nodeSettings(int nodeOrdinal) {
+        Settings.Builder builder = Settings.builder().put(super.nodeSettings(nodeOrdinal));
+        builder.put("script.engine.expression.indexed.update", "off");
+        builder.put("script.engine.expression.indexed.search", "off");
+        builder.put("script.engine.expression.indexed.aggs", "off");
+        builder.put("script.engine.expression.indexed.mapping", "off");
+        return builder.build();
+    }
+    
+    @Override
+    protected Collection<Class<? extends Plugin>> nodePlugins() {
+        return Collections.singleton(ExpressionPlugin.class);
+    }
+
+    @Test
+    public void testAllOpsDisabledIndexedScripts() throws IOException {
+        if (randomBoolean()) {
+            client().preparePutIndexedScript(ExpressionScriptEngineService.NAME, "script1", "{\"script\":\"2\"}").get();
+        } else {
+            client().prepareIndex(ScriptService.SCRIPT_INDEX, ExpressionScriptEngineService.NAME, "script1").setSource("{\"script\":\"2\"}").get();
+        }
+        client().prepareIndex("test", "scriptTest", "1").setSource("{\"theField\":\"foo\"}").get();
+        try {
+            client().prepareUpdate("test", "scriptTest", "1")
+                    .setScript(new Script("script1", ScriptService.ScriptType.INDEXED, ExpressionScriptEngineService.NAME, null)).get();
+            fail("update script should have been rejected");
+        } catch(Exception e) {
+            assertThat(e.getMessage(), containsString("failed to execute script"));
+            assertThat(e.getCause().getMessage(), containsString("scripts of type [indexed], operation [update] and lang [expression] are disabled"));
+        }
+        try {
+            String query = "{ \"script_fields\" : { \"test1\" : { \"script_id\" : \"script1\", \"lang\":\"expression\" }}}";
+            client().prepareSearch().setSource(new BytesArray(query)).setIndices("test").setTypes("scriptTest").get();
+            fail("search script should have been rejected");
+        } catch(Exception e) {
+            assertThat(e.toString(), containsString("scripts of type [indexed], operation [search] and lang [expression] are disabled"));
+        }
+        try {
+            String source = "{\"aggs\": {\"test\": { \"terms\" : { \"script_id\":\"script1\", \"script_lang\":\"expression\" } } } }";
+            client().prepareSearch("test").setSource(new BytesArray(source)).get();
+        } catch(Exception e) {
+            assertThat(e.toString(), containsString("scripts of type [indexed], operation [aggs] and lang [expression] are disabled"));
+        }
+    }
+}

+ 26 - 17
core/src/test/java/org/elasticsearch/script/expression/ExpressionScriptIT.java → plugins/lang-expression/src/test/java/org/elasticsearch/script/expression/MoreExpressionTests.java

@@ -32,6 +32,7 @@ import org.elasticsearch.common.xcontent.XContentFactory;
 import org.elasticsearch.index.query.QueryBuilders;
 import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;
 import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
+import org.elasticsearch.plugins.Plugin;
 import org.elasticsearch.script.CompiledScript;
 import org.elasticsearch.script.Script;
 import org.elasticsearch.script.ScriptException;
@@ -48,6 +49,8 @@ import org.elasticsearch.search.sort.SortOrder;
 import org.elasticsearch.test.ESIntegTestCase;
 import org.elasticsearch.test.hamcrest.ElasticsearchAssertions;
 
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -60,7 +63,13 @@ import static org.hamcrest.Matchers.equalTo;
 import static org.hamcrest.Matchers.greaterThan;
 import static org.hamcrest.Matchers.notNullValue;
 
-public class ExpressionScriptIT extends ESIntegTestCase {
+// TODO: please convert to unit tests!
+public class MoreExpressionTests extends ESIntegTestCase {
+
+    @Override
+    protected Collection<Class<? extends Plugin>> nodePlugins() {
+        return Collections.singleton(ExpressionPlugin.class);
+    }
 
     private SearchRequestBuilder buildRequest(String script, Object... params) {
         ensureGreen("test");
@@ -248,8 +257,8 @@ public class ExpressionScriptIT extends ESIntegTestCase {
             buildRequest("doc['bogus']").get();
             fail("Expected missing field to cause failure");
         } catch (SearchPhaseExecutionException e) {
-            assertThat(e.toString() + "should have contained ExpressionScriptCompilationException",
-                    e.toString().contains("ExpressionScriptCompilationException"), equalTo(true));
+            assertThat(e.toString() + "should have contained ScriptException",
+                    e.toString().contains("ScriptException"), equalTo(true));
             assertThat(e.toString() + "should have contained missing field error",
                     e.toString().contains("does not exist in mappings"), equalTo(true));
         }
@@ -278,8 +287,8 @@ public class ExpressionScriptIT extends ESIntegTestCase {
             buildRequest("garbage%@#%@").get();
             fail("Expected expression compilation failure");
         } catch (SearchPhaseExecutionException e) {
-            assertThat(e.toString() + "should have contained ExpressionScriptCompilationException",
-                    e.toString().contains("ExpressionScriptCompilationException"), equalTo(true));
+            assertThat(e.toString() + "should have contained ScriptException",
+                    e.toString().contains("ScriptException"), equalTo(true));
             assertThat(e.toString() + "should have contained compilation failure",
                     e.toString().contains("Failed to parse expression"), equalTo(true));
         }
@@ -291,8 +300,8 @@ public class ExpressionScriptIT extends ESIntegTestCase {
             buildRequest("a", "a", "astring").get();
             fail("Expected string parameter to cause failure");
         } catch (SearchPhaseExecutionException e) {
-            assertThat(e.toString() + "should have contained ExpressionScriptCompilationException",
-                    e.toString().contains("ExpressionScriptCompilationException"), equalTo(true));
+            assertThat(e.toString() + "should have contained ScriptException",
+                    e.toString().contains("ScriptException"), equalTo(true));
             assertThat(e.toString() + "should have contained non-numeric parameter error",
                     e.toString().contains("must be a numeric type"), equalTo(true));
         }
@@ -304,8 +313,8 @@ public class ExpressionScriptIT extends ESIntegTestCase {
             buildRequest("doc['text']").get();
             fail("Expected text field to cause execution failure");
         } catch (SearchPhaseExecutionException e) {
-            assertThat(e.toString() + "should have contained ExpressionScriptCompilationException",
-                    e.toString().contains("ExpressionScriptCompilationException"), equalTo(true));
+            assertThat(e.toString() + "should have contained ScriptException",
+                    e.toString().contains("ScriptException"), equalTo(true));
             assertThat(e.toString() + "should have contained non-numeric field error",
                     e.toString().contains("must be numeric"), equalTo(true));
         }
@@ -317,8 +326,8 @@ public class ExpressionScriptIT extends ESIntegTestCase {
             buildRequest("bogus").get();
             fail("Expected bogus variable to cause execution failure");
         } catch (SearchPhaseExecutionException e) {
-            assertThat(e.toString() + "should have contained ExpressionScriptCompilationException",
-                    e.toString().contains("ExpressionScriptCompilationException"), equalTo(true));
+            assertThat(e.toString() + "should have contained ScriptException",
+                    e.toString().contains("ScriptException"), equalTo(true));
             assertThat(e.toString() + "should have contained unknown variable error",
                     e.toString().contains("Unknown variable"), equalTo(true));
         }
@@ -330,8 +339,8 @@ public class ExpressionScriptIT extends ESIntegTestCase {
             buildRequest("doc").get();
             fail("Expected doc variable without field to cause execution failure");
         } catch (SearchPhaseExecutionException e) {
-            assertThat(e.toString() + "should have contained ExpressionScriptCompilationException",
-                    e.toString().contains("ExpressionScriptCompilationException"), equalTo(true));
+            assertThat(e.toString() + "should have contained ScriptException",
+                    e.toString().contains("ScriptException"), equalTo(true));
             assertThat(e.toString() + "should have contained a missing specific field error",
                     e.toString().contains("must be used with a specific field"), equalTo(true));
         }
@@ -343,8 +352,8 @@ public class ExpressionScriptIT extends ESIntegTestCase {
             buildRequest("doc['foo'].bogus").get();
             fail("Expected bogus field member to cause execution failure");
         } catch (SearchPhaseExecutionException e) {
-            assertThat(e.toString() + "should have contained ExpressionScriptCompilationException",
-                    e.toString().contains("ExpressionScriptCompilationException"), equalTo(true));
+            assertThat(e.toString() + "should have contained ScriptException",
+                    e.toString().contains("ScriptException"), equalTo(true));
             assertThat(e.toString() + "should have contained member variable [value] or member methods may be accessed",
                     e.toString().contains("member variable [value] or member methods may be accessed"), equalTo(true));
         }
@@ -405,8 +414,8 @@ public class ExpressionScriptIT extends ESIntegTestCase {
         } catch (SearchPhaseExecutionException e) {
             message = e.toString();
         }
-        assertThat(message + "should have contained ExpressionScriptExecutionException",
-                message.contains("ExpressionScriptExecutionException"), equalTo(true));
+        assertThat(message + "should have contained ScriptException",
+                message.contains("ScriptException"), equalTo(true));
         assertThat(message + "should have contained text variable error",
                 message.contains("text variable"), equalTo(true));
     }

+ 14 - 0
plugins/lang-expression/src/test/resources/rest-api-spec/test/lang_expression/10_basic.yaml

@@ -0,0 +1,14 @@
+# Integration tests for Expression scripts
+#
+"Expression loaded":
+    - do:
+        cluster.state: {}
+
+    # Get master node id
+    - set: { master_node: master }
+
+    - do:
+        nodes.info: {}
+
+    - match:  { nodes.$master.plugins.0.name: lang-expression  }
+    - match:  { nodes.$master.plugins.0.jvm: true  }

+ 0 - 0
rest-api-spec/src/main/resources/rest-api-spec/test/script/30_expressions.yaml → plugins/lang-expression/src/test/resources/rest-api-spec/test/lang_expression/20_search.yaml


+ 1 - 5
plugins/pom.xml

@@ -104,11 +104,6 @@
             <artifactId>lucene-spatial</artifactId>
             <scope>provided</scope>
         </dependency>
-        <dependency>
-            <groupId>org.apache.lucene</groupId>
-            <artifactId>lucene-expressions</artifactId>
-            <scope>provided</scope>
-        </dependency>
         <dependency>
             <groupId>com.spatial4j</groupId>
             <artifactId>spatial4j</artifactId>
@@ -401,6 +396,7 @@
         <module>discovery-azure</module>
         <module>discovery-ec2</module>
         <module>discovery-multicast</module>
+        <module>lang-expression</module>
         <module>lang-javascript</module>
         <module>lang-python</module>
         <module>mapper-murmur3</module>

+ 0 - 6
pom.xml

@@ -282,12 +282,6 @@
                 <artifactId>lucene-spatial</artifactId>
                 <version>${lucene.maven.version}</version>
             </dependency>
-            <dependency>
-                <groupId>org.apache.lucene</groupId>
-                <artifactId>lucene-expressions</artifactId>
-                <version>${lucene.maven.version}</version>
-                <optional>true</optional>
-            </dependency>
             <dependency>
                 <groupId>com.spatial4j</groupId>
                 <artifactId>spatial4j</artifactId>

+ 0 - 5
qa/smoke-test-multinode/pom.xml

@@ -90,11 +90,6 @@
       <artifactId>lucene-spatial</artifactId>
       <scope>provided</scope>
     </dependency>
-    <dependency>
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-expressions</artifactId>
-      <scope>provided</scope>
-    </dependency>
     <dependency>
       <groupId>com.spatial4j</groupId>
       <artifactId>spatial4j</artifactId>

+ 8 - 5
qa/smoke-test-plugins/pom.xml

@@ -95,11 +95,6 @@
       <artifactId>lucene-spatial</artifactId>
       <scope>provided</scope>
     </dependency>
-    <dependency>
-      <groupId>org.apache.lucene</groupId>
-      <artifactId>lucene-expressions</artifactId>
-      <scope>provided</scope>
-    </dependency>
     <dependency>
       <groupId>com.spatial4j</groupId>
       <artifactId>spatial4j</artifactId>
@@ -320,6 +315,14 @@
                    <overWrite>true</overWrite>
                  </artifactItem>
 
+                 <artifactItem>
+                   <groupId>org.elasticsearch.plugin</groupId>
+                   <artifactId>lang-expression</artifactId>
+                   <version>${elasticsearch.version}</version>
+                   <type>zip</type>
+                   <overWrite>true</overWrite>
+                 </artifactItem>
+
                  <artifactItem>
                    <groupId>org.elasticsearch.plugin</groupId>
                    <artifactId>lang-javascript</artifactId>