GroovyScript extends Script<StreamlineEvent, O, javax.script.ScriptEngine> { @Override public O evaluate(StreamlineEvent event) throws ScriptException { LOG.debug("Evaluating [{}] with [{}]", expression, event); groovy.lang.Script parsedScript = getParsedScript(); O evaluatedResult = null; if (event != null) { try { Binding binding = createBinding(event); parsedScript.setBinding(binding); LOG.debug("Set script binding to [{}]", event); evaluatedResult = (O) parsedScript.run(); LOG.debug("Expression [{}] evaluated to [{}]", expression, evaluatedResult); } catch (groovy.lang.MissingPropertyException e) { LOG.debug("Missing property: Expression [{}] params [{}]", expression, event); throw new ScriptException(e); } } return evaluatedResult; } GroovyScript(String expression, com.hortonworks.streamline.streams.runtime.script.engine.ScriptEngine<ScriptEngine> scriptEngine);  GroovyScript(String expression, com.hortonworks.streamline.streams.runtime.script.engine.ScriptEngine<ScriptEngine> scriptEngine, Map<String, Object> initialBindings); @Override O evaluate(StreamlineEvent event);  }
@Test public void testBindingsAreBoundOnlyWhenEvaluation() { GroovyScriptEngine groovyScriptEngine = new GroovyScriptEngine(); String groovyExpression = "temperature > 10 && humidity < 30"; GroovyScript<Boolean> groovyScript = new GroovyScript<Boolean>(groovyExpression, groovyScriptEngine); HashMap<String, Object> fieldsAndValue = new HashMap<>(); fieldsAndValue.put("temperature", 20); fieldsAndValue.put("humidity", 10); try { assertTrue(groovyScript.evaluate(StreamlineEventImpl.builder().fieldsAndValues(fieldsAndValue).dataSourceId("1").build())); } catch (ScriptException e) { e.printStackTrace(); Assert.fail("It shouldn't throw ScriptException"); } fieldsAndValue.clear(); fieldsAndValue.put("no_related_field", 3); try { groovyScript.evaluate(StreamlineEventImpl.builder().fieldsAndValues(fieldsAndValue).dataSourceId("1").build()); Assert.fail("It should not evaluate correctly"); } catch (ScriptException e) { } }
@Test public void testGroovyScriptEnsuresThreadSafe() throws InterruptedException { GroovyScriptEngine groovyScriptEngine = new GroovyScriptEngine(); String groovyExpression = "a % 2 == 0"; final GroovyScript<Boolean> groovyScript = new GroovyScript<>(groovyExpression, groovyScriptEngine); final AtomicInteger index = new AtomicInteger(0); List<Thread> threads = new ArrayList<>(); final AtomicReference<Throwable> anyException = new AtomicReference<>(); for (int i = 0 ; i < 500 ; i++) { Thread t = new Thread(new Runnable() { @Override public void run() { for (int j = 0 ; j < 10 ; j++) { try { Thread.sleep(new Random().nextInt(10)); } catch (InterruptedException e) { } int aVal = index.getAndIncrement(); HashMap<String, Object> fieldsAndValue = new HashMap<>(); fieldsAndValue.put("a", aVal); try { assertEquals(aVal % 2 == 0, groovyScript.evaluate(StreamlineEventImpl.builder().fieldsAndValues(fieldsAndValue).dataSourceId("1").build())); } catch (Throwable e) { e.printStackTrace(); anyException.set(e); } } } }); threads.add(t); t.start(); } for (Thread t : threads) { t.join(); } if (anyException.get() != null) { Assert.fail("Exception occurred within thread, first one is " + anyException.get().getMessage()); } }