mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-28 09:28:55 -04:00
Remove lang-python and lang-javascript (#20734)
They were deprecated in 5.0. We are concentrating on making Painless awesome rather than supporting every language possible. Closes #20698
This commit is contained in:
parent
4225737db9
commit
c79371fd5b
46 changed files with 6 additions and 5245 deletions
|
@ -968,14 +968,6 @@
|
||||||
<suppress files="plugins[/\\]discovery-ec2[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]cloud[/\\]aws[/\\]AbstractAwsTestCase.java" checks="LineLength" />
|
<suppress files="plugins[/\\]discovery-ec2[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]cloud[/\\]aws[/\\]AbstractAwsTestCase.java" checks="LineLength" />
|
||||||
<suppress files="plugins[/\\]discovery-ec2[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]ec2[/\\]AmazonEC2Mock.java" checks="LineLength" />
|
<suppress files="plugins[/\\]discovery-ec2[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]ec2[/\\]AmazonEC2Mock.java" checks="LineLength" />
|
||||||
<suppress files="plugins[/\\]discovery-gce[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]gce[/\\]GceNetworkTests.java" checks="LineLength" />
|
<suppress files="plugins[/\\]discovery-gce[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]discovery[/\\]gce[/\\]GceNetworkTests.java" checks="LineLength" />
|
||||||
<suppress files="plugins[/\\]lang-javascript[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]javascript[/\\]JavaScriptScriptEngineService.java" checks="LineLength" />
|
|
||||||
<suppress files="plugins[/\\]lang-javascript[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]javascript[/\\]JavaScriptScriptEngineTests.java" checks="LineLength" />
|
|
||||||
<suppress files="plugins[/\\]lang-javascript[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]javascript[/\\]JavaScriptScriptMultiThreadedTests.java" checks="LineLength" />
|
|
||||||
<suppress files="plugins[/\\]lang-javascript[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]javascript[/\\]JavaScriptSecurityTests.java" checks="LineLength" />
|
|
||||||
<suppress files="plugins[/\\]lang-javascript[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]javascript[/\\]SimpleBench.java" checks="LineLength" />
|
|
||||||
<suppress files="plugins[/\\]lang-python[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]python[/\\]PythonScriptEngineTests.java" checks="LineLength" />
|
|
||||||
<suppress files="plugins[/\\]lang-python[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]python[/\\]PythonScriptMultiThreadedTests.java" checks="LineLength" />
|
|
||||||
<suppress files="plugins[/\\]lang-python[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]python[/\\]PythonSecurityTests.java" checks="LineLength" />
|
|
||||||
<suppress files="plugins[/\\]mapper-murmur3[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]index[/\\]mapper[/\\]murmur3[/\\]Murmur3FieldMapper.java" checks="LineLength" />
|
<suppress files="plugins[/\\]mapper-murmur3[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]index[/\\]mapper[/\\]murmur3[/\\]Murmur3FieldMapper.java" checks="LineLength" />
|
||||||
<suppress files="plugins[/\\]mapper-murmur3[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]index[/\\]mapper[/\\]murmur3[/\\]Murmur3FieldMapperTests.java" checks="LineLength" />
|
<suppress files="plugins[/\\]mapper-murmur3[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]index[/\\]mapper[/\\]murmur3[/\\]Murmur3FieldMapperTests.java" checks="LineLength" />
|
||||||
<suppress files="plugins[/\\]mapper-murmur3[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]index[/\\]mapper[/\\]murmur3[/\\]Murmur3FieldMapperUpgradeTests.java" checks="LineLength" />
|
<suppress files="plugins[/\\]mapper-murmur3[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]index[/\\]mapper[/\\]murmur3[/\\]Murmur3FieldMapperUpgradeTests.java" checks="LineLength" />
|
||||||
|
|
|
@ -78,7 +78,7 @@ import java.util.Map;
|
||||||
* when they are so dangerous that general code should not be granted the
|
* when they are so dangerous that general code should not be granted the
|
||||||
* permission, but there are extenuating circumstances.
|
* permission, but there are extenuating circumstances.
|
||||||
* <p>
|
* <p>
|
||||||
* Scripts (groovy, javascript, python) are assigned minimal permissions. This does not provide adequate
|
* Scripts (groovy) are assigned minimal permissions. This does not provide adequate
|
||||||
* sandboxing, as these scripts still have access to ES classes, and could
|
* sandboxing, as these scripts still have access to ES classes, and could
|
||||||
* modify members, etc that would cause bad things to happen later on their
|
* modify members, etc that would cause bad things to happen later on their
|
||||||
* behalf (no package protections are yet in place, this would need some
|
* behalf (no package protections are yet in place, this would need some
|
||||||
|
|
|
@ -69,8 +69,6 @@ DEFAULT_PLUGINS = ["analysis-icu",
|
||||||
"ingest-attachment",
|
"ingest-attachment",
|
||||||
"ingest-geoip",
|
"ingest-geoip",
|
||||||
"ingest-user-agent",
|
"ingest-user-agent",
|
||||||
"lang-javascript",
|
|
||||||
"lang-python",
|
|
||||||
"mapper-attachments",
|
"mapper-attachments",
|
||||||
"mapper-murmur3",
|
"mapper-murmur3",
|
||||||
"mapper-size",
|
"mapper-size",
|
||||||
|
@ -297,6 +295,3 @@ if __name__ == "__main__":
|
||||||
else:
|
else:
|
||||||
download_url = 'https://staging.elastic.co/%s-%s/downloads/elasticsearch' % (version, hash)
|
download_url = 'https://staging.elastic.co/%s-%s/downloads/elasticsearch' % (version, hash)
|
||||||
download_and_verify(version, hash, files, download_url, plugins=DEFAULT_PLUGINS + plugins)
|
download_and_verify(version, hash, files, download_url, plugins=DEFAULT_PLUGINS + plugins)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -56,8 +56,6 @@ include::management.asciidoc[]
|
||||||
|
|
||||||
include::mapper.asciidoc[]
|
include::mapper.asciidoc[]
|
||||||
|
|
||||||
include::scripting.asciidoc[]
|
|
||||||
|
|
||||||
include::security.asciidoc[]
|
include::security.asciidoc[]
|
||||||
|
|
||||||
include::repository.asciidoc[]
|
include::repository.asciidoc[]
|
||||||
|
|
|
@ -1,189 +0,0 @@
|
||||||
[[lang-javascript]]
|
|
||||||
=== JavaScript Language Plugin
|
|
||||||
|
|
||||||
deprecated[5.0.0,JavaScript will be replaced by the new scripting language {ref}/modules-scripting-painless.html[`Painless`]]
|
|
||||||
|
|
||||||
The JavaScript language plugin enables the use of JavaScript in Elasticsearch
|
|
||||||
scripts, via Mozilla's
|
|
||||||
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino[Rhino JavaScript] engine.
|
|
||||||
|
|
||||||
[[lang-javascript-install]]
|
|
||||||
[float]
|
|
||||||
==== Installation
|
|
||||||
|
|
||||||
This plugin can be installed using the plugin manager:
|
|
||||||
|
|
||||||
[source,sh]
|
|
||||||
----------------------------------------------------------------
|
|
||||||
sudo bin/elasticsearch-plugin install lang-javascript
|
|
||||||
----------------------------------------------------------------
|
|
||||||
|
|
||||||
The plugin must be installed on every node in the cluster, and each node must
|
|
||||||
be restarted after installation.
|
|
||||||
|
|
||||||
This plugin can be downloaded for <<plugin-management-custom-url,offline install>> from
|
|
||||||
{plugin_url}/lang-javascript/lang-javascript-{version}.zip.
|
|
||||||
|
|
||||||
[[lang-javascript-remove]]
|
|
||||||
[float]
|
|
||||||
==== Removal
|
|
||||||
|
|
||||||
The plugin can be removed with the following command:
|
|
||||||
|
|
||||||
[source,sh]
|
|
||||||
----------------------------------------------------------------
|
|
||||||
sudo bin/elasticsearch-plugin remove lang-javascript
|
|
||||||
----------------------------------------------------------------
|
|
||||||
|
|
||||||
The node must be stopped before removing the plugin.
|
|
||||||
|
|
||||||
[[lang-javascript-usage]]
|
|
||||||
==== Using JavaScript in Elasticsearch
|
|
||||||
|
|
||||||
Once the plugin has been installed, JavaScript can be used at a scripting
|
|
||||||
language by setting the `lang` parameter to `javascript`.
|
|
||||||
|
|
||||||
Scripting is available in many APIs, but we will use an example with the
|
|
||||||
`function_score` for demonstration purposes:
|
|
||||||
|
|
||||||
[[lang-javascript-inline]]
|
|
||||||
[float]
|
|
||||||
=== Inline scripts
|
|
||||||
|
|
||||||
WARNING: Enabling inline scripting on an unprotected Elasticsearch cluster is dangerous.
|
|
||||||
See <<lang-javascript-file>> for a safer option.
|
|
||||||
|
|
||||||
If you have enabled {ref}/modules-scripting-security.html#enable-dynamic-scripting[inline scripts],
|
|
||||||
you can use JavaScript as follows:
|
|
||||||
|
|
||||||
[source,js]
|
|
||||||
----
|
|
||||||
PUT test/doc/1
|
|
||||||
{
|
|
||||||
"num": 1.0
|
|
||||||
}
|
|
||||||
|
|
||||||
PUT test/doc/2
|
|
||||||
{
|
|
||||||
"num": 2.0
|
|
||||||
}
|
|
||||||
|
|
||||||
GET test/_search
|
|
||||||
{
|
|
||||||
"query": {
|
|
||||||
"function_score": {
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"inline": "doc[\"num\"].value * factor",
|
|
||||||
"lang": "javascript",
|
|
||||||
"params": {
|
|
||||||
"factor": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
----
|
|
||||||
// CONSOLE
|
|
||||||
|
|
||||||
[[lang-javascript-stored]]
|
|
||||||
[float]
|
|
||||||
=== Stored scripts
|
|
||||||
|
|
||||||
WARNING: Enabling stored scripts on an unprotected Elasticsearch cluster is dangerous.
|
|
||||||
See <<lang-javascript-file>> for a safer option.
|
|
||||||
|
|
||||||
If you have enabled {ref}/modules-scripting-security.html#enable-dynamic-scripting[stored scripts],
|
|
||||||
you can use JavaScript as follows:
|
|
||||||
|
|
||||||
[source,js]
|
|
||||||
----
|
|
||||||
PUT test/doc/1
|
|
||||||
{
|
|
||||||
"num": 1.0
|
|
||||||
}
|
|
||||||
|
|
||||||
PUT test/doc/2
|
|
||||||
{
|
|
||||||
"num": 2.0
|
|
||||||
}
|
|
||||||
|
|
||||||
POST _scripts/javascript/my_script <1>
|
|
||||||
{
|
|
||||||
"script": "doc[\"num\"].value * factor"
|
|
||||||
}
|
|
||||||
|
|
||||||
GET test/_search
|
|
||||||
{
|
|
||||||
"query": {
|
|
||||||
"function_score": {
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"stored": "my_script", <2>
|
|
||||||
"lang": "javascript",
|
|
||||||
"params": {
|
|
||||||
"factor": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
----
|
|
||||||
// CONSOLE
|
|
||||||
|
|
||||||
<1> We store the script under the id `my_script`.
|
|
||||||
<2> The function score query retrieves the script with id `my_script`.
|
|
||||||
|
|
||||||
|
|
||||||
[[lang-javascript-file]]
|
|
||||||
[float]
|
|
||||||
=== File scripts
|
|
||||||
|
|
||||||
You can save your scripts to a file in the `config/scripts/` directory on
|
|
||||||
every node. The `.javascript` file suffix identifies the script as containing
|
|
||||||
JavaScript:
|
|
||||||
|
|
||||||
First, save this file as `config/scripts/my_script.js` on every node
|
|
||||||
in the cluster:
|
|
||||||
|
|
||||||
[source,painless]
|
|
||||||
----
|
|
||||||
doc["num"].value * factor
|
|
||||||
----
|
|
||||||
|
|
||||||
then use the script as follows:
|
|
||||||
|
|
||||||
[source,js]
|
|
||||||
----
|
|
||||||
PUT test/doc/1
|
|
||||||
{
|
|
||||||
"num": 1.0
|
|
||||||
}
|
|
||||||
|
|
||||||
PUT test/doc/2
|
|
||||||
{
|
|
||||||
"num": 2.0
|
|
||||||
}
|
|
||||||
|
|
||||||
GET test/_search
|
|
||||||
{
|
|
||||||
"query": {
|
|
||||||
"function_score": {
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"file": "my_script", <1>
|
|
||||||
"lang": "javascript",
|
|
||||||
"params": {
|
|
||||||
"factor": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
----
|
|
||||||
// CONSOLE
|
|
||||||
|
|
||||||
<1> The function score query retrieves the script with filename `my_script.javascript`.
|
|
|
@ -1,189 +0,0 @@
|
||||||
[[lang-python]]
|
|
||||||
=== Python Language Plugin
|
|
||||||
|
|
||||||
deprecated[5.0.0,Python will be replaced by the new scripting language {ref}/modules-scripting-painless.html[`Painless`]]
|
|
||||||
|
|
||||||
The Python language plugin enables the use of Python in Elasticsearch
|
|
||||||
scripts, via the http://www.jython.org/[Jython] Java implementation of Python.
|
|
||||||
|
|
||||||
[[lang-python-install]]
|
|
||||||
[float]
|
|
||||||
==== Installation
|
|
||||||
|
|
||||||
This plugin can be installed using the plugin manager:
|
|
||||||
|
|
||||||
[source,sh]
|
|
||||||
----------------------------------------------------------------
|
|
||||||
sudo bin/elasticsearch-plugin install lang-python
|
|
||||||
----------------------------------------------------------------
|
|
||||||
|
|
||||||
The plugin must be installed on every node in the cluster, and each node must
|
|
||||||
be restarted after installation.
|
|
||||||
|
|
||||||
This plugin can be downloaded for <<plugin-management-custom-url,offline install>> from
|
|
||||||
{plugin_url}/lang-python/lang-python-{version}.zip.
|
|
||||||
|
|
||||||
[[lang-python-remove]]
|
|
||||||
[float]
|
|
||||||
==== Removal
|
|
||||||
|
|
||||||
The plugin can be removed with the following command:
|
|
||||||
|
|
||||||
[source,sh]
|
|
||||||
----------------------------------------------------------------
|
|
||||||
sudo bin/elasticsearch-plugin remove lang-python
|
|
||||||
----------------------------------------------------------------
|
|
||||||
|
|
||||||
The node must be stopped before removing the plugin.
|
|
||||||
|
|
||||||
[[lang-python-usage]]
|
|
||||||
==== Using Python in Elasticsearch
|
|
||||||
|
|
||||||
Once the plugin has been installed, Python can be used at a scripting
|
|
||||||
language by setting the `lang` parameter to `python`.
|
|
||||||
|
|
||||||
Scripting is available in many APIs, but we will use an example with the
|
|
||||||
`function_score` for demonstration purposes:
|
|
||||||
|
|
||||||
[[lang-python-inline]]
|
|
||||||
[float]
|
|
||||||
=== Inline scripts
|
|
||||||
|
|
||||||
WARNING: Enabling inline scripting on an unprotected Elasticsearch cluster is dangerous.
|
|
||||||
See <<lang-python-file>> for a safer option.
|
|
||||||
|
|
||||||
If you have enabled {ref}/modules-scripting-security.html#enable-dynamic-scripting[inline scripts],
|
|
||||||
you can use Python as follows:
|
|
||||||
|
|
||||||
[source,js]
|
|
||||||
----
|
|
||||||
PUT test/doc/1
|
|
||||||
{
|
|
||||||
"num": 1.0
|
|
||||||
}
|
|
||||||
|
|
||||||
PUT test/doc/2
|
|
||||||
{
|
|
||||||
"num": 2.0
|
|
||||||
}
|
|
||||||
|
|
||||||
GET test/_search
|
|
||||||
{
|
|
||||||
"query": {
|
|
||||||
"function_score": {
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"inline": "doc[\"num\"].value * factor",
|
|
||||||
"lang": "python",
|
|
||||||
"params": {
|
|
||||||
"factor": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
----
|
|
||||||
// CONSOLE
|
|
||||||
|
|
||||||
[[lang-python-stored]]
|
|
||||||
[float]
|
|
||||||
=== Stored scripts
|
|
||||||
|
|
||||||
WARNING: Enabling stored scripts on an unprotected Elasticsearch cluster is dangerous.
|
|
||||||
See <<lang-python-file>> for a safer option.
|
|
||||||
|
|
||||||
If you have enabled {ref}/modules-scripting-security.html#enable-dynamic-scripting[stored scripts],
|
|
||||||
you can use Python as follows:
|
|
||||||
|
|
||||||
[source,js]
|
|
||||||
----
|
|
||||||
PUT test/doc/1
|
|
||||||
{
|
|
||||||
"num": 1.0
|
|
||||||
}
|
|
||||||
|
|
||||||
PUT test/doc/2
|
|
||||||
{
|
|
||||||
"num": 2.0
|
|
||||||
}
|
|
||||||
|
|
||||||
POST _scripts/python/my_script <1>
|
|
||||||
{
|
|
||||||
"script": "doc[\"num\"].value * factor"
|
|
||||||
}
|
|
||||||
|
|
||||||
GET test/_search
|
|
||||||
{
|
|
||||||
"query": {
|
|
||||||
"function_score": {
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"stored": "my_script", <2>
|
|
||||||
"lang": "python",
|
|
||||||
"params": {
|
|
||||||
"factor": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
----
|
|
||||||
// CONSOLE
|
|
||||||
|
|
||||||
<1> We store the script under the id `my_script`.
|
|
||||||
<2> The function score query retrieves the script with id `my_script`.
|
|
||||||
|
|
||||||
|
|
||||||
[[lang-python-file]]
|
|
||||||
[float]
|
|
||||||
=== File scripts
|
|
||||||
|
|
||||||
You can save your scripts to a file in the `config/scripts/` directory on
|
|
||||||
every node. The `.py` file suffix identifies the script as containing
|
|
||||||
Python:
|
|
||||||
|
|
||||||
First, save this file as `config/scripts/my_script.py` on every node
|
|
||||||
in the cluster:
|
|
||||||
|
|
||||||
[source,python]
|
|
||||||
----
|
|
||||||
doc["num"].value * factor
|
|
||||||
----
|
|
||||||
|
|
||||||
then use the script as follows:
|
|
||||||
|
|
||||||
[source,js]
|
|
||||||
----
|
|
||||||
PUT test/doc/1
|
|
||||||
{
|
|
||||||
"num": 1.0
|
|
||||||
}
|
|
||||||
|
|
||||||
PUT test/doc/2
|
|
||||||
{
|
|
||||||
"num": 2.0
|
|
||||||
}
|
|
||||||
|
|
||||||
GET test/_search
|
|
||||||
{
|
|
||||||
"query": {
|
|
||||||
"function_score": {
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"file": "my_script", <1>
|
|
||||||
"lang": "python",
|
|
||||||
"params": {
|
|
||||||
"factor": 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
----
|
|
||||||
// CONSOLE
|
|
||||||
|
|
||||||
<1> The function score query retrieves the script with filename `my_script.py`.
|
|
|
@ -1,25 +0,0 @@
|
||||||
[[scripting]]
|
|
||||||
== Scripting Plugins
|
|
||||||
|
|
||||||
Scripting plugins extend the scripting functionality in Elasticsearch to allow
|
|
||||||
the use of other scripting languages.
|
|
||||||
|
|
||||||
[float]
|
|
||||||
=== Core scripting plugins
|
|
||||||
|
|
||||||
The core scripting plugins are:
|
|
||||||
|
|
||||||
<<lang-javascript,JavaScript Language>>::
|
|
||||||
|
|
||||||
The JavaScript language plugin enables the use of JavaScript in Elasticsearch
|
|
||||||
scripts, via Mozilla's
|
|
||||||
https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino[Rhino JavaScript] engine.
|
|
||||||
|
|
||||||
<<lang-python,Python Language>>::
|
|
||||||
|
|
||||||
The Python language plugin enables the use of Python in Elasticsearch
|
|
||||||
scripts, via the http://www.jython.org/[Jython] Java implementation of Python.
|
|
||||||
|
|
||||||
include::lang-javascript.asciidoc[]
|
|
||||||
|
|
||||||
include::lang-python.asciidoc[]
|
|
|
@ -28,8 +28,6 @@ U7321H6 ingest-attachment {version} Ingest processor that uses Apache Tika
|
||||||
U7321H6 ingest-geoip {version} Ingest processor that uses looksup geo data based on ip adresses using the Maxmind geo database
|
U7321H6 ingest-geoip {version} Ingest processor that uses looksup geo data based on ip adresses using the Maxmind geo database
|
||||||
U7321H6 ingest-user-agent {version} Ingest processor that extracts information from a user agent
|
U7321H6 ingest-user-agent {version} Ingest processor that extracts information from a user agent
|
||||||
U7321H6 jvm-example {version} Demonstrates all the pluggable Java entry points in Elasticsearch
|
U7321H6 jvm-example {version} Demonstrates all the pluggable Java entry points in Elasticsearch
|
||||||
U7321H6 lang-javascript {version} The JavaScript language plugin allows to have javascript as the language of scripts to execute.
|
|
||||||
U7321H6 lang-python {version} The Python language plugin allows to have python as the language of scripts to execute.
|
|
||||||
U7321H6 mapper-murmur3 {version} The Mapper Murmur3 plugin allows to compute hashes of a field's values at index-time and to store them in the index.
|
U7321H6 mapper-murmur3 {version} The Mapper Murmur3 plugin allows to compute hashes of a field's values at index-time and to store them in the index.
|
||||||
U7321H6 mapper-size {version} The Mapper Size plugin allows document to record their uncompressed size at index time.
|
U7321H6 mapper-size {version} The Mapper Size plugin allows document to record their uncompressed size at index time.
|
||||||
U7321H6 store-smb {version} The Store SMB plugin adds support for SMB stores.
|
U7321H6 store-smb {version} The Store SMB plugin adds support for SMB stores.
|
||||||
|
|
|
@ -45,10 +45,10 @@ The modules in this section are:
|
||||||
<<modules-node,Node client>>::
|
<<modules-node,Node client>>::
|
||||||
|
|
||||||
A Java node client joins the cluster, but doesn't hold data or act as a master node.
|
A Java node client joins the cluster, but doesn't hold data or act as a master node.
|
||||||
|
|
||||||
<<modules-scripting-painless,Painless>>::
|
<<modules-scripting-painless,Painless>>::
|
||||||
|
|
||||||
A built-in scripting language for Elasticsearch that's designed to be as secure as possible.
|
A built-in scripting language for Elasticsearch that's designed to be as secure as possible.
|
||||||
|
|
||||||
<<modules-plugins,Plugins>>::
|
<<modules-plugins,Plugins>>::
|
||||||
|
|
||||||
|
@ -56,8 +56,8 @@ The modules in this section are:
|
||||||
|
|
||||||
<<modules-scripting,Scripting>>::
|
<<modules-scripting,Scripting>>::
|
||||||
|
|
||||||
Custom scripting available in Lucene Expressions, Groovy, Python, and
|
Custom scripting available in Lucene Expressions, ad Groovy. You can also
|
||||||
Javascript. You can also write scripts in the built-in scripting language,
|
write scripts in the built-in scripting language,
|
||||||
<<modules-scripting-painless, Painless>>.
|
<<modules-scripting-painless, Painless>>.
|
||||||
|
|
||||||
<<modules-snapshots,Snapshot/Restore>>::
|
<<modules-snapshots,Snapshot/Restore>>::
|
||||||
|
@ -105,7 +105,3 @@ include::modules/threadpool.asciidoc[]
|
||||||
include::modules/transport.asciidoc[]
|
include::modules/transport.asciidoc[]
|
||||||
|
|
||||||
include::modules/tribe.asciidoc[]
|
include::modules/tribe.asciidoc[]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,14 +30,6 @@ and give the most flexibility.
|
||||||
|<<modules-scripting-security, no>>
|
|<<modules-scripting-security, no>>
|
||||||
|built-in
|
|built-in
|
||||||
|
|
||||||
|{plugins}/lang-javascript.html[`javascript`]
|
|
||||||
|<<modules-scripting-security, no>>
|
|
||||||
|{plugins}/lang-javascript.html[`lang-javascript`]
|
|
||||||
|
|
||||||
|{plugins}/lang-python.html[`python`]
|
|
||||||
|<<modules-scripting-security, no>>
|
|
||||||
|{plugins}/lang-python.html[`lang-python`]
|
|
||||||
|
|
||||||
|=======================================================================
|
|=======================================================================
|
||||||
|
|
||||||
[float]
|
[float]
|
||||||
|
@ -98,4 +90,3 @@ include::scripting/expression.asciidoc[]
|
||||||
include::scripting/native.asciidoc[]
|
include::scripting/native.asciidoc[]
|
||||||
|
|
||||||
include::scripting/advanced-scripting.asciidoc[]
|
include::scripting/advanced-scripting.asciidoc[]
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,7 @@ The benefit of doing this is that it severely limits the attack vectors
|
||||||
available to a hacker.
|
available to a hacker.
|
||||||
|
|
||||||
Restricting permissions is particularly important with scripting languages
|
Restricting permissions is particularly important with scripting languages
|
||||||
like Groovy and Javascript which are designed to do anything that can be done
|
like Groovy which is designed to do anything that can be done
|
||||||
in Java itself, including writing to the file system, opening sockets to
|
in Java itself, including writing to the file system, opening sockets to
|
||||||
remote servers, etc.
|
remote servers, etc.
|
||||||
|
|
||||||
|
@ -287,4 +287,3 @@ doing so.
|
||||||
======================================
|
======================================
|
||||||
|
|
||||||
See http://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html for more information.
|
See http://docs.oracle.com/javase/7/docs/technotes/guides/security/PolicyFiles.html for more information.
|
||||||
|
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
esplugin {
|
|
||||||
description 'The JavaScript language plugin allows to have javascript as the language of scripts to execute.'
|
|
||||||
classname 'org.elasticsearch.plugin.javascript.JavaScriptPlugin'
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compile 'org.mozilla:rhino:1.7.7'
|
|
||||||
}
|
|
||||||
|
|
||||||
integTest {
|
|
||||||
cluster {
|
|
||||||
setting 'script.inline', 'true'
|
|
||||||
setting 'script.stored', 'true'
|
|
||||||
setting 'script.max_compilations_per_minute', '1000'
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
3a9ea863b86126b0ed8f2fe2230412747cd3c254
|
|
|
@ -1,375 +0,0 @@
|
||||||
The majority of Rhino is licensed under the MPL 2.0:
|
|
||||||
|
|
||||||
Mozilla Public License Version 2.0
|
|
||||||
==================================
|
|
||||||
|
|
||||||
1. Definitions
|
|
||||||
--------------
|
|
||||||
|
|
||||||
1.1. "Contributor"
|
|
||||||
means each individual or legal entity that creates, contributes to
|
|
||||||
the creation of, or owns Covered Software.
|
|
||||||
|
|
||||||
1.2. "Contributor Version"
|
|
||||||
means the combination of the Contributions of others (if any) used
|
|
||||||
by a Contributor and that particular Contributor's Contribution.
|
|
||||||
|
|
||||||
1.3. "Contribution"
|
|
||||||
means Covered Software of a particular Contributor.
|
|
||||||
|
|
||||||
1.4. "Covered Software"
|
|
||||||
means Source Code Form to which the initial Contributor has attached
|
|
||||||
the notice in Exhibit A, the Executable Form of such Source Code
|
|
||||||
Form, and Modifications of such Source Code Form, in each case
|
|
||||||
including portions thereof.
|
|
||||||
|
|
||||||
1.5. "Incompatible With Secondary Licenses"
|
|
||||||
means
|
|
||||||
|
|
||||||
(a) that the initial Contributor has attached the notice described
|
|
||||||
in Exhibit B to the Covered Software; or
|
|
||||||
|
|
||||||
(b) that the Covered Software was made available under the terms of
|
|
||||||
version 1.1 or earlier of the License, but not also under the
|
|
||||||
terms of a Secondary License.
|
|
||||||
|
|
||||||
1.6. "Executable Form"
|
|
||||||
means any form of the work other than Source Code Form.
|
|
||||||
|
|
||||||
1.7. "Larger Work"
|
|
||||||
means a work that combines Covered Software with other material, in
|
|
||||||
a separate file or files, that is not Covered Software.
|
|
||||||
|
|
||||||
1.8. "License"
|
|
||||||
means this document.
|
|
||||||
|
|
||||||
1.9. "Licensable"
|
|
||||||
means having the right to grant, to the maximum extent possible,
|
|
||||||
whether at the time of the initial grant or subsequently, any and
|
|
||||||
all of the rights conveyed by this License.
|
|
||||||
|
|
||||||
1.10. "Modifications"
|
|
||||||
means any of the following:
|
|
||||||
|
|
||||||
(a) any file in Source Code Form that results from an addition to,
|
|
||||||
deletion from, or modification of the contents of Covered
|
|
||||||
Software; or
|
|
||||||
|
|
||||||
(b) any new file in Source Code Form that contains any Covered
|
|
||||||
Software.
|
|
||||||
|
|
||||||
1.11. "Patent Claims" of a Contributor
|
|
||||||
means any patent claim(s), including without limitation, method,
|
|
||||||
process, and apparatus claims, in any patent Licensable by such
|
|
||||||
Contributor that would be infringed, but for the grant of the
|
|
||||||
License, by the making, using, selling, offering for sale, having
|
|
||||||
made, import, or transfer of either its Contributions or its
|
|
||||||
Contributor Version.
|
|
||||||
|
|
||||||
1.12. "Secondary License"
|
|
||||||
means either the GNU General Public License, Version 2.0, the GNU
|
|
||||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
|
||||||
Public License, Version 3.0, or any later versions of those
|
|
||||||
licenses.
|
|
||||||
|
|
||||||
1.13. "Source Code Form"
|
|
||||||
means the form of the work preferred for making modifications.
|
|
||||||
|
|
||||||
1.14. "You" (or "Your")
|
|
||||||
means an individual or a legal entity exercising rights under this
|
|
||||||
License. For legal entities, "You" includes any entity that
|
|
||||||
controls, is controlled by, or is under common control with You. For
|
|
||||||
purposes of this definition, "control" means (a) the power, direct
|
|
||||||
or indirect, to cause the direction or management of such entity,
|
|
||||||
whether by contract or otherwise, or (b) ownership of more than
|
|
||||||
fifty percent (50%) of the outstanding shares or beneficial
|
|
||||||
ownership of such entity.
|
|
||||||
|
|
||||||
2. License Grants and Conditions
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
2.1. Grants
|
|
||||||
|
|
||||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
|
||||||
non-exclusive license:
|
|
||||||
|
|
||||||
(a) under intellectual property rights (other than patent or trademark)
|
|
||||||
Licensable by such Contributor to use, reproduce, make available,
|
|
||||||
modify, display, perform, distribute, and otherwise exploit its
|
|
||||||
Contributions, either on an unmodified basis, with Modifications, or
|
|
||||||
as part of a Larger Work; and
|
|
||||||
|
|
||||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
|
||||||
for sale, have made, import, and otherwise transfer either its
|
|
||||||
Contributions or its Contributor Version.
|
|
||||||
|
|
||||||
2.2. Effective Date
|
|
||||||
|
|
||||||
The licenses granted in Section 2.1 with respect to any Contribution
|
|
||||||
become effective for each Contribution on the date the Contributor first
|
|
||||||
distributes such Contribution.
|
|
||||||
|
|
||||||
2.3. Limitations on Grant Scope
|
|
||||||
|
|
||||||
The licenses granted in this Section 2 are the only rights granted under
|
|
||||||
this License. No additional rights or licenses will be implied from the
|
|
||||||
distribution or licensing of Covered Software under this License.
|
|
||||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
|
||||||
Contributor:
|
|
||||||
|
|
||||||
(a) for any code that a Contributor has removed from Covered Software;
|
|
||||||
or
|
|
||||||
|
|
||||||
(b) for infringements caused by: (i) Your and any other third party's
|
|
||||||
modifications of Covered Software, or (ii) the combination of its
|
|
||||||
Contributions with other software (except as part of its Contributor
|
|
||||||
Version); or
|
|
||||||
|
|
||||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
|
||||||
its Contributions.
|
|
||||||
|
|
||||||
This License does not grant any rights in the trademarks, service marks,
|
|
||||||
or logos of any Contributor (except as may be necessary to comply with
|
|
||||||
the notice requirements in Section 3.4).
|
|
||||||
|
|
||||||
2.4. Subsequent Licenses
|
|
||||||
|
|
||||||
No Contributor makes additional grants as a result of Your choice to
|
|
||||||
distribute the Covered Software under a subsequent version of this
|
|
||||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
|
||||||
permitted under the terms of Section 3.3).
|
|
||||||
|
|
||||||
2.5. Representation
|
|
||||||
|
|
||||||
Each Contributor represents that the Contributor believes its
|
|
||||||
Contributions are its original creation(s) or it has sufficient rights
|
|
||||||
to grant the rights to its Contributions conveyed by this License.
|
|
||||||
|
|
||||||
2.6. Fair Use
|
|
||||||
|
|
||||||
This License is not intended to limit any rights You have under
|
|
||||||
applicable copyright doctrines of fair use, fair dealing, or other
|
|
||||||
equivalents.
|
|
||||||
|
|
||||||
2.7. Conditions
|
|
||||||
|
|
||||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
|
||||||
in Section 2.1.
|
|
||||||
|
|
||||||
3. Responsibilities
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
3.1. Distribution of Source Form
|
|
||||||
|
|
||||||
All distribution of Covered Software in Source Code Form, including any
|
|
||||||
Modifications that You create or to which You contribute, must be under
|
|
||||||
the terms of this License. You must inform recipients that the Source
|
|
||||||
Code Form of the Covered Software is governed by the terms of this
|
|
||||||
License, and how they can obtain a copy of this License. You may not
|
|
||||||
attempt to alter or restrict the recipients' rights in the Source Code
|
|
||||||
Form.
|
|
||||||
|
|
||||||
3.2. Distribution of Executable Form
|
|
||||||
|
|
||||||
If You distribute Covered Software in Executable Form then:
|
|
||||||
|
|
||||||
(a) such Covered Software must also be made available in Source Code
|
|
||||||
Form, as described in Section 3.1, and You must inform recipients of
|
|
||||||
the Executable Form how they can obtain a copy of such Source Code
|
|
||||||
Form by reasonable means in a timely manner, at a charge no more
|
|
||||||
than the cost of distribution to the recipient; and
|
|
||||||
|
|
||||||
(b) You may distribute such Executable Form under the terms of this
|
|
||||||
License, or sublicense it under different terms, provided that the
|
|
||||||
license for the Executable Form does not attempt to limit or alter
|
|
||||||
the recipients' rights in the Source Code Form under this License.
|
|
||||||
|
|
||||||
3.3. Distribution of a Larger Work
|
|
||||||
|
|
||||||
You may create and distribute a Larger Work under terms of Your choice,
|
|
||||||
provided that You also comply with the requirements of this License for
|
|
||||||
the Covered Software. If the Larger Work is a combination of Covered
|
|
||||||
Software with a work governed by one or more Secondary Licenses, and the
|
|
||||||
Covered Software is not Incompatible With Secondary Licenses, this
|
|
||||||
License permits You to additionally distribute such Covered Software
|
|
||||||
under the terms of such Secondary License(s), so that the recipient of
|
|
||||||
the Larger Work may, at their option, further distribute the Covered
|
|
||||||
Software under the terms of either this License or such Secondary
|
|
||||||
License(s).
|
|
||||||
|
|
||||||
3.4. Notices
|
|
||||||
|
|
||||||
You may not remove or alter the substance of any license notices
|
|
||||||
(including copyright notices, patent notices, disclaimers of warranty,
|
|
||||||
or limitations of liability) contained within the Source Code Form of
|
|
||||||
the Covered Software, except that You may alter any license notices to
|
|
||||||
the extent required to remedy known factual inaccuracies.
|
|
||||||
|
|
||||||
3.5. Application of Additional Terms
|
|
||||||
|
|
||||||
You may choose to offer, and to charge a fee for, warranty, support,
|
|
||||||
indemnity or liability obligations to one or more recipients of Covered
|
|
||||||
Software. However, You may do so only on Your own behalf, and not on
|
|
||||||
behalf of any Contributor. You must make it absolutely clear that any
|
|
||||||
such warranty, support, indemnity, or liability obligation is offered by
|
|
||||||
You alone, and You hereby agree to indemnify every Contributor for any
|
|
||||||
liability incurred by such Contributor as a result of warranty, support,
|
|
||||||
indemnity or liability terms You offer. You may include additional
|
|
||||||
disclaimers of warranty and limitations of liability specific to any
|
|
||||||
jurisdiction.
|
|
||||||
|
|
||||||
4. Inability to Comply Due to Statute or Regulation
|
|
||||||
---------------------------------------------------
|
|
||||||
|
|
||||||
If it is impossible for You to comply with any of the terms of this
|
|
||||||
License with respect to some or all of the Covered Software due to
|
|
||||||
statute, judicial order, or regulation then You must: (a) comply with
|
|
||||||
the terms of this License to the maximum extent possible; and (b)
|
|
||||||
describe the limitations and the code they affect. Such description must
|
|
||||||
be placed in a text file included with all distributions of the Covered
|
|
||||||
Software under this License. Except to the extent prohibited by statute
|
|
||||||
or regulation, such description must be sufficiently detailed for a
|
|
||||||
recipient of ordinary skill to be able to understand it.
|
|
||||||
|
|
||||||
5. Termination
|
|
||||||
--------------
|
|
||||||
|
|
||||||
5.1. The rights granted under this License will terminate automatically
|
|
||||||
if You fail to comply with any of its terms. However, if You become
|
|
||||||
compliant, then the rights granted under this License from a particular
|
|
||||||
Contributor are reinstated (a) provisionally, unless and until such
|
|
||||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
|
||||||
ongoing basis, if such Contributor fails to notify You of the
|
|
||||||
non-compliance by some reasonable means prior to 60 days after You have
|
|
||||||
come back into compliance. Moreover, Your grants from a particular
|
|
||||||
Contributor are reinstated on an ongoing basis if such Contributor
|
|
||||||
notifies You of the non-compliance by some reasonable means, this is the
|
|
||||||
first time You have received notice of non-compliance with this License
|
|
||||||
from such Contributor, and You become compliant prior to 30 days after
|
|
||||||
Your receipt of the notice.
|
|
||||||
|
|
||||||
5.2. If You initiate litigation against any entity by asserting a patent
|
|
||||||
infringement claim (excluding declaratory judgment actions,
|
|
||||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
|
||||||
directly or indirectly infringes any patent, then the rights granted to
|
|
||||||
You by any and all Contributors for the Covered Software under Section
|
|
||||||
2.1 of this License shall terminate.
|
|
||||||
|
|
||||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
|
||||||
end user license agreements (excluding distributors and resellers) which
|
|
||||||
have been validly granted by You or Your distributors under this License
|
|
||||||
prior to termination shall survive termination.
|
|
||||||
|
|
||||||
************************************************************************
|
|
||||||
* *
|
|
||||||
* 6. Disclaimer of Warranty *
|
|
||||||
* ------------------------- *
|
|
||||||
* *
|
|
||||||
* Covered Software is provided under this License on an "as is" *
|
|
||||||
* basis, without warranty of any kind, either expressed, implied, or *
|
|
||||||
* statutory, including, without limitation, warranties that the *
|
|
||||||
* Covered Software is free of defects, merchantable, fit for a *
|
|
||||||
* particular purpose or non-infringing. The entire risk as to the *
|
|
||||||
* quality and performance of the Covered Software is with You. *
|
|
||||||
* Should any Covered Software prove defective in any respect, You *
|
|
||||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
|
||||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
|
||||||
* essential part of this License. No use of any Covered Software is *
|
|
||||||
* authorized under this License except under this disclaimer. *
|
|
||||||
* *
|
|
||||||
************************************************************************
|
|
||||||
|
|
||||||
************************************************************************
|
|
||||||
* *
|
|
||||||
* 7. Limitation of Liability *
|
|
||||||
* -------------------------- *
|
|
||||||
* *
|
|
||||||
* Under no circumstances and under no legal theory, whether tort *
|
|
||||||
* (including negligence), contract, or otherwise, shall any *
|
|
||||||
* Contributor, or anyone who distributes Covered Software as *
|
|
||||||
* permitted above, be liable to You for any direct, indirect, *
|
|
||||||
* special, incidental, or consequential damages of any character *
|
|
||||||
* including, without limitation, damages for lost profits, loss of *
|
|
||||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
|
||||||
* and all other commercial damages or losses, even if such party *
|
|
||||||
* shall have been informed of the possibility of such damages. This *
|
|
||||||
* limitation of liability shall not apply to liability for death or *
|
|
||||||
* personal injury resulting from such party's negligence to the *
|
|
||||||
* extent applicable law prohibits such limitation. Some *
|
|
||||||
* jurisdictions do not allow the exclusion or limitation of *
|
|
||||||
* incidental or consequential damages, so this exclusion and *
|
|
||||||
* limitation may not apply to You. *
|
|
||||||
* *
|
|
||||||
************************************************************************
|
|
||||||
|
|
||||||
8. Litigation
|
|
||||||
-------------
|
|
||||||
|
|
||||||
Any litigation relating to this License may be brought only in the
|
|
||||||
courts of a jurisdiction where the defendant maintains its principal
|
|
||||||
place of business and such litigation shall be governed by laws of that
|
|
||||||
jurisdiction, without reference to its conflict-of-law provisions.
|
|
||||||
Nothing in this Section shall prevent a party's ability to bring
|
|
||||||
cross-claims or counter-claims.
|
|
||||||
|
|
||||||
9. Miscellaneous
|
|
||||||
----------------
|
|
||||||
|
|
||||||
This License represents the complete agreement concerning the subject
|
|
||||||
matter hereof. If any provision of this License is held to be
|
|
||||||
unenforceable, such provision shall be reformed only to the extent
|
|
||||||
necessary to make it enforceable. Any law or regulation which provides
|
|
||||||
that the language of a contract shall be construed against the drafter
|
|
||||||
shall not be used to construe this License against a Contributor.
|
|
||||||
|
|
||||||
10. Versions of the License
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
10.1. New Versions
|
|
||||||
|
|
||||||
Mozilla Foundation is the license steward. Except as provided in Section
|
|
||||||
10.3, no one other than the license steward has the right to modify or
|
|
||||||
publish new versions of this License. Each version will be given a
|
|
||||||
distinguishing version number.
|
|
||||||
|
|
||||||
10.2. Effect of New Versions
|
|
||||||
|
|
||||||
You may distribute the Covered Software under the terms of the version
|
|
||||||
of the License under which You originally received the Covered Software,
|
|
||||||
or under the terms of any subsequent version published by the license
|
|
||||||
steward.
|
|
||||||
|
|
||||||
10.3. Modified Versions
|
|
||||||
|
|
||||||
If you create software not governed by this License, and you want to
|
|
||||||
create a new license for such software, you may create and use a
|
|
||||||
modified version of this License if you rename the license and remove
|
|
||||||
any references to the name of the license steward (except to note that
|
|
||||||
such modified license differs from this License).
|
|
||||||
|
|
||||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
|
||||||
Licenses
|
|
||||||
|
|
||||||
If You choose to distribute Source Code Form that is Incompatible With
|
|
||||||
Secondary Licenses under the terms of this version of the License, the
|
|
||||||
notice described in Exhibit B of this License must be attached.
|
|
||||||
|
|
||||||
Exhibit A - Source Code Form License Notice
|
|
||||||
-------------------------------------------
|
|
||||||
|
|
||||||
This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
If it is not possible or desirable to put the notice in a particular
|
|
||||||
file, then You may include the notice in a location (such as a LICENSE
|
|
||||||
file in a relevant directory) where a recipient would be likely to look
|
|
||||||
for such a notice.
|
|
||||||
|
|
||||||
You may add additional accurate notices of copyright ownership.
|
|
||||||
|
|
||||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
|
||||||
---------------------------------------------------------
|
|
||||||
|
|
||||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
|
||||||
defined by the Mozilla Public License, v. 2.0.
|
|
|
@ -1,35 +0,0 @@
|
||||||
Rhino is licensed subject to the terms of the Mozilla Public License, v. 2.0.
|
|
||||||
See "License.txt" for the text of the license.
|
|
||||||
|
|
||||||
Rhino contains the following additional software:
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
Portions of the floating-point conversion code, and portions of the test suite
|
|
||||||
come from the Google V8 JavaScript engine and are subject to the following:
|
|
||||||
|
|
||||||
Copyright 2010-2015 the V8 project authors. 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 Google Inc. 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.
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.plugin.javascript;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.plugins.Plugin;
|
|
||||||
import org.elasticsearch.plugins.ScriptPlugin;
|
|
||||||
import org.elasticsearch.script.ScriptEngineRegistry;
|
|
||||||
import org.elasticsearch.script.ScriptEngineService;
|
|
||||||
import org.elasticsearch.script.ScriptModule;
|
|
||||||
import org.elasticsearch.script.javascript.JavaScriptScriptEngineService;
|
|
||||||
|
|
||||||
public class JavaScriptPlugin extends Plugin implements ScriptPlugin {
|
|
||||||
|
|
||||||
static {
|
|
||||||
// install rhino policy on plugin init
|
|
||||||
JavaScriptScriptEngineService.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ScriptEngineService getScriptEngineService(Settings settings) {
|
|
||||||
return new JavaScriptScriptEngineService(settings);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,355 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.javascript;
|
|
||||||
|
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
|
||||||
import org.apache.lucene.search.Scorer;
|
|
||||||
import org.elasticsearch.SpecialPermission;
|
|
||||||
import org.elasticsearch.bootstrap.BootstrapInfo;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.script.ClassPermission;
|
|
||||||
import org.elasticsearch.script.CompiledScript;
|
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
|
||||||
import org.elasticsearch.script.LeafSearchScript;
|
|
||||||
import org.elasticsearch.script.ScoreAccessor;
|
|
||||||
import org.elasticsearch.script.ScriptEngineService;
|
|
||||||
import org.elasticsearch.script.SearchScript;
|
|
||||||
import org.elasticsearch.script.javascript.support.NativeList;
|
|
||||||
import org.elasticsearch.script.javascript.support.NativeMap;
|
|
||||||
import org.elasticsearch.script.javascript.support.ScriptValueConverter;
|
|
||||||
import org.elasticsearch.search.lookup.LeafSearchLookup;
|
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
|
||||||
import org.mozilla.javascript.Context;
|
|
||||||
import org.mozilla.javascript.ContextFactory;
|
|
||||||
import org.mozilla.javascript.GeneratedClassLoader;
|
|
||||||
import org.mozilla.javascript.PolicySecurityController;
|
|
||||||
import org.mozilla.javascript.Script;
|
|
||||||
import org.mozilla.javascript.Scriptable;
|
|
||||||
import org.mozilla.javascript.ScriptableObject;
|
|
||||||
import org.mozilla.javascript.SecurityController;
|
|
||||||
import org.mozilla.javascript.WrapFactory;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.security.AccessControlContext;
|
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.CodeSource;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.security.cert.Certificate;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
|
||||||
|
|
||||||
public class JavaScriptScriptEngineService extends AbstractComponent implements ScriptEngineService {
|
|
||||||
|
|
||||||
public static final String NAME = "javascript";
|
|
||||||
|
|
||||||
public static final String EXTENSION = "js";
|
|
||||||
|
|
||||||
private final AtomicLong counter = new AtomicLong();
|
|
||||||
|
|
||||||
private static WrapFactory wrapFactory = new CustomWrapFactory();
|
|
||||||
|
|
||||||
private Scriptable globalScope;
|
|
||||||
|
|
||||||
// one time initialization of rhino security manager integration
|
|
||||||
private static final CodeSource DOMAIN;
|
|
||||||
private static final int OPTIMIZATION_LEVEL = 1;
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
DOMAIN = new CodeSource(new URL("file:" + BootstrapInfo.UNTRUSTED_CODEBASE), (Certificate[]) null);
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
ContextFactory factory = new ContextFactory() {
|
|
||||||
@Override
|
|
||||||
protected void onContextCreated(Context cx) {
|
|
||||||
cx.setWrapFactory(wrapFactory);
|
|
||||||
cx.setOptimizationLevel(OPTIMIZATION_LEVEL);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (System.getSecurityManager() != null) {
|
|
||||||
factory.initApplicationClassLoader(AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
|
|
||||||
@Override
|
|
||||||
public ClassLoader run() {
|
|
||||||
// snapshot our context (which has permissions for classes), since the script has none
|
|
||||||
final AccessControlContext engineContext = AccessController.getContext();
|
|
||||||
return new ClassLoader(JavaScriptScriptEngineService.class.getClassLoader()) {
|
|
||||||
@Override
|
|
||||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
|
||||||
try {
|
|
||||||
engineContext.checkPermission(new ClassPermission(name));
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
throw new ClassNotFoundException(name, e);
|
|
||||||
}
|
|
||||||
return super.loadClass(name, resolve);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
factory.seal();
|
|
||||||
ContextFactory.initGlobal(factory);
|
|
||||||
SecurityController.initGlobal(new PolicySecurityController() {
|
|
||||||
@Override
|
|
||||||
public GeneratedClassLoader createClassLoader(ClassLoader parent, Object securityDomain) {
|
|
||||||
// don't let scripts compile other scripts
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
sm.checkPermission(new SpecialPermission());
|
|
||||||
}
|
|
||||||
// check the domain, this is all we allow
|
|
||||||
if (securityDomain != DOMAIN) {
|
|
||||||
throw new SecurityException("illegal securityDomain: " + securityDomain);
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.createClassLoader(parent, securityDomain);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** ensures this engine is initialized */
|
|
||||||
public static void init() {}
|
|
||||||
|
|
||||||
public JavaScriptScriptEngineService(Settings settings) {
|
|
||||||
super(settings);
|
|
||||||
|
|
||||||
deprecationLogger.deprecated("[javascript] scripts are deprecated, use [painless] scripts instead");
|
|
||||||
|
|
||||||
Context ctx = Context.enter();
|
|
||||||
try {
|
|
||||||
globalScope = ctx.initStandardObjects(null, true);
|
|
||||||
} finally {
|
|
||||||
Context.exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
// Nothing to do here
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType() {
|
|
||||||
return NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getExtension() {
|
|
||||||
return EXTENSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
|
|
||||||
Context ctx = Context.enter();
|
|
||||||
try {
|
|
||||||
return ctx.compileString(scriptSource, generateScriptName(), 1, DOMAIN);
|
|
||||||
} finally {
|
|
||||||
Context.exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExecutableScript executable(CompiledScript compiledScript, @Nullable Map<String, Object> vars) {
|
|
||||||
deprecationLogger.deprecated("[javascript] scripts are deprecated, use [painless] scripts instead");
|
|
||||||
|
|
||||||
Context ctx = Context.enter();
|
|
||||||
try {
|
|
||||||
Scriptable scope = ctx.newObject(globalScope);
|
|
||||||
scope.setPrototype(globalScope);
|
|
||||||
scope.setParentScope(null);
|
|
||||||
if (vars != null) {
|
|
||||||
for (Map.Entry<String, Object> entry : vars.entrySet()) {
|
|
||||||
ScriptableObject.putProperty(scope, entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new JavaScriptExecutableScript((Script) compiledScript.compiled(), scope);
|
|
||||||
} finally {
|
|
||||||
Context.exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SearchScript search(final CompiledScript compiledScript, final SearchLookup lookup, @Nullable final Map<String, Object> vars) {
|
|
||||||
deprecationLogger.deprecated("[javascript] scripts are deprecated, use [painless] scripts instead");
|
|
||||||
|
|
||||||
Context ctx = Context.enter();
|
|
||||||
try {
|
|
||||||
final Scriptable scope = ctx.newObject(globalScope);
|
|
||||||
scope.setPrototype(globalScope);
|
|
||||||
scope.setParentScope(null);
|
|
||||||
|
|
||||||
return new SearchScript() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
|
|
||||||
final LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
|
|
||||||
for (Map.Entry<String, Object> entry : leafLookup.asMap().entrySet()) {
|
|
||||||
ScriptableObject.putProperty(scope, entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vars != null) {
|
|
||||||
for (Map.Entry<String, Object> entry : vars.entrySet()) {
|
|
||||||
ScriptableObject.putProperty(scope, entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new JavaScriptSearchScript((Script) compiledScript.compiled(), scope, leafLookup);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean needsScores() {
|
|
||||||
// TODO: can we reliably know if a javascript script makes use of _score
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} finally {
|
|
||||||
Context.exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String generateScriptName() {
|
|
||||||
return "Script" + counter.incrementAndGet() + ".js";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class JavaScriptExecutableScript implements ExecutableScript {
|
|
||||||
|
|
||||||
private final Script script;
|
|
||||||
|
|
||||||
private final Scriptable scope;
|
|
||||||
|
|
||||||
public JavaScriptExecutableScript(Script script, Scriptable scope) {
|
|
||||||
this.script = script;
|
|
||||||
this.scope = scope;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object run() {
|
|
||||||
Context ctx = Context.enter();
|
|
||||||
try {
|
|
||||||
return ScriptValueConverter.unwrapValue(script.exec(ctx, scope));
|
|
||||||
} finally {
|
|
||||||
Context.exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNextVar(String name, Object value) {
|
|
||||||
ScriptableObject.putProperty(scope, name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object unwrap(Object value) {
|
|
||||||
return ScriptValueConverter.unwrapValue(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class JavaScriptSearchScript implements LeafSearchScript {
|
|
||||||
|
|
||||||
private final Script script;
|
|
||||||
|
|
||||||
private final Scriptable scope;
|
|
||||||
|
|
||||||
private final LeafSearchLookup lookup;
|
|
||||||
|
|
||||||
public JavaScriptSearchScript(Script script, Scriptable scope, LeafSearchLookup lookup) {
|
|
||||||
this.script = script;
|
|
||||||
this.scope = scope;
|
|
||||||
this.lookup = lookup;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setScorer(Scorer scorer) {
|
|
||||||
Context ctx = Context.enter();
|
|
||||||
try {
|
|
||||||
ScriptableObject.putProperty(scope, "_score", wrapFactory.wrapAsJavaObject(ctx, scope, new ScoreAccessor(scorer), ScoreAccessor.class));
|
|
||||||
} finally {
|
|
||||||
Context.exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDocument(int doc) {
|
|
||||||
lookup.setDocument(doc);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNextVar(String name, Object value) {
|
|
||||||
ScriptableObject.putProperty(scope, name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSource(Map<String, Object> source) {
|
|
||||||
lookup.source().setSource(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object run() {
|
|
||||||
Context ctx = Context.enter();
|
|
||||||
try {
|
|
||||||
return ScriptValueConverter.unwrapValue(script.exec(ctx, scope));
|
|
||||||
} finally {
|
|
||||||
Context.exit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long runAsLong() {
|
|
||||||
return ((Number) run()).longValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double runAsDouble() {
|
|
||||||
return ((Number) run()).doubleValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object unwrap(Object value) {
|
|
||||||
return ScriptValueConverter.unwrapValue(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrap Factory for Rhino Script Engine
|
|
||||||
*/
|
|
||||||
public static class CustomWrapFactory extends WrapFactory {
|
|
||||||
|
|
||||||
public CustomWrapFactory() {
|
|
||||||
setJavaPrimitiveWrap(false); // RingoJS does that..., claims its annoying...
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Scriptable wrapAsJavaObject(Context cx, Scriptable scope, Object javaObject, Class<?> staticType) {
|
|
||||||
if (javaObject instanceof Map) {
|
|
||||||
return NativeMap.wrap(scope, (Map<Object, Object>) javaObject);
|
|
||||||
}
|
|
||||||
if (javaObject instanceof List) {
|
|
||||||
return NativeList.wrap(scope, (List<Object>) javaObject, staticType);
|
|
||||||
}
|
|
||||||
return super.wrapAsJavaObject(cx, scope, javaObject, staticType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,145 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.javascript.support;
|
|
||||||
|
|
||||||
import org.mozilla.javascript.NativeJavaObject;
|
|
||||||
import org.mozilla.javascript.Scriptable;
|
|
||||||
import org.mozilla.javascript.Undefined;
|
|
||||||
import org.mozilla.javascript.Wrapper;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class NativeList extends NativeJavaObject implements Scriptable, Wrapper {
|
|
||||||
private static final String LENGTH_PROPERTY = "length";
|
|
||||||
|
|
||||||
private final List<Object> list;
|
|
||||||
|
|
||||||
|
|
||||||
public static NativeList wrap(Scriptable scope, List<Object> list, Class<?> staticType) {
|
|
||||||
return new NativeList(scope, list, staticType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private NativeList(Scriptable scope, List<Object> list, Class<?> staticType) {
|
|
||||||
super(scope, list, staticType);
|
|
||||||
this.list = list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.mozilla.javascript.Wrapper#unwrap()
|
|
||||||
*/
|
|
||||||
|
|
||||||
public Object unwrap() {
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.mozilla.javascript.Scriptable#getClassName()
|
|
||||||
*/
|
|
||||||
|
|
||||||
public String getClassName() {
|
|
||||||
return "NativeList";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.mozilla.javascript.Scriptable#get(java.lang.String, org.mozilla.javascript.Scriptable)
|
|
||||||
*/
|
|
||||||
|
|
||||||
public Object get(String name, Scriptable start) {
|
|
||||||
if (LENGTH_PROPERTY.equals(name)) {
|
|
||||||
return list.size();
|
|
||||||
} else {
|
|
||||||
return super.get(name, start);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.mozilla.javascript.Scriptable#get(int, org.mozilla.javascript.Scriptable)
|
|
||||||
*/
|
|
||||||
|
|
||||||
public Object get(int index, Scriptable start) {
|
|
||||||
if (has(index, start) == false) {
|
|
||||||
return Undefined.instance;
|
|
||||||
}
|
|
||||||
return list.get(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.mozilla.javascript.Scriptable#has(java.lang.String, org.mozilla.javascript.Scriptable)
|
|
||||||
*/
|
|
||||||
|
|
||||||
public boolean has(String name, Scriptable start) {
|
|
||||||
return super.has(name, start) || LENGTH_PROPERTY.equals(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.mozilla.javascript.Scriptable#has(int, org.mozilla.javascript.Scriptable)
|
|
||||||
*/
|
|
||||||
|
|
||||||
public boolean has(int index, Scriptable start) {
|
|
||||||
return index >= 0 && index < list.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.mozilla.javascript.Scriptable#put(int, org.mozilla.javascript.Scriptable, java.lang.Object)
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void put(int index, Scriptable start, Object value) {
|
|
||||||
if (index == list.size()) {
|
|
||||||
list.add(value);
|
|
||||||
} else {
|
|
||||||
list.set(index, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.mozilla.javascript.Scriptable#delete(int)
|
|
||||||
*/
|
|
||||||
|
|
||||||
public void delete(int index) {
|
|
||||||
list.remove(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.mozilla.javascript.Scriptable#getIds()
|
|
||||||
*/
|
|
||||||
|
|
||||||
public Object[] getIds() {
|
|
||||||
final Object[] javaObjectIds = super.getIds();
|
|
||||||
final int size = list.size();
|
|
||||||
final Object[] ids = Arrays.copyOf(javaObjectIds, javaObjectIds.length + size);
|
|
||||||
for (int i = 0; i < size; ++i) {
|
|
||||||
ids[javaObjectIds.length + i] = i;
|
|
||||||
}
|
|
||||||
return ids;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.mozilla.javascript.Scriptable#hasInstance(org.mozilla.javascript.Scriptable)
|
|
||||||
*/
|
|
||||||
|
|
||||||
public boolean hasInstance(Scriptable value) {
|
|
||||||
if (!(value instanceof Wrapper))
|
|
||||||
return false;
|
|
||||||
Object instance = ((Wrapper) value).unwrap();
|
|
||||||
return List.class.isInstance(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,164 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.javascript.support;
|
|
||||||
|
|
||||||
import org.mozilla.javascript.Scriptable;
|
|
||||||
import org.mozilla.javascript.Wrapper;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper for exposing maps in Rhino scripts.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class NativeMap implements Scriptable, Wrapper {
|
|
||||||
private Map<Object, Object> map;
|
|
||||||
private Scriptable parentScope;
|
|
||||||
private Scriptable prototype;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct
|
|
||||||
*
|
|
||||||
* @return native map
|
|
||||||
*/
|
|
||||||
public static NativeMap wrap(Scriptable scope, Map<Object, Object> map) {
|
|
||||||
return new NativeMap(scope, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct
|
|
||||||
*/
|
|
||||||
private NativeMap(Scriptable scope, Map<Object, Object> map) {
|
|
||||||
this.parentScope = scope;
|
|
||||||
this.map = map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object unwrap() {
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getClassName() {
|
|
||||||
return "NativeMap";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object get(String name, Scriptable start) {
|
|
||||||
// get the property from the underlying QName map
|
|
||||||
if ("length".equals(name)) {
|
|
||||||
return map.size();
|
|
||||||
} else {
|
|
||||||
return map.get(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object get(int index, Scriptable start) {
|
|
||||||
Object value = null;
|
|
||||||
int i = 0;
|
|
||||||
Iterator<Object> itrValues = map.values().iterator();
|
|
||||||
while (i++ <= index && itrValues.hasNext()) {
|
|
||||||
value = itrValues.next();
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean has(String name, Scriptable start) {
|
|
||||||
// locate the property in the underlying map
|
|
||||||
return map.containsKey(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean has(int index, Scriptable start) {
|
|
||||||
return (index >= 0 && map.values().size() > index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void put(String name, Scriptable start, Object value) {
|
|
||||||
map.put(name, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void put(int index, Scriptable start, Object value) {
|
|
||||||
// TODO: implement?
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete(String name) {
|
|
||||||
map.remove(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete(int index) {
|
|
||||||
int i = 0;
|
|
||||||
Iterator<Object> itrKeys = map.keySet().iterator();
|
|
||||||
while (i <= index && itrKeys.hasNext()) {
|
|
||||||
Object key = itrKeys.next();
|
|
||||||
if (i == index) {
|
|
||||||
map.remove(key);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Scriptable getPrototype() {
|
|
||||||
return this.prototype;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPrototype(Scriptable prototype) {
|
|
||||||
this.prototype = prototype;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Scriptable getParentScope() {
|
|
||||||
return this.parentScope;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setParentScope(Scriptable parent) {
|
|
||||||
this.parentScope = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object[] getIds() {
|
|
||||||
return map.keySet().toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getDefaultValue(Class<?> hint) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasInstance(Scriptable value) {
|
|
||||||
if (!(value instanceof Wrapper))
|
|
||||||
return false;
|
|
||||||
Object instance = ((Wrapper) value).unwrap();
|
|
||||||
return Map.class.isInstance(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,197 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.javascript.support;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.mozilla.javascript.Context;
|
|
||||||
import org.mozilla.javascript.IdScriptableObject;
|
|
||||||
import org.mozilla.javascript.NativeArray;
|
|
||||||
import org.mozilla.javascript.ScriptRuntime;
|
|
||||||
import org.mozilla.javascript.Scriptable;
|
|
||||||
import org.mozilla.javascript.Wrapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Value Converter to marshal objects between Java and Javascript.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public final class ScriptValueConverter {
|
|
||||||
private static final String TYPE_DATE = "Date";
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Private constructor - methods are static
|
|
||||||
*/
|
|
||||||
private ScriptValueConverter() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert an object from a script wrapper value to a serializable value valid outside
|
|
||||||
* of the Rhino script processor context.
|
|
||||||
* <p>
|
|
||||||
* This includes converting JavaScript Array objects to Lists of valid objects.
|
|
||||||
*
|
|
||||||
* @param value Value to convert from script wrapper object to external object value.
|
|
||||||
* @return unwrapped and converted value.
|
|
||||||
*/
|
|
||||||
public static Object unwrapValue(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
} else if (value instanceof Wrapper) {
|
|
||||||
// unwrap a Java object from a JavaScript wrapper
|
|
||||||
// recursively call this method to convert the unwrapped value
|
|
||||||
value = unwrapValue(((Wrapper) value).unwrap());
|
|
||||||
} else if (value instanceof IdScriptableObject) {
|
|
||||||
// check for special case Native object wrappers
|
|
||||||
String className = ((IdScriptableObject) value).getClassName();
|
|
||||||
// check for special case of the String object
|
|
||||||
if ("String".equals(className)) {
|
|
||||||
value = Context.jsToJava(value, String.class);
|
|
||||||
}
|
|
||||||
// check for special case of a Date object
|
|
||||||
else if ("Date".equals(className)) {
|
|
||||||
value = Context.jsToJava(value, Date.class);
|
|
||||||
} else {
|
|
||||||
// a scriptable object will probably indicate a multi-value property set
|
|
||||||
// set using a JavaScript associative Array object
|
|
||||||
Scriptable values = (Scriptable) value;
|
|
||||||
Object[] propIds = values.getIds();
|
|
||||||
|
|
||||||
// is it a JavaScript associative Array object using Integer indexes?
|
|
||||||
if (values instanceof NativeArray && isArray(propIds)) {
|
|
||||||
// convert JavaScript array of values to a List of Serializable objects
|
|
||||||
List<Object> propValues = new ArrayList<Object>(propIds.length);
|
|
||||||
for (int i = 0; i < propIds.length; i++) {
|
|
||||||
// work on each key in turn
|
|
||||||
Integer propId = (Integer) propIds[i];
|
|
||||||
|
|
||||||
// we are only interested in keys that indicate a list of values
|
|
||||||
if (propId instanceof Integer) {
|
|
||||||
// get the value out for the specified key
|
|
||||||
Object val = values.get(propId, values);
|
|
||||||
// recursively call this method to convert the value
|
|
||||||
propValues.add(unwrapValue(val));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
value = propValues;
|
|
||||||
} else {
|
|
||||||
// any other JavaScript object that supports properties - convert to a Map of objects
|
|
||||||
Map<String, Object> propValues = new HashMap<String, Object>(propIds.length);
|
|
||||||
for (int i = 0; i < propIds.length; i++) {
|
|
||||||
// work on each key in turn
|
|
||||||
Object propId = propIds[i];
|
|
||||||
|
|
||||||
// we are only interested in keys that indicate a list of values
|
|
||||||
if (propId instanceof String) {
|
|
||||||
// get the value out for the specified key
|
|
||||||
Object val = values.get((String) propId, values);
|
|
||||||
// recursively call this method to convert the value
|
|
||||||
propValues.put((String) propId, unwrapValue(val));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
value = propValues;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (value instanceof Object[]) {
|
|
||||||
// convert back a list Object Java values
|
|
||||||
Object[] array = (Object[]) value;
|
|
||||||
ArrayList<Object> list = new ArrayList<Object>(array.length);
|
|
||||||
for (int i = 0; i < array.length; i++) {
|
|
||||||
list.add(unwrapValue(array[i]));
|
|
||||||
}
|
|
||||||
value = list;
|
|
||||||
} else if (value instanceof Map) {
|
|
||||||
// ensure each value in the Map is unwrapped (which may have been an unwrapped NativeMap!)
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Map<Object, Object> map = (Map<Object, Object>) value;
|
|
||||||
Map<Object, Object> copyMap = new HashMap<Object, Object>(map.size());
|
|
||||||
for (Object key : map.keySet()) {
|
|
||||||
copyMap.put(key, unwrapValue(map.get(key)));
|
|
||||||
}
|
|
||||||
value = copyMap;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert an object from any repository serialized value to a valid script object.
|
|
||||||
* This includes converting Collection multi-value properties into JavaScript Array objects.
|
|
||||||
*
|
|
||||||
* @param scope Scripting scope
|
|
||||||
* @param value Property value
|
|
||||||
* @return Value safe for scripting usage
|
|
||||||
*/
|
|
||||||
public static Object wrapValue(Scriptable scope, Object value) {
|
|
||||||
// perform conversions from Java objects to JavaScript scriptable instances
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
} else if (value instanceof Date) {
|
|
||||||
// convert Date to JavaScript native Date object
|
|
||||||
// call the "Date" constructor on the root scope object - passing in the millisecond
|
|
||||||
// value from the Java date - this will construct a JavaScript Date with the same value
|
|
||||||
Date date = (Date) value;
|
|
||||||
value = ScriptRuntime.newObject(
|
|
||||||
Context.getCurrentContext(), scope, TYPE_DATE, new Object[]{date.getTime()});
|
|
||||||
} else if (value instanceof Collection) {
|
|
||||||
// recursively convert each value in the collection
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Collection<Object> collection = (Collection<Object>) value;
|
|
||||||
Object[] array = new Object[collection.size()];
|
|
||||||
int index = 0;
|
|
||||||
for (Object obj : collection) {
|
|
||||||
array[index++] = wrapValue(scope, obj);
|
|
||||||
}
|
|
||||||
// convert array to a native JavaScript Array
|
|
||||||
value = Context.getCurrentContext().newArray(scope, array);
|
|
||||||
} else if (value instanceof Map) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Map<Object, Object> map = (Map<Object, Object>) value;
|
|
||||||
value = NativeMap.wrap(scope, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
// simple numbers, strings and booleans are wrapped automatically by Rhino
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Look at the id's of a native array and try to determine whether it's actually an Array or a Hashmap
|
|
||||||
*
|
|
||||||
* @param ids id's of the native array
|
|
||||||
* @return boolean true if it's an array, false otherwise (ie it's a map)
|
|
||||||
*/
|
|
||||||
private static boolean isArray(final Object[] ids) {
|
|
||||||
boolean result = true;
|
|
||||||
for (int i = 0; i < ids.length; i++) {
|
|
||||||
if (ids[i] instanceof Integer == false) {
|
|
||||||
result = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,202 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.javascript.support;
|
|
||||||
|
|
||||||
import org.mozilla.javascript.Scriptable;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of a Scriptable Map. This is the best choice for maps that want to represent
|
|
||||||
* JavaScript associative arrays - allowing access via key and integer index. It maintains and
|
|
||||||
* respects insertion order of the elements and allows either string or integer keys.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ScriptableLinkedHashMap<K, V> extends LinkedHashMap<K, V> implements ScriptableMap<K, V> {
|
|
||||||
private Scriptable parentScope;
|
|
||||||
private Scriptable prototype;
|
|
||||||
|
|
||||||
|
|
||||||
public ScriptableLinkedHashMap() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScriptableLinkedHashMap(int initialCapacity) {
|
|
||||||
super(initialCapacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScriptableLinkedHashMap(Map<K, V> source) {
|
|
||||||
super(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#getClassName()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String getClassName() {
|
|
||||||
return "ScriptableMap";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#get(java.lang.String, org.mozilla.javascript.Scriptable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Object get(String name, Scriptable start) {
|
|
||||||
// get the property from the underlying QName map
|
|
||||||
if ("length".equals(name)) {
|
|
||||||
return this.size();
|
|
||||||
} else {
|
|
||||||
return get(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#get(int, org.mozilla.javascript.Scriptable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Object get(int index, Scriptable start) {
|
|
||||||
Object value = null;
|
|
||||||
int i = 0;
|
|
||||||
Iterator<V> itrValues = this.values().iterator();
|
|
||||||
while (i++ <= index && itrValues.hasNext()) {
|
|
||||||
value = itrValues.next();
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#has(java.lang.String, org.mozilla.javascript.Scriptable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean has(String name, Scriptable start) {
|
|
||||||
// locate the property in the underlying map
|
|
||||||
return containsKey(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#has(int, org.mozilla.javascript.Scriptable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean has(int index, Scriptable start) {
|
|
||||||
return (index >= 0 && this.values().size() > index);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#put(java.lang.String, org.mozilla.javascript.Scriptable, java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void put(String name, Scriptable start, Object value) {
|
|
||||||
// add the property to the underlying QName map
|
|
||||||
put((K) name, (V) value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#put(int, org.mozilla.javascript.Scriptable, java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void put(int index, Scriptable start, Object value) {
|
|
||||||
// TODO: implement?
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#delete(java.lang.String)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void delete(String name) {
|
|
||||||
// remove the property from the underlying QName map
|
|
||||||
remove(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#delete(int)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void delete(int index) {
|
|
||||||
int i = 0;
|
|
||||||
Iterator<K> itrKeys = this.keySet().iterator();
|
|
||||||
while (i <= index && itrKeys.hasNext()) {
|
|
||||||
Object key = itrKeys.next();
|
|
||||||
if (i == index) {
|
|
||||||
remove(key);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#getPrototype()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Scriptable getPrototype() {
|
|
||||||
return this.prototype;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#setPrototype(org.mozilla.javascript.Scriptable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setPrototype(Scriptable prototype) {
|
|
||||||
this.prototype = prototype;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#getParentScope()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Scriptable getParentScope() {
|
|
||||||
return this.parentScope;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#setParentScope(org.mozilla.javascript.Scriptable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void setParentScope(Scriptable parent) {
|
|
||||||
this.parentScope = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#getIds()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Object[] getIds() {
|
|
||||||
return keySet().toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#getDefaultValue(java.lang.Class)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Object getDefaultValue(Class<?> hint) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.mozilla.javascript.Scriptable#hasInstance(org.mozilla.javascript.Scriptable)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public boolean hasInstance(Scriptable instance) {
|
|
||||||
return instance instanceof ScriptableLinkedHashMap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.javascript.support;
|
|
||||||
|
|
||||||
import org.mozilla.javascript.Scriptable;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Contract to be implemented by classes providing Map like collections to JavaScript.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface ScriptableMap<K, V> extends Scriptable, Map<K, V> {
|
|
||||||
}
|
|
|
@ -1,241 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.javascript.support;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.mozilla.javascript.Scriptable;
|
|
||||||
import org.mozilla.javascript.Wrapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of a Scriptable Map. This is the best choice where you want values to be
|
|
||||||
* persisted directly to an underlying map supplied on construction. The class automatically
|
|
||||||
* wraps/unwraps JS objects as they enter/leave the underlying map via the Scriptable interface
|
|
||||||
* methods - objects are untouched if accessed via the usual Map interface methods.
|
|
||||||
* <p>Access should be by string key only - not integer index - unless you are sure the wrapped
|
|
||||||
* map will maintain insertion order of the elements.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ScriptableWrappedMap implements ScriptableMap<Object, Object>, Wrapper {
|
|
||||||
private Map<Object, Object> map;
|
|
||||||
private Scriptable parentScope;
|
|
||||||
private Scriptable prototype;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construction
|
|
||||||
* @return scriptable wrapped map
|
|
||||||
*/
|
|
||||||
public static ScriptableWrappedMap wrap(Scriptable scope, Map<Object, Object> map) {
|
|
||||||
return new ScriptableWrappedMap(scope, map);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct
|
|
||||||
*/
|
|
||||||
public ScriptableWrappedMap(Map<Object, Object> map) {
|
|
||||||
this.map = map;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct
|
|
||||||
*/
|
|
||||||
public ScriptableWrappedMap(Scriptable scope, Map<Object, Object> map) {
|
|
||||||
this.parentScope = scope;
|
|
||||||
this.map = map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object unwrap() {
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getClassName() {
|
|
||||||
return "ScriptableWrappedMap";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object get(String name, Scriptable start) {
|
|
||||||
// get the property from the underlying QName map
|
|
||||||
if ("length".equals(name)) {
|
|
||||||
return map.size();
|
|
||||||
} else {
|
|
||||||
return ScriptValueConverter.wrapValue(this.parentScope != null ? this.parentScope : start, map.get(name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object get(int index, Scriptable start) {
|
|
||||||
Object value = null;
|
|
||||||
int i = 0;
|
|
||||||
Iterator<Object> itrValues = map.values().iterator();
|
|
||||||
while (i++ <= index && itrValues.hasNext()) {
|
|
||||||
value = itrValues.next();
|
|
||||||
}
|
|
||||||
return ScriptValueConverter.wrapValue(this.parentScope != null ? this.parentScope : start, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean has(String name, Scriptable start) {
|
|
||||||
// locate the property in the underlying map
|
|
||||||
return map.containsKey(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean has(int index, Scriptable start) {
|
|
||||||
return (index >= 0 && map.values().size() > index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void put(String name, Scriptable start, Object value) {
|
|
||||||
map.put(name, ScriptValueConverter.unwrapValue(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void put(int index, Scriptable start, Object value) {
|
|
||||||
// TODO: implement?
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete(String name) {
|
|
||||||
map.remove(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete(int index) {
|
|
||||||
int i = 0;
|
|
||||||
Iterator<Object> itrKeys = map.keySet().iterator();
|
|
||||||
while (i <= index && itrKeys.hasNext()) {
|
|
||||||
Object key = itrKeys.next();
|
|
||||||
if (i == index) {
|
|
||||||
map.remove(key);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Scriptable getPrototype() {
|
|
||||||
return this.prototype;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setPrototype(Scriptable prototype) {
|
|
||||||
this.prototype = prototype;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Scriptable getParentScope() {
|
|
||||||
return this.parentScope;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setParentScope(Scriptable parent) {
|
|
||||||
this.parentScope = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object[] getIds() {
|
|
||||||
return map.keySet().toArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getDefaultValue(Class<?> hint) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasInstance(Scriptable value) {
|
|
||||||
if (!(value instanceof Wrapper))
|
|
||||||
return false;
|
|
||||||
Object instance = ((Wrapper) value).unwrap();
|
|
||||||
return Map.class.isInstance(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void clear() {
|
|
||||||
this.map.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean containsKey(Object key) {
|
|
||||||
return this.map.containsKey(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean containsValue(Object value) {
|
|
||||||
return this.map.containsValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Map.Entry<Object, Object>> entrySet() {
|
|
||||||
return this.map.entrySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object get(Object key) {
|
|
||||||
return this.map.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return (this.map.size() == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Object> keySet() {
|
|
||||||
return this.map.keySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object put(Object key, Object value) {
|
|
||||||
return this.map.put(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void putAll(Map<? extends Object, ? extends Object> t) {
|
|
||||||
this.map.putAll(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object remove(Object key) {
|
|
||||||
return this.map.remove(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
return this.map.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Object> values() {
|
|
||||||
return this.map.values();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return (this.map != null ? this.map.toString() : super.toString());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
grant {
|
|
||||||
// needed to generate runtime classes
|
|
||||||
permission java.lang.RuntimePermission "createClassLoader";
|
|
||||||
|
|
||||||
// Standard set of classes
|
|
||||||
permission org.elasticsearch.script.ClassPermission "<<STANDARD>>";
|
|
||||||
// rhino runtime (TODO: clean these up if possible)
|
|
||||||
permission org.elasticsearch.script.ClassPermission "org.mozilla.javascript.ContextFactory";
|
|
||||||
permission org.elasticsearch.script.ClassPermission "org.mozilla.javascript.Callable";
|
|
||||||
permission org.elasticsearch.script.ClassPermission "org.mozilla.javascript.NativeFunction";
|
|
||||||
permission org.elasticsearch.script.ClassPermission "org.mozilla.javascript.Script";
|
|
||||||
permission org.elasticsearch.script.ClassPermission "org.mozilla.javascript.ScriptRuntime";
|
|
||||||
permission org.elasticsearch.script.ClassPermission "org.mozilla.javascript.Undefined";
|
|
||||||
permission org.elasticsearch.script.ClassPermission "org.mozilla.javascript.optimizer.OptRuntime";
|
|
||||||
};
|
|
|
@ -1,188 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.javascript;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static java.util.Collections.emptyMap;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.collect.MapBuilder;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.script.CompiledScript;
|
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
|
||||||
import org.elasticsearch.script.ScriptType;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
|
||||||
|
|
||||||
public class JavaScriptScriptEngineTests extends ESTestCase {
|
|
||||||
private JavaScriptScriptEngineService se;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() {
|
|
||||||
se = new JavaScriptScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void close() {
|
|
||||||
se.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSimpleEquation() {
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
Object o = se.executable(new CompiledScript(ScriptType.INLINE, "testSimpleEquation", "js", se.compile(null, "1 + 2", Collections.emptyMap())), vars).run();
|
|
||||||
assertThat(((Number) o).intValue(), equalTo(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testNullVars() {
|
|
||||||
CompiledScript script = new CompiledScript(ScriptType.INLINE, "testSimpleEquation", "js",
|
|
||||||
se.compile(null, "1 + 2", emptyMap()));
|
|
||||||
Object o = se.executable(script, null).run();
|
|
||||||
assertThat(((Number) o).intValue(), equalTo(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void testMapAccess() {
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
|
|
||||||
Map<String, Object> obj2 = MapBuilder.<String, Object>newMapBuilder().put("prop2", "value2").map();
|
|
||||||
Map<String, Object> obj1 = MapBuilder.<String, Object>newMapBuilder().put("prop1", "value1").put("obj2", obj2).put("l", Arrays.asList("2", "1")).map();
|
|
||||||
vars.put("obj1", obj1);
|
|
||||||
Object o = se.executable(new CompiledScript(ScriptType.INLINE, "testMapAccess", "js", se.compile(null, "obj1", Collections.emptyMap())), vars).run();
|
|
||||||
assertThat(o, instanceOf(Map.class));
|
|
||||||
obj1 = (Map<String, Object>) o;
|
|
||||||
assertThat((String) obj1.get("prop1"), equalTo("value1"));
|
|
||||||
assertThat((String) ((Map<String, Object>) obj1.get("obj2")).get("prop2"), equalTo("value2"));
|
|
||||||
|
|
||||||
o = se.executable(new CompiledScript(ScriptType.INLINE, "testMapAccess", "js", se.compile(null, "obj1.l[0]", Collections.emptyMap())), vars).run();
|
|
||||||
assertThat(((String) o), equalTo("2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void testJavaScriptObjectToMap() {
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
Object o = se.executable(new CompiledScript(ScriptType.INLINE, "testJavaScriptObjectToMap", "js",
|
|
||||||
se.compile(null, "var obj1 = {}; obj1.prop1 = 'value1'; obj1.obj2 = {}; obj1.obj2.prop2 = 'value2'; obj1", Collections.emptyMap())), vars).run();
|
|
||||||
Map<String, Object> obj1 = (Map<String, Object>) o;
|
|
||||||
assertThat((String) obj1.get("prop1"), equalTo("value1"));
|
|
||||||
assertThat((String) ((Map<String, Object>) obj1.get("obj2")).get("prop2"), equalTo("value2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void testJavaScriptObjectMapInter() {
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
Map<String, Object> ctx = new HashMap<String, Object>();
|
|
||||||
Map<String, Object> obj1 = new HashMap<String, Object>();
|
|
||||||
obj1.put("prop1", "value1");
|
|
||||||
ctx.put("obj1", obj1);
|
|
||||||
vars.put("ctx", ctx);
|
|
||||||
|
|
||||||
ExecutableScript executable = se.executable(new CompiledScript(ScriptType.INLINE, "testJavaScriptObjectMapInter", "js",
|
|
||||||
se.compile(null, "ctx.obj2 = {}; ctx.obj2.prop2 = 'value2'; ctx.obj1.prop1 = 'uvalue1'", Collections.emptyMap())), vars);
|
|
||||||
executable.run();
|
|
||||||
ctx = (Map<String, Object>) executable.unwrap(vars.get("ctx"));
|
|
||||||
assertThat(ctx.containsKey("obj1"), equalTo(true));
|
|
||||||
assertThat((String) ((Map<String, Object>) ctx.get("obj1")).get("prop1"), equalTo("uvalue1"));
|
|
||||||
assertThat(ctx.containsKey("obj2"), equalTo(true));
|
|
||||||
assertThat((String) ((Map<String, Object>) ctx.get("obj2")).get("prop2"), equalTo("value2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void testJavaScriptInnerArrayCreation() {
|
|
||||||
Map<String, Object> ctx = new HashMap<String, Object>();
|
|
||||||
Map<String, Object> doc = new HashMap<String, Object>();
|
|
||||||
ctx.put("doc", doc);
|
|
||||||
|
|
||||||
Object compiled = se.compile(null, "ctx.doc.field1 = ['value1', 'value2']", Collections.emptyMap());
|
|
||||||
ExecutableScript script = se.executable(new CompiledScript(ScriptType.INLINE, "testJavaScriptInnerArrayCreation", "js",
|
|
||||||
compiled), new HashMap<String, Object>());
|
|
||||||
script.setNextVar("ctx", ctx);
|
|
||||||
script.run();
|
|
||||||
|
|
||||||
Map<String, Object> unwrap = (Map<String, Object>) script.unwrap(ctx);
|
|
||||||
|
|
||||||
assertThat(((Map<String, Object>) unwrap.get("doc")).get("field1"), instanceOf(List.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void testAccessListInScript() {
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
Map<String, Object> obj2 = MapBuilder.<String, Object>newMapBuilder().put("prop2", "value2").map();
|
|
||||||
Map<String, Object> obj1 = MapBuilder.<String, Object>newMapBuilder().put("prop1", "value1").put("obj2", obj2).map();
|
|
||||||
vars.put("l", Arrays.asList("1", "2", "3", obj1));
|
|
||||||
|
|
||||||
Object o = se.executable(new CompiledScript(ScriptType.INLINE, "testAccessInScript", "js",
|
|
||||||
se.compile(null, "l.length", Collections.emptyMap())), vars).run();
|
|
||||||
assertThat(((Number) o).intValue(), equalTo(4));
|
|
||||||
|
|
||||||
o = se.executable(new CompiledScript(ScriptType.INLINE, "testAccessInScript", "js",
|
|
||||||
se.compile(null, "l[0]", Collections.emptyMap())), vars).run();
|
|
||||||
assertThat(((String) o), equalTo("1"));
|
|
||||||
|
|
||||||
o = se.executable(new CompiledScript(ScriptType.INLINE, "testAccessInScript", "js",
|
|
||||||
se.compile(null, "l[3]", Collections.emptyMap())), vars).run();
|
|
||||||
obj1 = (Map<String, Object>) o;
|
|
||||||
assertThat((String) obj1.get("prop1"), equalTo("value1"));
|
|
||||||
assertThat((String) ((Map<String, Object>) obj1.get("obj2")).get("prop2"), equalTo("value2"));
|
|
||||||
|
|
||||||
o = se.executable(new CompiledScript(ScriptType.INLINE, "testAccessInScript", "js",
|
|
||||||
se.compile(null, "l[3].prop1", Collections.emptyMap())), vars).run();
|
|
||||||
assertThat(((String) o), equalTo("value1"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testChangingVarsCrossExecution1() {
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
Map<String, Object> ctx = new HashMap<String, Object>();
|
|
||||||
vars.put("ctx", ctx);
|
|
||||||
Object compiledScript = se.compile(null, "ctx.value", Collections.emptyMap());
|
|
||||||
|
|
||||||
ExecutableScript script = se.executable(new CompiledScript(ScriptType.INLINE, "testChangingVarsCrossExecution1", "js",
|
|
||||||
compiledScript), vars);
|
|
||||||
ctx.put("value", 1);
|
|
||||||
Object o = script.run();
|
|
||||||
assertThat(((Number) o).intValue(), equalTo(1));
|
|
||||||
|
|
||||||
ctx.put("value", 2);
|
|
||||||
o = script.run();
|
|
||||||
assertThat(((Number) o).intValue(), equalTo(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testChangingVarsCrossExecution2() {
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
Object compiledScript = se.compile(null, "value", Collections.emptyMap());
|
|
||||||
|
|
||||||
ExecutableScript script = se.executable(new CompiledScript(ScriptType.INLINE, "testChangingVarsCrossExecution2", "js",
|
|
||||||
compiledScript), vars);
|
|
||||||
script.setNextVar("value", 1);
|
|
||||||
Object o = script.run();
|
|
||||||
assertThat(((Number) o).intValue(), equalTo(1));
|
|
||||||
|
|
||||||
script.setNextVar("value", 2);
|
|
||||||
o = script.run();
|
|
||||||
assertThat(((Number) o).intValue(), equalTo(2));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,163 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.javascript;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.Randomness;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.script.CompiledScript;
|
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
|
||||||
import org.elasticsearch.script.ScriptType;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.CyclicBarrier;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
|
||||||
|
|
||||||
public class JavaScriptScriptMultiThreadedTests extends ESTestCase {
|
|
||||||
public void testExecutableNoRuntimeParams() throws Exception {
|
|
||||||
final JavaScriptScriptEngineService se = new JavaScriptScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
|
||||||
final Object compiled = se.compile(null, "x + y", Collections.emptyMap());
|
|
||||||
final AtomicBoolean failed = new AtomicBoolean();
|
|
||||||
|
|
||||||
Thread[] threads = new Thread[between(3, 12)];
|
|
||||||
final CountDownLatch latch = new CountDownLatch(threads.length);
|
|
||||||
final CyclicBarrier barrier = new CyclicBarrier(threads.length + 1);
|
|
||||||
for (int i = 0; i < threads.length; i++) {
|
|
||||||
threads[i] = new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
barrier.await();
|
|
||||||
long x = Randomness.get().nextInt();
|
|
||||||
long y = Randomness.get().nextInt();
|
|
||||||
long addition = x + y;
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
vars.put("x", x);
|
|
||||||
vars.put("y", y);
|
|
||||||
ExecutableScript script = se.executable(new CompiledScript(ScriptType.INLINE, "testExecutableNoRuntimeParams", "js", compiled), vars);
|
|
||||||
for (int i = 0; i < between(100, 1000); i++) {
|
|
||||||
long result = ((Number) script.run()).longValue();
|
|
||||||
assertThat(result, equalTo(addition));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
failed.set(true);
|
|
||||||
logger.error("failed", e);
|
|
||||||
} finally {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for (int i = 0; i < threads.length; i++) {
|
|
||||||
threads[i].start();
|
|
||||||
}
|
|
||||||
barrier.await();
|
|
||||||
latch.await();
|
|
||||||
assertThat(failed.get(), equalTo(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testExecutableWithRuntimeParams() throws Exception {
|
|
||||||
final JavaScriptScriptEngineService se = new JavaScriptScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
|
||||||
final Object compiled = se.compile(null, "x + y", Collections.emptyMap());
|
|
||||||
final AtomicBoolean failed = new AtomicBoolean();
|
|
||||||
|
|
||||||
Thread[] threads = new Thread[between(3, 12)];
|
|
||||||
final CountDownLatch latch = new CountDownLatch(threads.length);
|
|
||||||
final CyclicBarrier barrier = new CyclicBarrier(threads.length + 1);
|
|
||||||
for (int i = 0; i < threads.length; i++) {
|
|
||||||
threads[i] = new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
barrier.await();
|
|
||||||
long x = Randomness.get().nextInt();
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
vars.put("x", x);
|
|
||||||
ExecutableScript script = se.executable(new CompiledScript(ScriptType.INLINE, "testExecutableNoRuntimeParams", "js", compiled), vars);
|
|
||||||
for (int i = 0; i < between(100, 1000); i++) {
|
|
||||||
long y = Randomness.get().nextInt();
|
|
||||||
long addition = x + y;
|
|
||||||
script.setNextVar("y", y);
|
|
||||||
long result = ((Number) script.run()).longValue();
|
|
||||||
assertThat(result, equalTo(addition));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
failed.set(true);
|
|
||||||
logger.error("failed", e);
|
|
||||||
} finally {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for (int i = 0; i < threads.length; i++) {
|
|
||||||
threads[i].start();
|
|
||||||
}
|
|
||||||
barrier.await();
|
|
||||||
latch.await();
|
|
||||||
assertThat(failed.get(), equalTo(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testExecute() throws Exception {
|
|
||||||
final JavaScriptScriptEngineService se = new JavaScriptScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
|
||||||
final Object compiled = se.compile(null, "x + y", Collections.emptyMap());
|
|
||||||
final AtomicBoolean failed = new AtomicBoolean();
|
|
||||||
|
|
||||||
Thread[] threads = new Thread[between(3, 12)];
|
|
||||||
final CountDownLatch latch = new CountDownLatch(threads.length);
|
|
||||||
final CyclicBarrier barrier = new CyclicBarrier(threads.length + 1);
|
|
||||||
for (int i = 0; i < threads.length; i++) {
|
|
||||||
threads[i] = new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
barrier.await();
|
|
||||||
Map<String, Object> runtimeVars = new HashMap<String, Object>();
|
|
||||||
for (int i = 0; i < between(100, 1000); i++) {
|
|
||||||
long x = Randomness.get().nextInt();
|
|
||||||
long y = Randomness.get().nextInt();
|
|
||||||
long addition = x + y;
|
|
||||||
runtimeVars.put("x", x);
|
|
||||||
runtimeVars.put("y", y);
|
|
||||||
long result = ((Number) se.executable(new CompiledScript(ScriptType.INLINE, "testExecutableNoRuntimeParams", "js", compiled), runtimeVars).run()).longValue();
|
|
||||||
assertThat(result, equalTo(addition));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
failed.set(true);
|
|
||||||
logger.error("failed", e);
|
|
||||||
} finally {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for (int i = 0; i < threads.length; i++) {
|
|
||||||
threads[i].start();
|
|
||||||
}
|
|
||||||
barrier.await();
|
|
||||||
latch.await();
|
|
||||||
assertThat(failed.get(), equalTo(false));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.javascript;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.script.CompiledScript;
|
|
||||||
import org.elasticsearch.script.ScriptType;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
import org.mozilla.javascript.EcmaError;
|
|
||||||
import org.mozilla.javascript.WrappedException;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for the Javascript security permissions
|
|
||||||
*/
|
|
||||||
public class JavaScriptSecurityTests extends ESTestCase {
|
|
||||||
|
|
||||||
private JavaScriptScriptEngineService se;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
se = new JavaScriptScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
|
||||||
// otherwise will exit your VM and other bad stuff
|
|
||||||
assumeTrue("test requires security manager to be enabled", System.getSecurityManager() != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
se.close();
|
|
||||||
super.tearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** runs a script */
|
|
||||||
private void doTest(String script) {
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
se.executable(new CompiledScript(ScriptType.INLINE, "test", "js", se.compile(null, script, Collections.emptyMap())), vars).run();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** asserts that a script runs without exception */
|
|
||||||
private void assertSuccess(String script) {
|
|
||||||
doTest(script);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** assert that a security exception is hit */
|
|
||||||
private void assertFailure(String script, Class<? extends Throwable> exceptionClass) {
|
|
||||||
try {
|
|
||||||
doTest(script);
|
|
||||||
fail("did not get expected exception");
|
|
||||||
} catch (WrappedException expected) {
|
|
||||||
Throwable cause = expected.getCause();
|
|
||||||
assertNotNull(cause);
|
|
||||||
if (exceptionClass.isAssignableFrom(cause.getClass()) == false) {
|
|
||||||
throw new AssertionError("unexpected exception: " + expected, expected);
|
|
||||||
}
|
|
||||||
} catch (EcmaError expected) {
|
|
||||||
if (exceptionClass.isAssignableFrom(expected.getClass()) == false) {
|
|
||||||
throw new AssertionError("unexpected exception: " + expected, expected);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Test some javascripts that are ok */
|
|
||||||
public void testOK() {
|
|
||||||
assertSuccess("1 + 2");
|
|
||||||
assertSuccess("Math.cos(Math.PI)");
|
|
||||||
assertSuccess("Array.apply(null, Array(100)).map(function (_, i) {return i;}).map(function (i) {return i+1;})");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Test some javascripts that should hit security exception */
|
|
||||||
public void testNotOK() throws Exception {
|
|
||||||
// sanity check :)
|
|
||||||
assertFailure("java.lang.Runtime.getRuntime().halt(0)", EcmaError.class);
|
|
||||||
// check a few things more restrictive than the ordinary policy
|
|
||||||
// no network
|
|
||||||
assertFailure("new java.net.Socket(\"localhost\", 1024)", EcmaError.class);
|
|
||||||
// no files
|
|
||||||
assertFailure("java.io.File.createTempFile(\"test\", \"tmp\")", EcmaError.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testDefinitelyNotOK() {
|
|
||||||
// no mucking with security controller
|
|
||||||
assertFailure("var ctx = org.mozilla.javascript.Context.getCurrentContext(); " +
|
|
||||||
"ctx.setSecurityController(new org.mozilla.javascript.PolicySecurityController());", EcmaError.class);
|
|
||||||
// no compiling scripts from scripts
|
|
||||||
assertFailure("var ctx = org.mozilla.javascript.Context.getCurrentContext(); " +
|
|
||||||
"ctx.compileString(\"1 + 1\", \"foobar\", 1, null); ", EcmaError.class);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.javascript;
|
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
|
||||||
|
|
||||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
|
||||||
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
|
||||||
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class LangJavascriptClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
|
||||||
|
|
||||||
public LangJavascriptClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
|
||||||
super(testCandidate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParametersFactory
|
|
||||||
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
|
||||||
return ESClientYamlSuiteTestCase.createParameters();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
# Integration tests for Lang JavaScript components
|
|
||||||
#
|
|
||||||
setup:
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body: { "foo": "aaa" }
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"Lang JavaScript":
|
|
||||||
- do:
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
script_fields:
|
|
||||||
bar:
|
|
||||||
script:
|
|
||||||
inline: "doc['foo.keyword'].value + x"
|
|
||||||
lang: javascript
|
|
||||||
params:
|
|
||||||
x: "bbb"
|
|
||||||
|
|
||||||
- match: { hits.hits.0.fields.bar.0: "aaabbb"}
|
|
|
@ -1,416 +0,0 @@
|
||||||
# Integration tests for Lang JavaScript components
|
|
||||||
#
|
|
||||||
"JavaScript Query":
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body: { "test": "value beck", "num1": 1.0 }
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 2
|
|
||||||
body: { "test": "value beck", "num1": 2.0 }
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 3
|
|
||||||
body: { "test": "value beck", "num1": 3.0 }
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
script:
|
|
||||||
script:
|
|
||||||
inline: "doc['num1'].value > 1"
|
|
||||||
lang: javascript
|
|
||||||
script_fields:
|
|
||||||
sNum1:
|
|
||||||
script:
|
|
||||||
inline: "doc['num1'].value"
|
|
||||||
lang: javascript
|
|
||||||
sort:
|
|
||||||
num1:
|
|
||||||
order: asc
|
|
||||||
|
|
||||||
- match: { hits.total: 2 }
|
|
||||||
- match: { hits.hits.0.fields.sNum1.0: 2.0 }
|
|
||||||
- match: { hits.hits.1.fields.sNum1.0: 3.0 }
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
script:
|
|
||||||
script:
|
|
||||||
inline: "doc['num1'].value > param1"
|
|
||||||
lang: javascript
|
|
||||||
params:
|
|
||||||
param1: 1
|
|
||||||
|
|
||||||
script_fields:
|
|
||||||
sNum1:
|
|
||||||
script:
|
|
||||||
inline: "doc['num1'].value"
|
|
||||||
lang: javascript
|
|
||||||
sort:
|
|
||||||
num1:
|
|
||||||
order: asc
|
|
||||||
|
|
||||||
- match: { hits.total: 2 }
|
|
||||||
- match: { hits.hits.0.fields.sNum1.0: 2.0 }
|
|
||||||
- match: { hits.hits.1.fields.sNum1.0: 3.0 }
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
script:
|
|
||||||
script:
|
|
||||||
inline: "doc['num1'].value > param1"
|
|
||||||
lang: javascript
|
|
||||||
params:
|
|
||||||
param1: -1
|
|
||||||
|
|
||||||
script_fields:
|
|
||||||
sNum1:
|
|
||||||
script:
|
|
||||||
inline: "doc['num1'].value"
|
|
||||||
lang: javascript
|
|
||||||
sort:
|
|
||||||
num1:
|
|
||||||
order: asc
|
|
||||||
|
|
||||||
- match: { hits.total: 3 }
|
|
||||||
- match: { hits.hits.0.fields.sNum1.0: 1.0 }
|
|
||||||
- match: { hits.hits.1.fields.sNum1.0: 2.0 }
|
|
||||||
- match: { hits.hits.2.fields.sNum1.0: 3.0 }
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"JavaScript Script Field Using Source":
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body: {
|
|
||||||
"obj1": {
|
|
||||||
"test": "something"
|
|
||||||
},
|
|
||||||
"obj2": {
|
|
||||||
"arr2": [ "arr_value1", "arr_value2" ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
script_fields:
|
|
||||||
s_obj1:
|
|
||||||
script:
|
|
||||||
inline: "_source.obj1"
|
|
||||||
lang: javascript
|
|
||||||
s_obj1_test:
|
|
||||||
script:
|
|
||||||
inline: "_source.obj1.test"
|
|
||||||
lang: javascript
|
|
||||||
s_obj2:
|
|
||||||
script:
|
|
||||||
inline: "_source.obj2"
|
|
||||||
lang: javascript
|
|
||||||
s_obj2_arr2:
|
|
||||||
script:
|
|
||||||
inline: "_source.obj2.arr2"
|
|
||||||
lang: javascript
|
|
||||||
|
|
||||||
- match: { hits.total: 1 }
|
|
||||||
- match: { hits.hits.0.fields.s_obj1.0.test: something }
|
|
||||||
- match: { hits.hits.0.fields.s_obj1_test.0: something }
|
|
||||||
- match: { hits.hits.0.fields.s_obj2.0.arr2.0: arr_value1 }
|
|
||||||
- match: { hits.hits.0.fields.s_obj2.0.arr2.1: arr_value2 }
|
|
||||||
- match: { hits.hits.0.fields.s_obj2_arr2.0: arr_value1 }
|
|
||||||
- match: { hits.hits.0.fields.s_obj2_arr2.1: arr_value2 }
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"JavaScript Custom Script Boost":
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body: { "test": "value beck", "num1": 1.0 }
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 2
|
|
||||||
body: { "test": "value beck", "num1": 2.0 }
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
query:
|
|
||||||
term:
|
|
||||||
test: value
|
|
||||||
"functions": [{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "javascript",
|
|
||||||
"inline": "doc['num1'].value"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
- match: { hits.total: 2 }
|
|
||||||
- match: { hits.hits.0._id: "2" }
|
|
||||||
- match: { hits.hits.1._id: "1" }
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
query:
|
|
||||||
term:
|
|
||||||
test: value
|
|
||||||
"functions": [{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "javascript",
|
|
||||||
"inline": "-doc['num1'].value"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
- match: { hits.total: 2 }
|
|
||||||
- match: { hits.hits.0._id: "1" }
|
|
||||||
- match: { hits.hits.1._id: "2" }
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
query:
|
|
||||||
term:
|
|
||||||
test: value
|
|
||||||
"functions": [{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "javascript",
|
|
||||||
"inline": "Math.pow(doc['num1'].value, 2)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
- match: { hits.total: 2 }
|
|
||||||
- match: { hits.hits.0._id: "2" }
|
|
||||||
- match: { hits.hits.1._id: "1" }
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
query:
|
|
||||||
term:
|
|
||||||
test: value
|
|
||||||
"functions": [{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "javascript",
|
|
||||||
"inline": "Math.max(doc['num1'].value, 1)"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
- match: { hits.total: 2 }
|
|
||||||
- match: { hits.hits.0._id: "2" }
|
|
||||||
- match: { hits.hits.1._id: "1" }
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
query:
|
|
||||||
term:
|
|
||||||
test: value
|
|
||||||
"functions": [{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "javascript",
|
|
||||||
"inline": "doc['num1'].value * _score"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
- match: { hits.total: 2 }
|
|
||||||
- match: { hits.hits.0._id: "2" }
|
|
||||||
- match: { hits.hits.1._id: "1" }
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
query:
|
|
||||||
term:
|
|
||||||
test: value
|
|
||||||
"functions": [{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "javascript",
|
|
||||||
"inline": "param1 * param2 * _score",
|
|
||||||
"params": {
|
|
||||||
"param1": 2,
|
|
||||||
"param2": 2
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
- match: { hits.total: 2 }
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"JavaScript Scores Nested":
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body: { "dummy_field": 1 }
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
"functions": [
|
|
||||||
{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "javascript",
|
|
||||||
"inline": "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "javascript",
|
|
||||||
"inline": "_score.doubleValue()"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
"functions": [{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "javascript",
|
|
||||||
"inline": "_score.doubleValue()"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
- match: { hits.total: 1 }
|
|
||||||
- match: { hits.hits.0._score: 1.0 }
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"JavaScript Scores With Agg":
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body: { "dummy_field": 1 }
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
"functions": [{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "javascript",
|
|
||||||
"inline": "_score.doubleValue()"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
aggs:
|
|
||||||
score_agg:
|
|
||||||
terms:
|
|
||||||
script:
|
|
||||||
lang: javascript
|
|
||||||
inline: "_score.doubleValue()"
|
|
||||||
|
|
||||||
- match: { hits.total: 1 }
|
|
||||||
- match: { hits.hits.0._score: 1.0 }
|
|
||||||
- match: { aggregations.score_agg.buckets.0.key: "1.0" }
|
|
||||||
- match: { aggregations.score_agg.buckets.0.doc_count: 1 }
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"JavaScript Use List Length In Scripts":
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body: { "f": 42 }
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
script_fields:
|
|
||||||
foobar:
|
|
||||||
script:
|
|
||||||
inline: "doc['f'].values.length"
|
|
||||||
lang: javascript
|
|
||||||
|
|
||||||
|
|
||||||
- match: { hits.total: 1 }
|
|
||||||
- match: { hits.hits.0.fields.foobar.0: 1 }
|
|
||||||
|
|
|
@ -1,528 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
esplugin {
|
|
||||||
description 'The Python language plugin allows to have python as the language of scripts to execute.'
|
|
||||||
classname 'org.elasticsearch.plugin.python.PythonPlugin'
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compile 'org.python:jython-standalone:2.7.0'
|
|
||||||
}
|
|
||||||
|
|
||||||
integTest {
|
|
||||||
cluster {
|
|
||||||
setting 'script.inline', 'true'
|
|
||||||
setting 'script.stored', 'true'
|
|
||||||
setting 'script.max_compilations_per_minute', '1000'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
thirdPartyAudit.excludes = [
|
|
||||||
// uses internal java api: sun.security.x509 (X509CertInfo, X509CertImpl, X500Name)
|
|
||||||
'org.python.netty.handler.ssl.util.OpenJdkSelfSignedCertGenerator',
|
|
||||||
|
|
||||||
// uses internal java api: sun.misc.Cleaner
|
|
||||||
'org.python.netty.util.internal.Cleaner0',
|
|
||||||
|
|
||||||
// uses internal java api: sun.misc.Signal
|
|
||||||
'jnr.posix.JavaPOSIX',
|
|
||||||
'jnr.posix.JavaPOSIX$SunMiscSignalHandler',
|
|
||||||
|
|
||||||
// uses internal java api: sun.misc.Unsafe
|
|
||||||
'com.kenai.jffi.MemoryIO$UnsafeImpl',
|
|
||||||
'com.kenai.jffi.MemoryIO$UnsafeImpl32',
|
|
||||||
'com.kenai.jffi.MemoryIO$UnsafeImpl64',
|
|
||||||
'org.python.google.common.cache.Striped64',
|
|
||||||
'org.python.google.common.cache.Striped64$1',
|
|
||||||
'org.python.google.common.cache.Striped64$Cell',
|
|
||||||
'org.python.google.common.primitives.UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator',
|
|
||||||
'org.python.google.common.primitives.UnsignedBytes$LexicographicalComparatorHolder$UnsafeComparator$1',
|
|
||||||
'org.python.netty.util.internal.chmv8.ForkJoinPool$2',
|
|
||||||
'org.python.netty.util.internal.PlatformDependent0',
|
|
||||||
'org.python.netty.util.internal.UnsafeAtomicIntegerFieldUpdater',
|
|
||||||
'org.python.netty.util.internal.UnsafeAtomicLongFieldUpdater',
|
|
||||||
'org.python.netty.util.internal.UnsafeAtomicReferenceFieldUpdater',
|
|
||||||
'org.python.netty.util.internal.chmv8.ConcurrentHashMapV8',
|
|
||||||
'org.python.netty.util.internal.chmv8.ConcurrentHashMapV8$1',
|
|
||||||
'org.python.netty.util.internal.chmv8.ConcurrentHashMapV8$TreeBin',
|
|
||||||
'org.python.netty.util.internal.chmv8.CountedCompleter',
|
|
||||||
'org.python.netty.util.internal.chmv8.CountedCompleter$1',
|
|
||||||
'org.python.netty.util.internal.chmv8.ForkJoinPool',
|
|
||||||
'org.python.netty.util.internal.chmv8.ForkJoinPool$WorkQueue',
|
|
||||||
'org.python.netty.util.internal.chmv8.ForkJoinTask',
|
|
||||||
'org.python.netty.util.internal.chmv8.ForkJoinTask$1',
|
|
||||||
|
|
||||||
// "uberjaring" (but not shading) classes that have been in the JDK since 1.5
|
|
||||||
// nice job python.
|
|
||||||
'javax.xml.XMLConstants',
|
|
||||||
'javax.xml.datatype.DatatypeConfigurationException',
|
|
||||||
'javax.xml.datatype.DatatypeConstants$1',
|
|
||||||
'javax.xml.datatype.DatatypeConstants$Field',
|
|
||||||
'javax.xml.datatype.DatatypeConstants',
|
|
||||||
'javax.xml.datatype.DatatypeFactory',
|
|
||||||
'javax.xml.datatype.Duration',
|
|
||||||
'javax.xml.datatype.FactoryFinder',
|
|
||||||
'javax.xml.datatype.SecuritySupport$1',
|
|
||||||
'javax.xml.datatype.SecuritySupport$2',
|
|
||||||
'javax.xml.datatype.SecuritySupport$3',
|
|
||||||
'javax.xml.datatype.SecuritySupport$4',
|
|
||||||
'javax.xml.datatype.SecuritySupport$5',
|
|
||||||
'javax.xml.datatype.SecuritySupport',
|
|
||||||
'javax.xml.datatype.XMLGregorianCalendar',
|
|
||||||
'javax.xml.namespace.NamespaceContext',
|
|
||||||
'javax.xml.namespace.QName$1',
|
|
||||||
'javax.xml.namespace.QName',
|
|
||||||
'javax.xml.parsers.DocumentBuilder',
|
|
||||||
'javax.xml.parsers.DocumentBuilderFactory',
|
|
||||||
'javax.xml.parsers.FactoryConfigurationError',
|
|
||||||
'javax.xml.parsers.FactoryFinder',
|
|
||||||
'javax.xml.parsers.ParserConfigurationException',
|
|
||||||
'javax.xml.parsers.SAXParser',
|
|
||||||
'javax.xml.parsers.SAXParserFactory',
|
|
||||||
'javax.xml.parsers.SecuritySupport$1',
|
|
||||||
'javax.xml.parsers.SecuritySupport$2',
|
|
||||||
'javax.xml.parsers.SecuritySupport$3',
|
|
||||||
'javax.xml.parsers.SecuritySupport$4',
|
|
||||||
'javax.xml.parsers.SecuritySupport$5',
|
|
||||||
'javax.xml.parsers.SecuritySupport',
|
|
||||||
'javax.xml.stream.EventFilter',
|
|
||||||
'javax.xml.stream.FactoryConfigurationError',
|
|
||||||
'javax.xml.stream.FactoryFinder',
|
|
||||||
'javax.xml.stream.Location',
|
|
||||||
'javax.xml.stream.SecuritySupport$1',
|
|
||||||
'javax.xml.stream.SecuritySupport$2',
|
|
||||||
'javax.xml.stream.SecuritySupport$3',
|
|
||||||
'javax.xml.stream.SecuritySupport$4',
|
|
||||||
'javax.xml.stream.SecuritySupport$5',
|
|
||||||
'javax.xml.stream.SecuritySupport',
|
|
||||||
'javax.xml.stream.StreamFilter',
|
|
||||||
'javax.xml.stream.XMLEventFactory',
|
|
||||||
'javax.xml.stream.XMLEventReader',
|
|
||||||
'javax.xml.stream.XMLEventWriter',
|
|
||||||
'javax.xml.stream.XMLInputFactory',
|
|
||||||
'javax.xml.stream.XMLOutputFactory',
|
|
||||||
'javax.xml.stream.XMLReporter',
|
|
||||||
'javax.xml.stream.XMLResolver',
|
|
||||||
'javax.xml.stream.XMLStreamConstants',
|
|
||||||
'javax.xml.stream.XMLStreamException',
|
|
||||||
'javax.xml.stream.XMLStreamReader',
|
|
||||||
'javax.xml.stream.XMLStreamWriter',
|
|
||||||
'javax.xml.stream.events.Attribute',
|
|
||||||
'javax.xml.stream.events.Characters',
|
|
||||||
'javax.xml.stream.events.Comment',
|
|
||||||
'javax.xml.stream.events.DTD',
|
|
||||||
'javax.xml.stream.events.EndDocument',
|
|
||||||
'javax.xml.stream.events.EndElement',
|
|
||||||
'javax.xml.stream.events.EntityDeclaration',
|
|
||||||
'javax.xml.stream.events.EntityReference',
|
|
||||||
'javax.xml.stream.events.Namespace',
|
|
||||||
'javax.xml.stream.events.NotationDeclaration',
|
|
||||||
'javax.xml.stream.events.ProcessingInstruction',
|
|
||||||
'javax.xml.stream.events.StartDocument',
|
|
||||||
'javax.xml.stream.events.StartElement',
|
|
||||||
'javax.xml.stream.events.XMLEvent',
|
|
||||||
'javax.xml.stream.util.EventReaderDelegate',
|
|
||||||
'javax.xml.stream.util.StreamReaderDelegate',
|
|
||||||
'javax.xml.stream.util.XMLEventAllocator',
|
|
||||||
'javax.xml.stream.util.XMLEventConsumer',
|
|
||||||
'javax.xml.transform.ErrorListener',
|
|
||||||
'javax.xml.transform.FactoryFinder',
|
|
||||||
'javax.xml.transform.OutputKeys',
|
|
||||||
'javax.xml.transform.Result',
|
|
||||||
'javax.xml.transform.SecuritySupport$1',
|
|
||||||
'javax.xml.transform.SecuritySupport$2',
|
|
||||||
'javax.xml.transform.SecuritySupport$3',
|
|
||||||
'javax.xml.transform.SecuritySupport$4',
|
|
||||||
'javax.xml.transform.SecuritySupport$5',
|
|
||||||
'javax.xml.transform.SecuritySupport',
|
|
||||||
'javax.xml.transform.Source',
|
|
||||||
'javax.xml.transform.SourceLocator',
|
|
||||||
'javax.xml.transform.Templates',
|
|
||||||
'javax.xml.transform.Transformer',
|
|
||||||
'javax.xml.transform.TransformerConfigurationException',
|
|
||||||
'javax.xml.transform.TransformerException',
|
|
||||||
'javax.xml.transform.TransformerFactory',
|
|
||||||
'javax.xml.transform.TransformerFactoryConfigurationError',
|
|
||||||
'javax.xml.transform.URIResolver',
|
|
||||||
'javax.xml.transform.dom.DOMLocator',
|
|
||||||
'javax.xml.transform.dom.DOMResult',
|
|
||||||
'javax.xml.transform.dom.DOMSource',
|
|
||||||
'javax.xml.transform.sax.SAXResult',
|
|
||||||
'javax.xml.transform.sax.SAXSource',
|
|
||||||
'javax.xml.transform.sax.SAXTransformerFactory',
|
|
||||||
'javax.xml.transform.sax.TemplatesHandler',
|
|
||||||
'javax.xml.transform.sax.TransformerHandler',
|
|
||||||
'javax.xml.transform.stax.StAXResult',
|
|
||||||
'javax.xml.transform.stax.StAXSource',
|
|
||||||
'javax.xml.transform.stream.StreamResult',
|
|
||||||
'javax.xml.transform.stream.StreamSource',
|
|
||||||
'javax.xml.validation.Schema',
|
|
||||||
'javax.xml.validation.SchemaFactory',
|
|
||||||
'javax.xml.validation.SchemaFactoryFinder$1',
|
|
||||||
'javax.xml.validation.SchemaFactoryFinder$2',
|
|
||||||
'javax.xml.validation.SchemaFactoryFinder',
|
|
||||||
'javax.xml.validation.SchemaFactoryLoader',
|
|
||||||
'javax.xml.validation.SecuritySupport$1',
|
|
||||||
'javax.xml.validation.SecuritySupport$2',
|
|
||||||
'javax.xml.validation.SecuritySupport$3',
|
|
||||||
'javax.xml.validation.SecuritySupport$4',
|
|
||||||
'javax.xml.validation.SecuritySupport$5',
|
|
||||||
'javax.xml.validation.SecuritySupport$6',
|
|
||||||
'javax.xml.validation.SecuritySupport$7',
|
|
||||||
'javax.xml.validation.SecuritySupport$8',
|
|
||||||
'javax.xml.validation.SecuritySupport',
|
|
||||||
'javax.xml.validation.TypeInfoProvider',
|
|
||||||
'javax.xml.validation.Validator',
|
|
||||||
'javax.xml.validation.ValidatorHandler',
|
|
||||||
'javax.xml.xpath.SecuritySupport$1',
|
|
||||||
'javax.xml.xpath.SecuritySupport$2',
|
|
||||||
'javax.xml.xpath.SecuritySupport$3',
|
|
||||||
'javax.xml.xpath.SecuritySupport$4',
|
|
||||||
'javax.xml.xpath.SecuritySupport$5',
|
|
||||||
'javax.xml.xpath.SecuritySupport$6',
|
|
||||||
'javax.xml.xpath.SecuritySupport$7',
|
|
||||||
'javax.xml.xpath.SecuritySupport$8',
|
|
||||||
'javax.xml.xpath.SecuritySupport',
|
|
||||||
'javax.xml.xpath.XPath',
|
|
||||||
'javax.xml.xpath.XPathConstants',
|
|
||||||
'javax.xml.xpath.XPathException',
|
|
||||||
'javax.xml.xpath.XPathExpression',
|
|
||||||
'javax.xml.xpath.XPathExpressionException',
|
|
||||||
'javax.xml.xpath.XPathFactory',
|
|
||||||
'javax.xml.xpath.XPathFactoryConfigurationException',
|
|
||||||
'javax.xml.xpath.XPathFactoryFinder$1',
|
|
||||||
'javax.xml.xpath.XPathFactoryFinder$2',
|
|
||||||
'javax.xml.xpath.XPathFactoryFinder',
|
|
||||||
'javax.xml.xpath.XPathFunction',
|
|
||||||
'javax.xml.xpath.XPathFunctionException',
|
|
||||||
'javax.xml.xpath.XPathFunctionResolver',
|
|
||||||
'javax.xml.xpath.XPathVariableResolver',
|
|
||||||
'org.w3c.dom.Attr',
|
|
||||||
'org.w3c.dom.CDATASection',
|
|
||||||
'org.w3c.dom.CharacterData',
|
|
||||||
'org.w3c.dom.Comment',
|
|
||||||
'org.w3c.dom.DOMConfiguration',
|
|
||||||
'org.w3c.dom.DOMError',
|
|
||||||
'org.w3c.dom.DOMErrorHandler',
|
|
||||||
'org.w3c.dom.DOMException',
|
|
||||||
'org.w3c.dom.DOMImplementation',
|
|
||||||
'org.w3c.dom.DOMImplementationList',
|
|
||||||
'org.w3c.dom.DOMImplementationSource',
|
|
||||||
'org.w3c.dom.DOMLocator',
|
|
||||||
'org.w3c.dom.DOMStringList',
|
|
||||||
'org.w3c.dom.Document',
|
|
||||||
'org.w3c.dom.DocumentFragment',
|
|
||||||
'org.w3c.dom.DocumentType',
|
|
||||||
'org.w3c.dom.Element',
|
|
||||||
'org.w3c.dom.Entity',
|
|
||||||
'org.w3c.dom.EntityReference',
|
|
||||||
'org.w3c.dom.NameList',
|
|
||||||
'org.w3c.dom.NamedNodeMap',
|
|
||||||
'org.w3c.dom.Node',
|
|
||||||
'org.w3c.dom.NodeList',
|
|
||||||
'org.w3c.dom.Notation',
|
|
||||||
'org.w3c.dom.ProcessingInstruction',
|
|
||||||
'org.w3c.dom.Text',
|
|
||||||
'org.w3c.dom.TypeInfo',
|
|
||||||
'org.w3c.dom.UserDataHandler',
|
|
||||||
'org.w3c.dom.bootstrap.DOMImplementationRegistry$1',
|
|
||||||
'org.w3c.dom.bootstrap.DOMImplementationRegistry$2',
|
|
||||||
'org.w3c.dom.bootstrap.DOMImplementationRegistry$3',
|
|
||||||
'org.w3c.dom.bootstrap.DOMImplementationRegistry$4',
|
|
||||||
'org.w3c.dom.bootstrap.DOMImplementationRegistry',
|
|
||||||
'org.w3c.dom.css.CSS2Properties',
|
|
||||||
'org.w3c.dom.css.CSSCharsetRule',
|
|
||||||
'org.w3c.dom.css.CSSFontFaceRule',
|
|
||||||
'org.w3c.dom.css.CSSImportRule',
|
|
||||||
'org.w3c.dom.css.CSSMediaRule',
|
|
||||||
'org.w3c.dom.css.CSSPageRule',
|
|
||||||
'org.w3c.dom.css.CSSPrimitiveValue',
|
|
||||||
'org.w3c.dom.css.CSSRule',
|
|
||||||
'org.w3c.dom.css.CSSRuleList',
|
|
||||||
'org.w3c.dom.css.CSSStyleDeclaration',
|
|
||||||
'org.w3c.dom.css.CSSStyleRule',
|
|
||||||
'org.w3c.dom.css.CSSStyleSheet',
|
|
||||||
'org.w3c.dom.css.CSSUnknownRule',
|
|
||||||
'org.w3c.dom.css.CSSValue',
|
|
||||||
'org.w3c.dom.css.CSSValueList',
|
|
||||||
'org.w3c.dom.css.Counter',
|
|
||||||
'org.w3c.dom.css.DOMImplementationCSS',
|
|
||||||
'org.w3c.dom.css.DocumentCSS',
|
|
||||||
'org.w3c.dom.css.ElementCSSInlineStyle',
|
|
||||||
'org.w3c.dom.css.RGBColor',
|
|
||||||
'org.w3c.dom.css.Rect',
|
|
||||||
'org.w3c.dom.css.ViewCSS',
|
|
||||||
'org.w3c.dom.events.DocumentEvent',
|
|
||||||
'org.w3c.dom.events.Event',
|
|
||||||
'org.w3c.dom.events.EventException',
|
|
||||||
'org.w3c.dom.events.EventListener',
|
|
||||||
'org.w3c.dom.events.EventTarget',
|
|
||||||
'org.w3c.dom.events.MouseEvent',
|
|
||||||
'org.w3c.dom.events.MutationEvent',
|
|
||||||
'org.w3c.dom.events.UIEvent',
|
|
||||||
'org.w3c.dom.html.HTMLAnchorElement',
|
|
||||||
'org.w3c.dom.html.HTMLAppletElement',
|
|
||||||
'org.w3c.dom.html.HTMLAreaElement',
|
|
||||||
'org.w3c.dom.html.HTMLBRElement',
|
|
||||||
'org.w3c.dom.html.HTMLBaseElement',
|
|
||||||
'org.w3c.dom.html.HTMLBaseFontElement',
|
|
||||||
'org.w3c.dom.html.HTMLBodyElement',
|
|
||||||
'org.w3c.dom.html.HTMLButtonElement',
|
|
||||||
'org.w3c.dom.html.HTMLCollection',
|
|
||||||
'org.w3c.dom.html.HTMLDListElement',
|
|
||||||
'org.w3c.dom.html.HTMLDOMImplementation',
|
|
||||||
'org.w3c.dom.html.HTMLDirectoryElement',
|
|
||||||
'org.w3c.dom.html.HTMLDivElement',
|
|
||||||
'org.w3c.dom.html.HTMLDocument',
|
|
||||||
'org.w3c.dom.html.HTMLElement',
|
|
||||||
'org.w3c.dom.html.HTMLFieldSetElement',
|
|
||||||
'org.w3c.dom.html.HTMLFontElement',
|
|
||||||
'org.w3c.dom.html.HTMLFormElement',
|
|
||||||
'org.w3c.dom.html.HTMLFrameElement',
|
|
||||||
'org.w3c.dom.html.HTMLFrameSetElement',
|
|
||||||
'org.w3c.dom.html.HTMLHRElement',
|
|
||||||
'org.w3c.dom.html.HTMLHeadElement',
|
|
||||||
'org.w3c.dom.html.HTMLHeadingElement',
|
|
||||||
'org.w3c.dom.html.HTMLHtmlElement',
|
|
||||||
'org.w3c.dom.html.HTMLIFrameElement',
|
|
||||||
'org.w3c.dom.html.HTMLImageElement',
|
|
||||||
'org.w3c.dom.html.HTMLInputElement',
|
|
||||||
'org.w3c.dom.html.HTMLIsIndexElement',
|
|
||||||
'org.w3c.dom.html.HTMLLIElement',
|
|
||||||
'org.w3c.dom.html.HTMLLabelElement',
|
|
||||||
'org.w3c.dom.html.HTMLLegendElement',
|
|
||||||
'org.w3c.dom.html.HTMLLinkElement',
|
|
||||||
'org.w3c.dom.html.HTMLMapElement',
|
|
||||||
'org.w3c.dom.html.HTMLMenuElement',
|
|
||||||
'org.w3c.dom.html.HTMLMetaElement',
|
|
||||||
'org.w3c.dom.html.HTMLModElement',
|
|
||||||
'org.w3c.dom.html.HTMLOListElement',
|
|
||||||
'org.w3c.dom.html.HTMLObjectElement',
|
|
||||||
'org.w3c.dom.html.HTMLOptGroupElement',
|
|
||||||
'org.w3c.dom.html.HTMLOptionElement',
|
|
||||||
'org.w3c.dom.html.HTMLParagraphElement',
|
|
||||||
'org.w3c.dom.html.HTMLParamElement',
|
|
||||||
'org.w3c.dom.html.HTMLPreElement',
|
|
||||||
'org.w3c.dom.html.HTMLQuoteElement',
|
|
||||||
'org.w3c.dom.html.HTMLScriptElement',
|
|
||||||
'org.w3c.dom.html.HTMLSelectElement',
|
|
||||||
'org.w3c.dom.html.HTMLStyleElement',
|
|
||||||
'org.w3c.dom.html.HTMLTableCaptionElement',
|
|
||||||
'org.w3c.dom.html.HTMLTableCellElement',
|
|
||||||
'org.w3c.dom.html.HTMLTableColElement',
|
|
||||||
'org.w3c.dom.html.HTMLTableElement',
|
|
||||||
'org.w3c.dom.html.HTMLTableRowElement',
|
|
||||||
'org.w3c.dom.html.HTMLTableSectionElement',
|
|
||||||
'org.w3c.dom.html.HTMLTextAreaElement',
|
|
||||||
'org.w3c.dom.html.HTMLTitleElement',
|
|
||||||
'org.w3c.dom.html.HTMLUListElement',
|
|
||||||
'org.w3c.dom.ls.DOMImplementationLS',
|
|
||||||
'org.w3c.dom.ls.LSException',
|
|
||||||
'org.w3c.dom.ls.LSInput',
|
|
||||||
'org.w3c.dom.ls.LSLoadEvent',
|
|
||||||
'org.w3c.dom.ls.LSOutput',
|
|
||||||
'org.w3c.dom.ls.LSParser',
|
|
||||||
'org.w3c.dom.ls.LSParserFilter',
|
|
||||||
'org.w3c.dom.ls.LSProgressEvent',
|
|
||||||
'org.w3c.dom.ls.LSResourceResolver',
|
|
||||||
'org.w3c.dom.ls.LSSerializer',
|
|
||||||
'org.w3c.dom.ls.LSSerializerFilter',
|
|
||||||
'org.w3c.dom.ranges.DocumentRange',
|
|
||||||
'org.w3c.dom.ranges.Range',
|
|
||||||
'org.w3c.dom.ranges.RangeException',
|
|
||||||
'org.w3c.dom.stylesheets.DocumentStyle',
|
|
||||||
'org.w3c.dom.stylesheets.LinkStyle',
|
|
||||||
'org.w3c.dom.stylesheets.MediaList',
|
|
||||||
'org.w3c.dom.stylesheets.StyleSheet',
|
|
||||||
'org.w3c.dom.stylesheets.StyleSheetList',
|
|
||||||
'org.w3c.dom.traversal.DocumentTraversal',
|
|
||||||
'org.w3c.dom.traversal.NodeFilter',
|
|
||||||
'org.w3c.dom.traversal.NodeIterator',
|
|
||||||
'org.w3c.dom.traversal.TreeWalker',
|
|
||||||
'org.w3c.dom.views.AbstractView',
|
|
||||||
'org.w3c.dom.views.DocumentView',
|
|
||||||
'org.w3c.dom.xpath.XPathEvaluator',
|
|
||||||
'org.w3c.dom.xpath.XPathException',
|
|
||||||
'org.w3c.dom.xpath.XPathExpression',
|
|
||||||
'org.w3c.dom.xpath.XPathNSResolver',
|
|
||||||
'org.w3c.dom.xpath.XPathNamespace',
|
|
||||||
'org.w3c.dom.xpath.XPathResult',
|
|
||||||
'org.xml.sax.AttributeList',
|
|
||||||
'org.xml.sax.Attributes',
|
|
||||||
'org.xml.sax.ContentHandler',
|
|
||||||
'org.xml.sax.DTDHandler',
|
|
||||||
'org.xml.sax.DocumentHandler',
|
|
||||||
'org.xml.sax.EntityResolver',
|
|
||||||
'org.xml.sax.ErrorHandler',
|
|
||||||
'org.xml.sax.HandlerBase',
|
|
||||||
'org.xml.sax.InputSource',
|
|
||||||
'org.xml.sax.Locator',
|
|
||||||
'org.xml.sax.Parser',
|
|
||||||
'org.xml.sax.SAXException',
|
|
||||||
'org.xml.sax.SAXNotRecognizedException',
|
|
||||||
'org.xml.sax.SAXNotSupportedException',
|
|
||||||
'org.xml.sax.SAXParseException',
|
|
||||||
'org.xml.sax.XMLFilter',
|
|
||||||
'org.xml.sax.XMLReader',
|
|
||||||
'org.xml.sax.ext.Attributes2',
|
|
||||||
'org.xml.sax.ext.Attributes2Impl',
|
|
||||||
'org.xml.sax.ext.DeclHandler',
|
|
||||||
'org.xml.sax.ext.DefaultHandler2',
|
|
||||||
'org.xml.sax.ext.EntityResolver2',
|
|
||||||
'org.xml.sax.ext.LexicalHandler',
|
|
||||||
'org.xml.sax.ext.Locator2',
|
|
||||||
'org.xml.sax.ext.Locator2Impl',
|
|
||||||
'org.xml.sax.helpers.AttributeListImpl',
|
|
||||||
'org.xml.sax.helpers.AttributesImpl',
|
|
||||||
'org.xml.sax.helpers.DefaultHandler',
|
|
||||||
'org.xml.sax.helpers.LocatorImpl',
|
|
||||||
'org.xml.sax.helpers.NamespaceSupport$Context',
|
|
||||||
'org.xml.sax.helpers.NamespaceSupport',
|
|
||||||
'org.xml.sax.helpers.NewInstance',
|
|
||||||
'org.xml.sax.helpers.ParserAdapter$AttributeListAdapter',
|
|
||||||
'org.xml.sax.helpers.ParserAdapter',
|
|
||||||
'org.xml.sax.helpers.ParserFactory',
|
|
||||||
'org.xml.sax.helpers.SecuritySupport$1',
|
|
||||||
'org.xml.sax.helpers.SecuritySupport$2',
|
|
||||||
'org.xml.sax.helpers.SecuritySupport$3',
|
|
||||||
'org.xml.sax.helpers.SecuritySupport$4',
|
|
||||||
'org.xml.sax.helpers.SecuritySupport',
|
|
||||||
'org.xml.sax.helpers.XMLFilterImpl',
|
|
||||||
'org.xml.sax.helpers.XMLReaderAdapter$AttributesAdapter',
|
|
||||||
'org.xml.sax.helpers.XMLReaderAdapter',
|
|
||||||
'org.xml.sax.helpers.XMLReaderFactory',
|
|
||||||
|
|
||||||
// classes are missing
|
|
||||||
'com.jcraft.jzlib.Deflater',
|
|
||||||
'com.jcraft.jzlib.Inflater',
|
|
||||||
'com.jcraft.jzlib.JZlib$WrapperType',
|
|
||||||
'com.jcraft.jzlib.JZlib',
|
|
||||||
'javassist.ClassClassPath',
|
|
||||||
'javassist.ClassPath',
|
|
||||||
'javassist.ClassPool',
|
|
||||||
'javassist.CtClass',
|
|
||||||
'javassist.CtMethod',
|
|
||||||
'javax.servlet.Filter',
|
|
||||||
'javax.servlet.FilterChain',
|
|
||||||
'javax.servlet.FilterConfig',
|
|
||||||
'javax.servlet.ServletConfig',
|
|
||||||
'javax.servlet.ServletContext',
|
|
||||||
'javax.servlet.ServletContextEvent',
|
|
||||||
'javax.servlet.ServletContextListener',
|
|
||||||
'javax.servlet.ServletException',
|
|
||||||
'javax.servlet.ServletRequest',
|
|
||||||
'javax.servlet.ServletResponse',
|
|
||||||
'javax.servlet.http.HttpServlet',
|
|
||||||
'javax.servlet.http.HttpServletRequest',
|
|
||||||
'javax.servlet.http.HttpServletResponse',
|
|
||||||
'jnr.x86asm.Asm',
|
|
||||||
'jnr.x86asm.Assembler',
|
|
||||||
'jnr.x86asm.CPU',
|
|
||||||
'jnr.x86asm.Mem',
|
|
||||||
'jnr.x86asm.Register',
|
|
||||||
'junit.framework.Assert',
|
|
||||||
'junit.framework.TestCase',
|
|
||||||
'org.antlr.stringtemplate.StringTemplate',
|
|
||||||
'org.eclipse.jetty.alpn.ALPN$ClientProvider',
|
|
||||||
'org.eclipse.jetty.alpn.ALPN$ServerProvider',
|
|
||||||
'org.eclipse.jetty.alpn.ALPN',
|
|
||||||
'org.eclipse.jetty.npn.NextProtoNego$ClientProvider',
|
|
||||||
'org.eclipse.jetty.npn.NextProtoNego$ServerProvider',
|
|
||||||
'org.eclipse.jetty.npn.NextProtoNego',
|
|
||||||
'org.jboss.marshalling.ByteInput',
|
|
||||||
'org.jboss.marshalling.ByteOutput',
|
|
||||||
'org.jboss.marshalling.Marshaller',
|
|
||||||
'org.jboss.marshalling.MarshallerFactory',
|
|
||||||
'org.jboss.marshalling.MarshallingConfiguration',
|
|
||||||
'org.jboss.marshalling.Unmarshaller',
|
|
||||||
'org.junit.Assert',
|
|
||||||
'org.junit.internal.matchers.CombinableMatcher',
|
|
||||||
'org.junit.matchers.JUnitMatchers',
|
|
||||||
'org.junit.runner.JUnitCore',
|
|
||||||
'org.python.apache.commons.logging.Log',
|
|
||||||
'org.python.apache.commons.logging.LogFactory',
|
|
||||||
'org.python.apache.log4j.Level',
|
|
||||||
'org.python.apache.log4j.Logger',
|
|
||||||
'org.python.apache.tomcat.jni.Buffer',
|
|
||||||
'org.python.apache.tomcat.jni.CertificateVerifier',
|
|
||||||
'org.python.apache.tomcat.jni.Library',
|
|
||||||
'org.python.apache.tomcat.jni.Pool',
|
|
||||||
'org.python.apache.tomcat.jni.SSL',
|
|
||||||
'org.python.apache.tomcat.jni.SSLContext',
|
|
||||||
'org.python.apache.tools.ant.BuildException',
|
|
||||||
'org.python.apache.tools.ant.DirectoryScanner',
|
|
||||||
'org.python.apache.tools.ant.Project',
|
|
||||||
'org.python.apache.tools.ant.taskdefs.Execute',
|
|
||||||
'org.python.apache.tools.ant.taskdefs.Java',
|
|
||||||
'org.python.apache.tools.ant.taskdefs.MatchingTask',
|
|
||||||
'org.python.apache.tools.ant.types.Commandline$Argument',
|
|
||||||
'org.python.apache.tools.ant.types.Path',
|
|
||||||
'org.python.apache.tools.ant.types.Resource',
|
|
||||||
'org.python.apache.tools.ant.types.ResourceCollection',
|
|
||||||
'org.python.apache.tools.ant.types.resources.BaseResourceCollectionContainer',
|
|
||||||
'org.python.apache.tools.ant.util.GlobPatternMapper',
|
|
||||||
'org.python.apache.tools.ant.util.SourceFileScanner',
|
|
||||||
'org.python.apache.xml.resolver.Catalog',
|
|
||||||
'org.python.apache.xml.resolver.CatalogManager',
|
|
||||||
'org.python.apache.xml.resolver.readers.SAXCatalogReader',
|
|
||||||
'org.python.google.protobuf.CodedInputStream',
|
|
||||||
'org.python.google.protobuf.CodedOutputStream',
|
|
||||||
'org.python.google.protobuf.ExtensionRegistry',
|
|
||||||
'org.python.google.protobuf.ExtensionRegistryLite',
|
|
||||||
'org.python.google.protobuf.MessageLite$Builder',
|
|
||||||
'org.python.google.protobuf.MessageLite',
|
|
||||||
'org.python.google.protobuf.MessageLiteOrBuilder',
|
|
||||||
'org.python.google.protobuf.Parser',
|
|
||||||
'org.python.objectweb.asm.tree.AbstractInsnNode',
|
|
||||||
'org.python.objectweb.asm.tree.ClassNode',
|
|
||||||
'org.python.objectweb.asm.tree.InsnList',
|
|
||||||
'org.python.objectweb.asm.tree.InsnNode',
|
|
||||||
'org.python.objectweb.asm.tree.JumpInsnNode',
|
|
||||||
'org.python.objectweb.asm.tree.LabelNode',
|
|
||||||
'org.python.objectweb.asm.tree.LocalVariableNode',
|
|
||||||
'org.python.objectweb.asm.tree.LookupSwitchInsnNode',
|
|
||||||
'org.python.objectweb.asm.tree.MethodNode',
|
|
||||||
'org.python.objectweb.asm.tree.TableSwitchInsnNode',
|
|
||||||
'org.python.objectweb.asm.tree.TryCatchBlockNode',
|
|
||||||
'org.python.objectweb.asm.tree.analysis.Analyzer',
|
|
||||||
'org.python.objectweb.asm.tree.analysis.BasicValue',
|
|
||||||
'org.python.objectweb.asm.tree.analysis.BasicVerifier',
|
|
||||||
'org.python.objectweb.asm.tree.analysis.Frame',
|
|
||||||
'org.python.objectweb.asm.tree.analysis.SimpleVerifier',
|
|
||||||
'org.slf4j.Logger',
|
|
||||||
'org.slf4j.LoggerFactory',
|
|
||||||
'org.tukaani.xz.ARMOptions',
|
|
||||||
'org.tukaani.xz.ARMThumbOptions',
|
|
||||||
'org.tukaani.xz.DeltaOptions',
|
|
||||||
'org.tukaani.xz.FilterOptions',
|
|
||||||
'org.tukaani.xz.FinishableWrapperOutputStream',
|
|
||||||
'org.tukaani.xz.IA64Options',
|
|
||||||
'org.tukaani.xz.LZMA2InputStream',
|
|
||||||
'org.tukaani.xz.LZMA2Options',
|
|
||||||
'org.tukaani.xz.LZMAInputStream',
|
|
||||||
'org.tukaani.xz.PowerPCOptions',
|
|
||||||
'org.tukaani.xz.SPARCOptions',
|
|
||||||
'org.tukaani.xz.SingleXZInputStream',
|
|
||||||
'org.tukaani.xz.UnsupportedOptionsException',
|
|
||||||
'org.tukaani.xz.X86Options',
|
|
||||||
'org.tukaani.xz.XZ',
|
|
||||||
'org.tukaani.xz.XZInputStream',
|
|
||||||
'org.tukaani.xz.XZOutputStream',
|
|
||||||
]
|
|
|
@ -1 +0,0 @@
|
||||||
cdfb38bc6f8343bcf1d6accc2e1147e8e7b63b75
|
|
|
@ -1,201 +0,0 @@
|
||||||
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.
|
|
|
@ -1,11 +0,0 @@
|
||||||
Apache Commons Compress
|
|
||||||
Copyright 2002-2014 The Apache Software Foundation
|
|
||||||
|
|
||||||
This product includes software developed at
|
|
||||||
The Apache Software Foundation (http://www.apache.org/).
|
|
||||||
|
|
||||||
The files in the package org.apache.commons.compress.archivers.sevenz
|
|
||||||
were derived from the LZMA SDK, version 9.20 (C/ and CPP/7zip/),
|
|
||||||
which has been placed in the public domain:
|
|
||||||
|
|
||||||
"LZMA SDK is placed in the public domain." (http://www.7-zip.org/sdk.html)
|
|
|
@ -1,35 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.plugin.python;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.plugins.Plugin;
|
|
||||||
import org.elasticsearch.plugins.ScriptPlugin;
|
|
||||||
import org.elasticsearch.script.ScriptEngineRegistry;
|
|
||||||
import org.elasticsearch.script.ScriptEngineService;
|
|
||||||
import org.elasticsearch.script.ScriptModule;
|
|
||||||
import org.elasticsearch.script.python.PythonScriptEngineService;
|
|
||||||
|
|
||||||
public class PythonPlugin extends Plugin implements ScriptPlugin {
|
|
||||||
@Override
|
|
||||||
public ScriptEngineService getScriptEngineService(Settings settings) {
|
|
||||||
return new PythonScriptEngineService(settings);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,286 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.python;
|
|
||||||
|
|
||||||
import org.apache.lucene.index.LeafReaderContext;
|
|
||||||
import org.apache.lucene.search.Scorer;
|
|
||||||
import org.elasticsearch.SpecialPermission;
|
|
||||||
import org.elasticsearch.common.Nullable;
|
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.script.ClassPermission;
|
|
||||||
import org.elasticsearch.script.CompiledScript;
|
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
|
||||||
import org.elasticsearch.script.LeafSearchScript;
|
|
||||||
import org.elasticsearch.script.ScoreAccessor;
|
|
||||||
import org.elasticsearch.script.ScriptEngineService;
|
|
||||||
import org.elasticsearch.script.SearchScript;
|
|
||||||
import org.elasticsearch.search.lookup.LeafSearchLookup;
|
|
||||||
import org.elasticsearch.search.lookup.SearchLookup;
|
|
||||||
import org.python.core.Py;
|
|
||||||
import org.python.core.PyCode;
|
|
||||||
import org.python.core.PyObject;
|
|
||||||
import org.python.core.PyStringMap;
|
|
||||||
import org.python.util.PythonInterpreter;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.AccessControlContext;
|
|
||||||
import java.security.AccessController;
|
|
||||||
import java.security.Permissions;
|
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.security.ProtectionDomain;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
//TODO we can optimize the case for Map<String, Object> similar to PyStringMap
|
|
||||||
public class PythonScriptEngineService extends AbstractComponent implements ScriptEngineService {
|
|
||||||
|
|
||||||
public static final String NAME = "python";
|
|
||||||
public static final String EXTENSION = "py";
|
|
||||||
|
|
||||||
private final PythonInterpreter interp;
|
|
||||||
|
|
||||||
public PythonScriptEngineService(Settings settings) {
|
|
||||||
super(settings);
|
|
||||||
|
|
||||||
deprecationLogger.deprecated("[python] scripts are deprecated, use [painless] scripts instead.");
|
|
||||||
|
|
||||||
// classloader created here
|
|
||||||
final SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
sm.checkPermission(new SpecialPermission());
|
|
||||||
}
|
|
||||||
this.interp = AccessController.doPrivileged(new PrivilegedAction<PythonInterpreter> () {
|
|
||||||
@Override
|
|
||||||
public PythonInterpreter run() {
|
|
||||||
// snapshot our context here for checks, as the script has no permissions
|
|
||||||
final AccessControlContext engineContext = AccessController.getContext();
|
|
||||||
PythonInterpreter interp = PythonInterpreter.threadLocalStateInterpreter(null);
|
|
||||||
if (sm != null) {
|
|
||||||
interp.getSystemState().setClassLoader(new ClassLoader(getClass().getClassLoader()) {
|
|
||||||
@Override
|
|
||||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
|
||||||
try {
|
|
||||||
engineContext.checkPermission(new ClassPermission(name));
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
throw new ClassNotFoundException(name, e);
|
|
||||||
}
|
|
||||||
return super.loadClass(name, resolve);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return interp;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getType() {
|
|
||||||
return NAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getExtension() {
|
|
||||||
return EXTENSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object compile(String scriptName, String scriptSource, Map<String, String> params) {
|
|
||||||
// classloader created here
|
|
||||||
SecurityManager sm = System.getSecurityManager();
|
|
||||||
if (sm != null) {
|
|
||||||
sm.checkPermission(new SpecialPermission());
|
|
||||||
}
|
|
||||||
return AccessController.doPrivileged(new PrivilegedAction<PyCode>() {
|
|
||||||
@Override
|
|
||||||
public PyCode run() {
|
|
||||||
return interp.compile(scriptSource);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ExecutableScript executable(CompiledScript compiledScript, Map<String, Object> vars) {
|
|
||||||
deprecationLogger.deprecated("[python] scripts are deprecated, use [painless] scripts instead");
|
|
||||||
|
|
||||||
return new PythonExecutableScript((PyCode) compiledScript.compiled(), vars);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SearchScript search(final CompiledScript compiledScript, final SearchLookup lookup, @Nullable final Map<String, Object> vars) {
|
|
||||||
deprecationLogger.deprecated("[python] scripts are deprecated, use [painless] scripts instead");
|
|
||||||
|
|
||||||
return new SearchScript() {
|
|
||||||
@Override
|
|
||||||
public LeafSearchScript getLeafSearchScript(LeafReaderContext context) throws IOException {
|
|
||||||
final LeafSearchLookup leafLookup = lookup.getLeafSearchLookup(context);
|
|
||||||
return new PythonSearchScript((PyCode) compiledScript.compiled(), vars, leafLookup);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public boolean needsScores() {
|
|
||||||
// TODO: can we reliably know if a python script makes use of _score
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
interp.cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PythonExecutableScript implements ExecutableScript {
|
|
||||||
|
|
||||||
private final PyCode code;
|
|
||||||
|
|
||||||
private final PyStringMap pyVars;
|
|
||||||
|
|
||||||
public PythonExecutableScript(PyCode code, Map<String, Object> vars) {
|
|
||||||
this.code = code;
|
|
||||||
this.pyVars = new PyStringMap();
|
|
||||||
if (vars != null) {
|
|
||||||
for (Map.Entry<String, Object> entry : vars.entrySet()) {
|
|
||||||
pyVars.__setitem__(entry.getKey(), Py.java2py(entry.getValue()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNextVar(String name, Object value) {
|
|
||||||
pyVars.__setitem__(name, Py.java2py(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object run() {
|
|
||||||
interp.setLocals(pyVars);
|
|
||||||
// eval the script with reduced privileges
|
|
||||||
PyObject ret = evalRestricted(code);
|
|
||||||
if (ret == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return ret.__tojava__(Object.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object unwrap(Object value) {
|
|
||||||
return unwrapValue(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class PythonSearchScript implements LeafSearchScript {
|
|
||||||
|
|
||||||
private final PyCode code;
|
|
||||||
|
|
||||||
private final PyStringMap pyVars;
|
|
||||||
|
|
||||||
private final LeafSearchLookup lookup;
|
|
||||||
|
|
||||||
public PythonSearchScript(PyCode code, Map<String, Object> vars, LeafSearchLookup lookup) {
|
|
||||||
this.code = code;
|
|
||||||
this.pyVars = new PyStringMap();
|
|
||||||
for (Map.Entry<String, Object> entry : lookup.asMap().entrySet()) {
|
|
||||||
pyVars.__setitem__(entry.getKey(), Py.java2py(entry.getValue()));
|
|
||||||
}
|
|
||||||
if (vars != null) {
|
|
||||||
for (Map.Entry<String, Object> entry : vars.entrySet()) {
|
|
||||||
pyVars.__setitem__(entry.getKey(), Py.java2py(entry.getValue()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.lookup = lookup;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setScorer(Scorer scorer) {
|
|
||||||
pyVars.__setitem__("_score", Py.java2py(new ScoreAccessor(scorer)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDocument(int doc) {
|
|
||||||
lookup.setDocument(doc);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSource(Map<String, Object> source) {
|
|
||||||
lookup.source().setSource(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setNextVar(String name, Object value) {
|
|
||||||
pyVars.__setitem__(name, Py.java2py(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object run() {
|
|
||||||
interp.setLocals(pyVars);
|
|
||||||
// eval the script with reduced privileges
|
|
||||||
PyObject ret = evalRestricted(code);
|
|
||||||
if (ret == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return ret.__tojava__(Object.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long runAsLong() {
|
|
||||||
return ((Number) run()).longValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double runAsDouble() {
|
|
||||||
return ((Number) run()).doubleValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object unwrap(Object value) {
|
|
||||||
return unwrapValue(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we don't have a way to specify codesource for generated jython classes,
|
|
||||||
// so we just run them with a special context to reduce privileges
|
|
||||||
private static final AccessControlContext PY_CONTEXT;
|
|
||||||
static {
|
|
||||||
Permissions none = new Permissions();
|
|
||||||
none.setReadOnly();
|
|
||||||
PY_CONTEXT = new AccessControlContext(new ProtectionDomain[] {
|
|
||||||
new ProtectionDomain(null, none)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Evaluates with reduced privileges */
|
|
||||||
private PyObject evalRestricted(final PyCode code) {
|
|
||||||
// eval the script with reduced privileges
|
|
||||||
return AccessController.doPrivileged(new PrivilegedAction<PyObject>() {
|
|
||||||
@Override
|
|
||||||
public PyObject run() {
|
|
||||||
return interp.eval(code);
|
|
||||||
}
|
|
||||||
}, PY_CONTEXT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Object unwrapValue(Object value) {
|
|
||||||
if (value == null) {
|
|
||||||
return null;
|
|
||||||
} else if (value instanceof PyObject) {
|
|
||||||
// seems like this is enough, inner PyDictionary will do the conversion for us for example, so expose it directly
|
|
||||||
return ((PyObject) value).__tojava__(Object.class);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
grant {
|
|
||||||
// needed to generate runtime classes
|
|
||||||
permission java.lang.RuntimePermission "createClassLoader";
|
|
||||||
// needed by PySystemState init (TODO: see if we can avoid this)
|
|
||||||
permission java.lang.RuntimePermission "getClassLoader";
|
|
||||||
// Standard set of classes
|
|
||||||
permission org.elasticsearch.script.ClassPermission "<<STANDARD>>";
|
|
||||||
};
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.python;
|
|
||||||
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.Name;
|
|
||||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
|
||||||
|
|
||||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
|
||||||
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
|
||||||
import org.elasticsearch.test.rest.yaml.parser.ClientYamlTestParseException;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class LangPythonClientYamlTestSuiteIT extends ESClientYamlSuiteTestCase {
|
|
||||||
|
|
||||||
public LangPythonClientYamlTestSuiteIT(@Name("yaml") ClientYamlTestCandidate testCandidate) {
|
|
||||||
super(testCandidate);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParametersFactory
|
|
||||||
public static Iterable<Object[]> parameters() throws IOException, ClientYamlTestParseException {
|
|
||||||
return ESClientYamlSuiteTestCase.createParameters();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,146 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.python;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.collect.MapBuilder;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.script.CompiledScript;
|
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
|
||||||
import org.elasticsearch.script.ScriptType;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
|
||||||
import static org.hamcrest.Matchers.instanceOf;
|
|
||||||
|
|
||||||
public class PythonScriptEngineTests extends ESTestCase {
|
|
||||||
private PythonScriptEngineService se;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setup() {
|
|
||||||
se = new PythonScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void close() {
|
|
||||||
se.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSimpleEquation() {
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
Object o = se.executable(new CompiledScript(ScriptType.INLINE, "testSimpleEquation", "python", se.compile(null, "1 + 2", Collections.emptyMap())), vars).run();
|
|
||||||
assertThat(((Number) o).intValue(), equalTo(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void testMapAccess() {
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
|
|
||||||
Map<String, Object> obj2 = MapBuilder.<String, Object>newMapBuilder().put("prop2", "value2").map();
|
|
||||||
Map<String, Object> obj1 = MapBuilder.<String, Object>newMapBuilder().put("prop1", "value1").put("obj2", obj2).put("l", Arrays.asList("2", "1")).map();
|
|
||||||
vars.put("obj1", obj1);
|
|
||||||
Object o = se.executable(new CompiledScript(ScriptType.INLINE, "testMapAccess", "python", se.compile(null, "obj1", Collections.emptyMap())), vars).run();
|
|
||||||
assertThat(o, instanceOf(Map.class));
|
|
||||||
obj1 = (Map<String, Object>) o;
|
|
||||||
assertThat((String) obj1.get("prop1"), equalTo("value1"));
|
|
||||||
assertThat((String) ((Map<String, Object>) obj1.get("obj2")).get("prop2"), equalTo("value2"));
|
|
||||||
|
|
||||||
o = se.executable(new CompiledScript(ScriptType.INLINE, "testMapAccess", "python", se.compile(null, "obj1['l'][0]", Collections.emptyMap())), vars).run();
|
|
||||||
assertThat(((String) o), equalTo("2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void testObjectMapInter() {
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
Map<String, Object> ctx = new HashMap<String, Object>();
|
|
||||||
Map<String, Object> obj1 = new HashMap<String, Object>();
|
|
||||||
obj1.put("prop1", "value1");
|
|
||||||
ctx.put("obj1", obj1);
|
|
||||||
vars.put("ctx", ctx);
|
|
||||||
|
|
||||||
ExecutableScript executable = se.executable(new CompiledScript(ScriptType.INLINE, "testObjectInterMap", "python",
|
|
||||||
se.compile(null, "ctx['obj2'] = { 'prop2' : 'value2' }; ctx['obj1']['prop1'] = 'uvalue1'", Collections.emptyMap())), vars);
|
|
||||||
executable.run();
|
|
||||||
ctx = (Map<String, Object>) executable.unwrap(vars.get("ctx"));
|
|
||||||
assertThat(ctx.containsKey("obj1"), equalTo(true));
|
|
||||||
assertThat((String) ((Map<String, Object>) ctx.get("obj1")).get("prop1"), equalTo("uvalue1"));
|
|
||||||
assertThat(ctx.containsKey("obj2"), equalTo(true));
|
|
||||||
assertThat((String) ((Map<String, Object>) ctx.get("obj2")).get("prop2"), equalTo("value2"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void testAccessListInScript() {
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
Map<String, Object> obj2 = MapBuilder.<String, Object>newMapBuilder().put("prop2", "value2").map();
|
|
||||||
Map<String, Object> obj1 = MapBuilder.<String, Object>newMapBuilder().put("prop1", "value1").put("obj2", obj2).map();
|
|
||||||
vars.put("l", Arrays.asList("1", "2", "3", obj1));
|
|
||||||
|
|
||||||
// Object o = se.execute(se.compile("l.length"), vars);
|
|
||||||
// assertThat(((Number) o).intValue(), equalTo(4));
|
|
||||||
|
|
||||||
Object o = se.executable(new CompiledScript(ScriptType.INLINE, "testAccessListInScript", "python", se.compile(null, "l[0]", Collections.emptyMap())), vars).run();
|
|
||||||
assertThat(((String) o), equalTo("1"));
|
|
||||||
|
|
||||||
o = se.executable(new CompiledScript(ScriptType.INLINE, "testAccessListInScript", "python", se.compile(null, "l[3]", Collections.emptyMap())), vars).run();
|
|
||||||
obj1 = (Map<String, Object>) o;
|
|
||||||
assertThat((String) obj1.get("prop1"), equalTo("value1"));
|
|
||||||
assertThat((String) ((Map<String, Object>) obj1.get("obj2")).get("prop2"), equalTo("value2"));
|
|
||||||
|
|
||||||
o = se.executable(new CompiledScript(ScriptType.INLINE, "testAccessListInScript", "python", se.compile(null, "l[3]['prop1']", Collections.emptyMap())), vars).run();
|
|
||||||
assertThat(((String) o), equalTo("value1"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testChangingVarsCrossExecution1() {
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
Map<String, Object> ctx = new HashMap<String, Object>();
|
|
||||||
vars.put("ctx", ctx);
|
|
||||||
Object compiledScript = se.compile(null, "ctx['value']", Collections.emptyMap());
|
|
||||||
|
|
||||||
ExecutableScript script = se.executable(new CompiledScript(ScriptType.INLINE, "testChangingVarsCrossExecution1", "python", compiledScript), vars);
|
|
||||||
ctx.put("value", 1);
|
|
||||||
Object o = script.run();
|
|
||||||
assertThat(((Number) o).intValue(), equalTo(1));
|
|
||||||
|
|
||||||
ctx.put("value", 2);
|
|
||||||
o = script.run();
|
|
||||||
assertThat(((Number) o).intValue(), equalTo(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testChangingVarsCrossExecution2() {
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
Map<String, Object> ctx = new HashMap<String, Object>();
|
|
||||||
Object compiledScript = se.compile(null, "value", Collections.emptyMap());
|
|
||||||
|
|
||||||
ExecutableScript script = se.executable(new CompiledScript(ScriptType.INLINE, "testChangingVarsCrossExecution2", "python", compiledScript), vars);
|
|
||||||
script.setNextVar("value", 1);
|
|
||||||
Object o = script.run();
|
|
||||||
assertThat(((Number) o).intValue(), equalTo(1));
|
|
||||||
|
|
||||||
script.setNextVar("value", 2);
|
|
||||||
o = script.run();
|
|
||||||
assertThat(((Number) o).intValue(), equalTo(2));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,167 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.python;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.Randomness;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.script.CompiledScript;
|
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
|
||||||
import org.elasticsearch.script.ScriptType;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.CyclicBarrier;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
|
||||||
|
|
||||||
public class PythonScriptMultiThreadedTests extends ESTestCase {
|
|
||||||
|
|
||||||
public void testExecutableNoRuntimeParams() throws Exception {
|
|
||||||
final PythonScriptEngineService se = new PythonScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
|
||||||
final Object compiled = se.compile(null, "x + y", Collections.emptyMap());
|
|
||||||
final CompiledScript compiledScript = new CompiledScript(ScriptType.INLINE, "testExecutableNoRuntimeParams", "python", compiled);
|
|
||||||
final AtomicBoolean failed = new AtomicBoolean();
|
|
||||||
|
|
||||||
Thread[] threads = new Thread[4];
|
|
||||||
final CountDownLatch latch = new CountDownLatch(threads.length);
|
|
||||||
final CyclicBarrier barrier = new CyclicBarrier(threads.length + 1);
|
|
||||||
for (int i = 0; i < threads.length; i++) {
|
|
||||||
threads[i] = new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
barrier.await();
|
|
||||||
long x = Randomness.get().nextInt();
|
|
||||||
long y = Randomness.get().nextInt();
|
|
||||||
long addition = x + y;
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
vars.put("x", x);
|
|
||||||
vars.put("y", y);
|
|
||||||
ExecutableScript script = se.executable(compiledScript, vars);
|
|
||||||
for (int i = 0; i < 10000; i++) {
|
|
||||||
long result = ((Number) script.run()).longValue();
|
|
||||||
assertThat(result, equalTo(addition));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
failed.set(true);
|
|
||||||
logger.error("failed", e);
|
|
||||||
} finally {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for (int i = 0; i < threads.length; i++) {
|
|
||||||
threads[i].start();
|
|
||||||
}
|
|
||||||
barrier.await();
|
|
||||||
latch.await();
|
|
||||||
assertThat(failed.get(), equalTo(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// public void testExecutableWithRuntimeParams() throws Exception {
|
|
||||||
// final PythonScriptEngineService se = new PythonScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
|
||||||
// final Object compiled = se.compile("x + y");
|
|
||||||
// final AtomicBoolean failed = new AtomicBoolean();
|
|
||||||
//
|
|
||||||
// Thread[] threads = new Thread[50];
|
|
||||||
// final CountDownLatch latch = new CountDownLatch(threads.length);
|
|
||||||
// final CyclicBarrier barrier = new CyclicBarrier(threads.length + 1);
|
|
||||||
// for (int i = 0; i < threads.length; i++) {
|
|
||||||
// threads[i] = new Thread(new Runnable() {
|
|
||||||
// @Override public void run() {
|
|
||||||
// try {
|
|
||||||
// barrier.await();
|
|
||||||
// long x = Randomness.get().nextInt();
|
|
||||||
// Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
// vars.put("x", x);
|
|
||||||
// ExecutableScript script = se.executable(compiled, vars);
|
|
||||||
// Map<String, Object> runtimeVars = new HashMap<String, Object>();
|
|
||||||
// for (int i = 0; i < 100000; i++) {
|
|
||||||
// long y = Randomness.get().nextInt();
|
|
||||||
// long addition = x + y;
|
|
||||||
// runtimeVars.put("y", y);
|
|
||||||
// long result = ((Number) script.run(runtimeVars)).longValue();
|
|
||||||
// assertThat(result, equalTo(addition));
|
|
||||||
// }
|
|
||||||
// } catch (Exception e) {
|
|
||||||
// failed.set(true);
|
|
||||||
// logger.error("failed", e);
|
|
||||||
// } finally {
|
|
||||||
// latch.countDown();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// for (int i = 0; i < threads.length; i++) {
|
|
||||||
// threads[i].start();
|
|
||||||
// }
|
|
||||||
// barrier.await();
|
|
||||||
// latch.await();
|
|
||||||
// assertThat(failed.get(), equalTo(false));
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void testExecute() throws Exception {
|
|
||||||
final PythonScriptEngineService se = new PythonScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
|
||||||
final Object compiled = se.compile(null, "x + y", Collections.emptyMap());
|
|
||||||
final CompiledScript compiledScript = new CompiledScript(ScriptType.INLINE, "testExecute", "python", compiled);
|
|
||||||
final AtomicBoolean failed = new AtomicBoolean();
|
|
||||||
|
|
||||||
Thread[] threads = new Thread[4];
|
|
||||||
final CountDownLatch latch = new CountDownLatch(threads.length);
|
|
||||||
final CyclicBarrier barrier = new CyclicBarrier(threads.length + 1);
|
|
||||||
for (int i = 0; i < threads.length; i++) {
|
|
||||||
threads[i] = new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
barrier.await();
|
|
||||||
Map<String, Object> runtimeVars = new HashMap<String, Object>();
|
|
||||||
for (int i = 0; i < 10000; i++) {
|
|
||||||
long x = Randomness.get().nextInt();
|
|
||||||
long y = Randomness.get().nextInt();
|
|
||||||
long addition = x + y;
|
|
||||||
runtimeVars.put("x", x);
|
|
||||||
runtimeVars.put("y", y);
|
|
||||||
long result = ((Number) se.executable(compiledScript, runtimeVars).run()).longValue();
|
|
||||||
assertThat(result, equalTo(addition));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
failed.set(true);
|
|
||||||
logger.error("failed", e);
|
|
||||||
} finally {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for (int i = 0; i < threads.length; i++) {
|
|
||||||
threads[i].start();
|
|
||||||
}
|
|
||||||
barrier.await();
|
|
||||||
latch.await();
|
|
||||||
assertThat(failed.get(), equalTo(false));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,110 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.python;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.script.CompiledScript;
|
|
||||||
import org.elasticsearch.script.ScriptType;
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
|
||||||
import org.python.core.PyException;
|
|
||||||
|
|
||||||
import java.text.DecimalFormatSymbols;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tests for Python security permissions
|
|
||||||
*/
|
|
||||||
public class PythonSecurityTests extends ESTestCase {
|
|
||||||
|
|
||||||
private PythonScriptEngineService se;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
se = new PythonScriptEngineService(Settings.Builder.EMPTY_SETTINGS);
|
|
||||||
// otherwise will exit your VM and other bad stuff
|
|
||||||
assumeTrue("test requires security manager to be enabled", System.getSecurityManager() != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
se.close();
|
|
||||||
super.tearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** runs a script */
|
|
||||||
private void doTest(String script) {
|
|
||||||
Map<String, Object> vars = new HashMap<String, Object>();
|
|
||||||
se.executable(new CompiledScript(ScriptType.INLINE, "test", "python", se.compile(null, script, Collections.emptyMap())), vars).run();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** asserts that a script runs without exception */
|
|
||||||
private void assertSuccess(String script) {
|
|
||||||
doTest(script);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** assert that a security exception is hit */
|
|
||||||
private void assertFailure(String script) {
|
|
||||||
try {
|
|
||||||
doTest(script);
|
|
||||||
fail("did not get expected exception");
|
|
||||||
} catch (PyException expected) {
|
|
||||||
// TODO: fix jython localization bugs: https://github.com/elastic/elasticsearch/issues/13967
|
|
||||||
// we do a gross hack for now
|
|
||||||
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(Locale.getDefault());
|
|
||||||
if (symbols.getZeroDigit() == '0') {
|
|
||||||
assertTrue(expected.toString().contains("cannot import"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Test some py scripts that are ok */
|
|
||||||
public void testOK() {
|
|
||||||
assertSuccess("1 + 2");
|
|
||||||
assertSuccess("from java.lang import Math\nMath.cos(0)");
|
|
||||||
assertSuccess("map(lambda x: x + 1, range(100))");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Test some py scripts that should hit security exception */
|
|
||||||
public void testNotOK() {
|
|
||||||
// sanity check :)
|
|
||||||
assertFailure("from java.lang import Runtime\nRuntime.getRuntime().halt(0)");
|
|
||||||
// check a few things more restrictive than the ordinary policy
|
|
||||||
// no network
|
|
||||||
assertFailure("from java.net import Socket\nSocket(\"localhost\", 1024)");
|
|
||||||
// no files
|
|
||||||
assertFailure("from java.io import File\nFile.createTempFile(\"test\", \"tmp\")");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Test again from a new thread, python has complex threadlocal configuration */
|
|
||||||
public void testNotOKFromSeparateThread() throws Exception {
|
|
||||||
Thread t = new Thread() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
assertFailure("from java.lang import Runtime\nRuntime.availableProcessors()");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
t.start();
|
|
||||||
t.join();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
# Integration tests for Lang Python components
|
|
||||||
#
|
|
||||||
setup:
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body: { "foo": "aaa" }
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"Lang Python":
|
|
||||||
- do:
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
script_fields:
|
|
||||||
bar:
|
|
||||||
script:
|
|
||||||
inline: "doc['foo.keyword'].value + x"
|
|
||||||
lang: python
|
|
||||||
params:
|
|
||||||
x: "bbb"
|
|
||||||
|
|
||||||
- match: { hits.hits.0.fields.bar.0: "aaabbb"}
|
|
|
@ -1,345 +0,0 @@
|
||||||
# Integration tests for Lang Python components
|
|
||||||
#
|
|
||||||
"Python Query":
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body: { "test": "value beck", "num1": 1.0 }
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 2
|
|
||||||
body: { "test": "value beck", "num1": 2.0 }
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 3
|
|
||||||
body: { "test": "value beck", "num1": 3.0 }
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
script:
|
|
||||||
script:
|
|
||||||
inline: "doc['num1'].value > 1"
|
|
||||||
lang: python
|
|
||||||
script_fields:
|
|
||||||
sNum1:
|
|
||||||
script:
|
|
||||||
inline: "doc['num1'].value"
|
|
||||||
lang: python
|
|
||||||
sort:
|
|
||||||
num1:
|
|
||||||
order: asc
|
|
||||||
|
|
||||||
- match: { hits.total: 2 }
|
|
||||||
- match: { hits.hits.0.fields.sNum1.0: 2.0 }
|
|
||||||
- match: { hits.hits.1.fields.sNum1.0: 3.0 }
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
script:
|
|
||||||
script:
|
|
||||||
inline: "doc['num1'].value > param1"
|
|
||||||
lang: python
|
|
||||||
params:
|
|
||||||
param1: 1
|
|
||||||
|
|
||||||
script_fields:
|
|
||||||
sNum1:
|
|
||||||
script:
|
|
||||||
inline: "doc['num1'].value"
|
|
||||||
lang: python
|
|
||||||
sort:
|
|
||||||
num1:
|
|
||||||
order: asc
|
|
||||||
|
|
||||||
- match: { hits.total: 2 }
|
|
||||||
- match: { hits.hits.0.fields.sNum1.0: 2.0 }
|
|
||||||
- match: { hits.hits.1.fields.sNum1.0: 3.0 }
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
script:
|
|
||||||
script:
|
|
||||||
inline: "doc['num1'].value > param1"
|
|
||||||
lang: python
|
|
||||||
params:
|
|
||||||
param1: -1
|
|
||||||
|
|
||||||
script_fields:
|
|
||||||
sNum1:
|
|
||||||
script:
|
|
||||||
inline: "doc['num1'].value"
|
|
||||||
lang: python
|
|
||||||
sort:
|
|
||||||
num1:
|
|
||||||
order: asc
|
|
||||||
|
|
||||||
- match: { hits.total: 3 }
|
|
||||||
- match: { hits.hits.0.fields.sNum1.0: 1.0 }
|
|
||||||
- match: { hits.hits.1.fields.sNum1.0: 2.0 }
|
|
||||||
- match: { hits.hits.2.fields.sNum1.0: 3.0 }
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"Python Script Field Using Source":
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body: {
|
|
||||||
"obj1": {
|
|
||||||
"test": "something"
|
|
||||||
},
|
|
||||||
"obj2": {
|
|
||||||
"arr2": [ "arr_value1", "arr_value2" ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
script_fields:
|
|
||||||
s_obj1:
|
|
||||||
script:
|
|
||||||
inline: "_source['obj1']"
|
|
||||||
lang: python
|
|
||||||
s_obj1_test:
|
|
||||||
script:
|
|
||||||
inline: "_source['obj1']['test']"
|
|
||||||
lang: python
|
|
||||||
s_obj2:
|
|
||||||
script:
|
|
||||||
inline: "_source['obj2']"
|
|
||||||
lang: python
|
|
||||||
s_obj2_arr2:
|
|
||||||
script:
|
|
||||||
inline: "_source['obj2']['arr2']"
|
|
||||||
lang: python
|
|
||||||
|
|
||||||
- match: { hits.total: 1 }
|
|
||||||
- match: { hits.hits.0.fields.s_obj1.0.test: something }
|
|
||||||
- match: { hits.hits.0.fields.s_obj1_test.0: something }
|
|
||||||
- match: { hits.hits.0.fields.s_obj2.0.arr2.0: arr_value1 }
|
|
||||||
- match: { hits.hits.0.fields.s_obj2.0.arr2.1: arr_value2 }
|
|
||||||
- match: { hits.hits.0.fields.s_obj2_arr2.0: arr_value1 }
|
|
||||||
- match: { hits.hits.0.fields.s_obj2_arr2.1: arr_value2 }
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"Python Custom Script Boost":
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body: { "test": "value beck", "num1": 1.0 }
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 2
|
|
||||||
body: { "test": "value beck", "num1": 2.0 }
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
query:
|
|
||||||
term:
|
|
||||||
test: value
|
|
||||||
"functions": [{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "python",
|
|
||||||
"inline": "doc['num1'].value"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
- match: { hits.total: 2 }
|
|
||||||
- match: { hits.hits.0._id: "2" }
|
|
||||||
- match: { hits.hits.1._id: "1" }
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
query:
|
|
||||||
term:
|
|
||||||
test: value
|
|
||||||
"functions": [{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "python",
|
|
||||||
"inline": "-doc['num1'].value"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
- match: { hits.total: 2 }
|
|
||||||
- match: { hits.hits.0._id: "1" }
|
|
||||||
- match: { hits.hits.1._id: "2" }
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
query:
|
|
||||||
term:
|
|
||||||
test: value
|
|
||||||
"functions": [{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "python",
|
|
||||||
"inline": "doc['num1'].value * _score.doubleValue()"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
- match: { hits.total: 2 }
|
|
||||||
- match: { hits.hits.0._id: "2" }
|
|
||||||
- match: { hits.hits.1._id: "1" }
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
query:
|
|
||||||
term:
|
|
||||||
test: value
|
|
||||||
"functions": [{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "python",
|
|
||||||
"inline": "param1 * param2 * _score.doubleValue()",
|
|
||||||
"params": {
|
|
||||||
"param1": 2,
|
|
||||||
"param2": 2
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
- match: { hits.total: 2 }
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"Python Scores Nested":
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body: { "dummy_field": 1 }
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
"functions": [
|
|
||||||
{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "python",
|
|
||||||
"inline": "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "python",
|
|
||||||
"inline": "_score.doubleValue()"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
"functions": [{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "python",
|
|
||||||
"inline": "_score.doubleValue()"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
|
|
||||||
- match: { hits.total: 1 }
|
|
||||||
- match: { hits.hits.0._score: 1.0 }
|
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
"Python Scores With Agg":
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body: { "dummy_field": 1 }
|
|
||||||
- do:
|
|
||||||
indices.refresh: {}
|
|
||||||
|
|
||||||
|
|
||||||
- do:
|
|
||||||
index: test
|
|
||||||
search:
|
|
||||||
body:
|
|
||||||
query:
|
|
||||||
function_score:
|
|
||||||
"functions": [{
|
|
||||||
"script_score": {
|
|
||||||
"script": {
|
|
||||||
"lang": "python",
|
|
||||||
"inline": "_score.doubleValue()"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
aggs:
|
|
||||||
score_agg:
|
|
||||||
terms:
|
|
||||||
script:
|
|
||||||
lang: python
|
|
||||||
inline: "_score.doubleValue()"
|
|
||||||
|
|
||||||
- match: { hits.total: 1 }
|
|
||||||
- match: { hits.hits.0._score: 1.0 }
|
|
||||||
- match: { aggregations.score_agg.buckets.0.key: "1.0" }
|
|
||||||
- match: { aggregations.score_agg.buckets.0.doc_count: 1 }
|
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
# Integration tests for Lang Python components
|
|
||||||
#
|
|
||||||
|
|
||||||
# Test case for #4: https://github.com/elastic/elasticsearch-lang-python/issues/4
|
|
||||||
# Update request that uses python script with no parameters fails with NullPointerException
|
|
||||||
#
|
|
||||||
"Python Update With Empty Parameters":
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body: { "myfield": "foo" }
|
|
||||||
- do:
|
|
||||||
update:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body:
|
|
||||||
script:
|
|
||||||
inline: "ctx[\"_source\"][\"myfield\"]=\"bar\""
|
|
||||||
lang: python
|
|
||||||
- do:
|
|
||||||
get:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
|
|
||||||
- match: { _source.myfield: "bar" }
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# Test case for #19: https://github.com/elastic/elasticsearch-lang-python/issues/19
|
|
||||||
# Multi-line or multi-statement Python scripts raise NullPointerException
|
|
||||||
#
|
|
||||||
"Python Update With Multi Lines":
|
|
||||||
- do:
|
|
||||||
index:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body: { "myfield": "foo" }
|
|
||||||
- do:
|
|
||||||
update:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
body:
|
|
||||||
script:
|
|
||||||
inline: "a=42; ctx[\"_source\"][\"myfield\"]=\"bar\""
|
|
||||||
lang: python
|
|
||||||
- do:
|
|
||||||
get:
|
|
||||||
index: test
|
|
||||||
type: test
|
|
||||||
id: 1
|
|
||||||
|
|
||||||
- match: { _source.myfield: "bar" }
|
|
||||||
|
|
|
@ -267,14 +267,6 @@ fi
|
||||||
check_secure_module lang-painless antlr4-runtime-*.jar asm-debug-all-*.jar
|
check_secure_module lang-painless antlr4-runtime-*.jar asm-debug-all-*.jar
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "[$GROUP] install javascript plugin" {
|
|
||||||
install_and_check_plugin lang javascript rhino-*.jar
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "[$GROUP] install python plugin" {
|
|
||||||
install_and_check_plugin lang python jython-standalone-*.jar
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "[$GROUP] install murmur3 mapper plugin" {
|
@test "[$GROUP] install murmur3 mapper plugin" {
|
||||||
install_and_check_plugin mapper murmur3
|
install_and_check_plugin mapper murmur3
|
||||||
}
|
}
|
||||||
|
@ -381,14 +373,6 @@ fi
|
||||||
remove_plugin ingest-user-agent
|
remove_plugin ingest-user-agent
|
||||||
}
|
}
|
||||||
|
|
||||||
@test "[$GROUP] remove javascript plugin" {
|
|
||||||
remove_plugin lang-javascript
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "[$GROUP] remove python plugin" {
|
|
||||||
remove_plugin lang-python
|
|
||||||
}
|
|
||||||
|
|
||||||
@test "[$GROUP] remove murmur3 mapper plugin" {
|
@test "[$GROUP] remove murmur3 mapper plugin" {
|
||||||
remove_plugin mapper-murmur3
|
remove_plugin mapper-murmur3
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,6 @@ List projects = [
|
||||||
'plugins:ingest-geoip',
|
'plugins:ingest-geoip',
|
||||||
'plugins:ingest-attachment',
|
'plugins:ingest-attachment',
|
||||||
'plugins:ingest-user-agent',
|
'plugins:ingest-user-agent',
|
||||||
'plugins:lang-javascript',
|
|
||||||
'plugins:lang-python',
|
|
||||||
'plugins:mapper-murmur3',
|
'plugins:mapper-murmur3',
|
||||||
'plugins:mapper-size',
|
'plugins:mapper-size',
|
||||||
'plugins:repository-azure',
|
'plugins:repository-azure',
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue