I am trying to use the reindex api to create a copy of a set of documents. One of the fields (uuid
) of the document is a UUID. I need the copied documents to have new UUIDs for the uuid
field.
According to [1] and [2] the method java.util.UUID.randomUUID()
is not whitelisted for use in painless scripts.
Questions:
1) How can I generate a UUID in painless?
2) Why is UUID.randomUUID()
considered an unsafe operation? Or is it just an oversight that it is not whitelisted?
3) How can I whitelist UUID.randomUUID()
in the "reindex"
context? I tried to build my own elasticsearch painless extension/plugin to do this based on the example in [3]. The problem is it only works for the "SearchScript"
context. There does not seem to be an equivalent "ReindexContext"
.
Here is a simplified version of what I am trying:
curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'
{
"source": {
"index": "product1"
},
"dest": {
"index": "product2"
},
"script": {
"source": "ctx._source.uuid = java.util.UUID.randomUUID().toString()",
"lang": "painless"
}
}
'
Which produces the following error:
{
"error" : {
"root_cause" : [
{
"type" : "script_exception",
"reason" : "compile error",
"script_stack" : [
"... rce.uuid = java.util.UUID.randomUUID().toString()",
" ^---- HERE"
],
"script" : "ctx._source.uuid = java.util.UUID.randomUUID().toString()",
"lang" : "painless"
}
],
"type" : "script_exception",
"reason" : "compile error",
"script_stack" : [
"... rce.uuid = java.util.UUID.randomUUID().toString()",
" ^---- HERE"
],
"script" : "ctx._source.uuid = java.util.UUID.randomUUID().toString()",
"lang" : "painless",
"caused_by" : {
"type" : "illegal_argument_exception",
"reason" : "method [java.util.UUID, randomUUID/0] not found"
}
},
"status" : 500
}
I know my approach is valid and that the above is a painless whitelisting issue because when I try a different method (fromString()
) I get no errors:
curl -X POST "localhost:9200/_reindex?pretty" -H 'Content-Type: application/json' -d'
{
"source": {
"index": "product1"
},
"dest": {
"index": "product2"
},
"script": {
"source": "ctx._source.uuid = java.util.UUID.fromString(\u0027ad139caa-5b54-4179-b812-5015daecad1e\u0027).toString()",
"lang": "painless"
}
}
'
References:
[1] - https://discuss.elastic.co/t/generate-a-uuid-using-randomuuid-in-painless/144354/3
[2] - https://www.elastic.co/guide/en/elasticsearch/painless/6.6/painless-api-reference.html
[3] - https://github.com/elastic/elasticsearch/tree/v6.6.0/plugins/examples/painless-whitelist
Other Notes:
Elasticsearch 6.6
I've already asked this question on the elasticsearch forum here (no responses): https://discuss.elastic.co/t/need-to-generate-uuid-in-painless-script/165318
I've also asked about whitelisting the UUID.randomUUID()
method here (no responses):
https://discuss.elastic.co/t/question-about-painless-whitelist/165523
My feature request to resolve this issue has been accepted and implemented here: https://github.com/elastic/elasticsearch/issues/39080