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:
Nik Everett 2016-11-21 22:13:25 -05:00 committed by GitHub
parent 4225737db9
commit c79371fd5b
46 changed files with 6 additions and 5245 deletions

View file

@ -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" />

View file

@ -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

View file

@ -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)

View file

@ -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[]

View file

@ -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`.

View file

@ -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`.

View file

@ -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[]

View file

@ -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.

View file

@ -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[]

View file

@ -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[]

View file

@ -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.

View file

@ -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'
}
}

View file

@ -1 +0,0 @@
3a9ea863b86126b0ed8f2fe2230412747cd3c254

View file

@ -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.

View file

@ -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.

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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> {
}

View file

@ -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());
}
}

View file

@ -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";
};

View file

@ -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));
}
}

View file

@ -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));
}
}

View file

@ -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);
}
}

View file

@ -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();
}
}

View file

@ -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"}

View file

@ -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 }

View file

@ -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',
]

View file

@ -1 +0,0 @@
cdfb38bc6f8343bcf1d6accc2e1147e8e7b63b75

View file

@ -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.

View file

@ -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)

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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>>";
};

View file

@ -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();
}
}

View file

@ -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));
}
}

View file

@ -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));
}
}

View file

@ -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();
}
}

View file

@ -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"}

View file

@ -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 }

View file

@ -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" }

View file

@ -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
} }

View file

@ -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',