How do you use the ExampleWhitelistExtension in Terms Aggregations


(Ben Youngblut) #1

I am trying to whitelist some additional Java functions in painless.
I am using the ExampleWhitelistExtension as example. I compiled it and installed it on to my elasticsearch server.

[byoungb@sawmill ~]$ curl "http://192.168.209.199:9200"
{
  "name" : "sawmill",
  "cluster_name" : "lumber",
  "cluster_uuid" : "YZu33B1cQnKcJd19xk0oDg",
  "version" : {
    "number" : "6.2.1",
    "build_hash" : "7299dc3",
    "build_date" : "2018-02-07T19:34:26.990113Z",
    "build_snapshot" : false,
    "lucene_version" : "7.2.1",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}
[byoungb@sawmill ~]$ sudo /usr/share/elasticsearch/bin/elasticsearch-plugin list
painless-whitelist
[byoungb@sawmill ~]$ 

But it doesn't seem to work, I cannot perform the queries that are in tests on this commit

So I am not sure what else I need to do, do I need to restart elasticsearch for the plugin to be loaded? I am pretty sure my version of elasticsearch should contain this new whilelisting ability. But there is not much in the documentation that I can see regarding any of this.

Any help would be appreciated, Thanks.


(Ryan Ernst) #2

do I need to restart elasticsearch for the plugin to be loaded?

Yes, elasticsearch must always be restarted after installing plugins.


(Ben Youngblut) #5

Okay so now I know what is going on.... and I may need to open up a issue instead.
So the reboot helped and I can useExampleWhitelistedClass in scripted_fields like the test in the commit but does not work in Terms Aggregations like the following.

{
  "query": {
    "match_all": {}
  },
  "aggregations": {
    "statuses": {
      "terms": {
        "script": {
          "source": "def e = new ExampleWhitelistedClass(64, 42); ExampleWhitelistedClass.staticMethod(); return e.publicMember + e.privateMemberAccessor + ExampleWhitelistedClass.CONSTANT;",
          "lang": "painless"
        }
      }
    }
  }
}

So is this something that you expected should work?


(Ryan Ernst) #6

The example whitelist plugin is only an example. Specifically, it adds the whitelisted classes and methods to the SearchScript context. Each place in Elasticsearch which use scripts have different variables they expect to be available. For example, in a search script, a _score is provided to the script (note that scripted fields use the SearchScript context due to legacy reasons, but this will eventually be corrected). In order to add the example whitelist to aggregations, you would need to add it to SearchScript.AGGS_CONTEXT (again, the fact this is also a "search script" is for legacy reasons and will eventually be fixed). See ExampleWhitelistExtension.java in the example plugin for where it maps the context to the whitelist.


(Ben Youngblut) #7

Awesome thank you so much this is exactly what I needed, but I don't think I would have been able to figure it out at all without your help.

package org.elasticsearch.example.painlesswhitelist;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.elasticsearch.painless.spi.PainlessExtension;
import org.elasticsearch.painless.spi.Whitelist;
import org.elasticsearch.painless.spi.WhitelistLoader;
import org.elasticsearch.script.ScriptContext;
import org.elasticsearch.script.SearchScript;

/** An extension of painless which adds a whitelist. */
public class ExampleWhitelistExtension implements PainlessExtension {

    private static final Whitelist WHITELIST =
        WhitelistLoader.loadFromResourceFiles(ExampleWhitelistExtension.class, "example_whitelist.txt");

    @Override
    public Map<ScriptContext<?>, List<Whitelist>> getContextWhitelists() {
        Map<ScriptContext<?>, List<Whitelist>> map = new HashMap<ScriptContext<?>, List<Whitelist>>();
        map.put(SearchScript.CONTEXT, Collections.singletonList(WHITELIST));
        map.put(SearchScript.AGGS_CONTEXT, Collections.singletonList(WHITELIST));
        return map;
    }
}

Was my changes and now the following works

POST lumber-2018.02.20/_search?size=1
{
  "query": {
    "match_all": {}
  },
  "script_fields": {
    "sNum1": {
      "script": {
        "source": "def e = new ExampleWhitelistedClass(6, 42); ExampleWhitelistedClass.staticMethod(); return e.publicMember + e.privateMemberAccessor + ExampleWhitelistedClass.CONSTANT + '2'.toInt()",
        "lang": "painless"
      }
    }
  },
  "aggregations": {
    "statuses": {
      "terms": {
        "script": {
          "source": "def e = new ExampleWhitelistedClass(6, 42); ExampleWhitelistedClass.staticMethod(); return e.publicMember + e.privateMemberAccessor + ExampleWhitelistedClass.CONSTANT + '2'.toInt();",
          "lang": "painless"
        }
      }
    }
  }
}

Thanks again.


(system) #8

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.