@Override public Parser<String, Object> makeParser() { // JavaScript configuration should be checked when it's actually used because someone might still want Druid // nodes to be able to deserialize JavaScript-based objects even though JavaScript is disabled. Preconditions.checkState(config.isEnabled(), "JavaScript is disabled"); parser = parser == null ? new JavaScriptParser(function) : parser; return parser; }
private JavaScriptDimFilter newJavaScriptDimFilter( final String dimension, final String function, final ExtractionFn extractionFn ) { return new JavaScriptDimFilter( dimension, function, extractionFn, JavaScriptConfig.getEnabledInstance() ); } }
@Test public void testGetRequiredColumns() { JavaScriptDimFilter javaScriptDimFilter = new JavaScriptDimFilter("dim", FN1, null, new JavaScriptConfig(false)); Assert.assertEquals(javaScriptDimFilter.getRequiredColumns(), Sets.newHashSet("dim")); } }
@Test public void testCompute() { JavaScriptPostAggregator javaScriptPostAggregator; Map<String, Object> metricValues = new HashMap<>(); metricValues.put("delta", -10.0); metricValues.put("total", 100.0); String absPercentFunction = "function(delta, total) { return 100 * Math.abs(delta) / total; }"; javaScriptPostAggregator = new JavaScriptPostAggregator( "absPercent", Lists.newArrayList("delta", "total"), absPercentFunction, JavaScriptConfig.getEnabledInstance() ); Assert.assertEquals(10.0, javaScriptPostAggregator.compute(metricValues)); }
@JsonCreator public JavaScriptTieredBrokerSelectorStrategy( @JsonProperty("function") String fn, @JacksonInject JavaScriptConfig config ) { Preconditions.checkNotNull(fn, "function must not be null"); Preconditions.checkState(config.isEnabled(), "JavaScript is disabled"); this.function = fn; }
@Test public void testComputeJavaScriptNotAllowed() { String absPercentFunction = "function(delta, total) { return 100 * Math.abs(delta) / total; }"; JavaScriptPostAggregator aggregator = new JavaScriptPostAggregator( "absPercent", Lists.newArrayList("delta", "total"), absPercentFunction, new JavaScriptConfig(false) ); expectedException.expect(IllegalStateException.class); expectedException.expectMessage("JavaScript is disabled"); aggregator.compute(new HashMap<>()); } }
@Test public void testEquals() { JavaScriptDimFilter javaScriptDimFilter = new JavaScriptDimFilter("dim", FN1, null, JavaScriptConfig.getEnabledInstance()); JavaScriptDimFilter javaScriptDimFilter2 = new JavaScriptDimFilter("di", FN2, null, JavaScriptConfig.getEnabledInstance()); JavaScriptDimFilter javaScriptDimFilter3 = new JavaScriptDimFilter("di", FN2, null, JavaScriptConfig.getEnabledInstance()); Assert.assertNotEquals(javaScriptDimFilter, javaScriptDimFilter2); Assert.assertEquals(javaScriptDimFilter2, javaScriptDimFilter3); RegexDimExtractionFn regexFn = new RegexDimExtractionFn(".*", false, null); JavaScriptDimFilter javaScriptDimFilter4 = new JavaScriptDimFilter("dim", FN1, regexFn, JavaScriptConfig.getEnabledInstance()); JavaScriptDimFilter javaScriptDimFilter5 = new JavaScriptDimFilter("dim", FN1, regexFn, JavaScriptConfig.getEnabledInstance()); Assert.assertNotEquals(javaScriptDimFilter, javaScriptDimFilter3); Assert.assertEquals(javaScriptDimFilter4, javaScriptDimFilter5); }
@JsonCreator public JavaScriptWorkerSelectStrategy( @JsonProperty("function") String fn, @JacksonInject JavaScriptConfig config ) { Preconditions.checkNotNull(fn, "function must not be null"); Preconditions.checkState(config.isEnabled(), "JavaScript is disabled"); this.function = fn; }
@Test public void testJavaScriptDisabledFactorize() { final JavaScriptAggregatorFactory factory = new JavaScriptAggregatorFactory( "foo", ImmutableList.of("foo"), scriptDoubleSum.get("fnAggregate"), scriptDoubleSum.get("fnReset"), scriptDoubleSum.get("fnCombine"), new JavaScriptConfig(false) ); expectedException.expect(IllegalStateException.class); expectedException.expectMessage("JavaScript is disabled"); factory.factorize(DUMMY_COLUMN_SELECTOR_FACTORY); Assert.assertTrue(false); }
@Test public void testGetCacheKey() { JavaScriptDimFilter javaScriptDimFilter = new JavaScriptDimFilter("dim", FN1, null, JavaScriptConfig.getEnabledInstance()); JavaScriptDimFilter javaScriptDimFilter2 = new JavaScriptDimFilter("di", FN2, null, JavaScriptConfig.getEnabledInstance()); Assert.assertFalse(Arrays.equals(javaScriptDimFilter.getCacheKey(), javaScriptDimFilter2.getCacheKey())); RegexDimExtractionFn regexFn = new RegexDimExtractionFn(".*", false, null); JavaScriptDimFilter javaScriptDimFilter3 = new JavaScriptDimFilter("dim", FN1, regexFn, JavaScriptConfig.getEnabledInstance()); Assert.assertFalse(Arrays.equals(javaScriptDimFilter.getCacheKey(), javaScriptDimFilter3.getCacheKey())); }
/** * This class can be used by multiple threads, so this function should be thread-safe to avoid extra * script compilation. */ @EnsuresNonNull("compiledScript") private JavaScriptAggregator.ScriptAggregator getCompiledScript() { // JavaScript configuration should be checked when it's actually used because someone might still want Druid // nodes to be able to deserialize JavaScript-based objects even though JavaScript is disabled. Preconditions.checkState(config.isEnabled(), "JavaScript is disabled"); JavaScriptAggregator.ScriptAggregator syncedCompiledScript = compiledScript; if (syncedCompiledScript == null) { synchronized (config) { syncedCompiledScript = compiledScript; if (syncedCompiledScript == null) { syncedCompiledScript = compileScript(fnAggregate, fnReset, fnCombine); compiledScript = syncedCompiledScript; } } } return syncedCompiledScript; }
@Test public void testJavaScriptDisabledFactorizeBuffered() { final JavaScriptAggregatorFactory factory = new JavaScriptAggregatorFactory( "foo", ImmutableList.of("foo"), scriptDoubleSum.get("fnAggregate"), scriptDoubleSum.get("fnReset"), scriptDoubleSum.get("fnCombine"), new JavaScriptConfig(false) ); expectedException.expect(IllegalStateException.class); expectedException.expectMessage("JavaScript is disabled"); factory.factorizeBuffered(DUMMY_COLUMN_SELECTOR_FACTORY); Assert.assertTrue(false); }
@Test public void testCastingAndNull() { String function = "function(x) {\n x = Number(x);\n if (isNaN(x)) return null;\n return Math.floor(x / 5) * 5;\n}"; ExtractionFn extractionFn = new JavaScriptExtractionFn(function, false, JavaScriptConfig.getEnabledInstance()); Iterator<String> it = Iterators.forArray("0", "5", "5", "10", null); for (String str : Lists.newArrayList("1", "5", "6", "10", "CA")) { String res = extractionFn.apply(str); String expected = it.next(); Assert.assertEquals(expected, res); } }
/** * {@link #compute} can be called by multiple threads, so this function should be thread-safe to avoid extra * script compilation. */ @EnsuresNonNull("fn") private Function getCompiledScript() { // JavaScript configuration should be checked when it's actually used because someone might still want Druid // nodes to be able to deserialize JavaScript-based objects even though JavaScript is disabled. Preconditions.checkState(config.isEnabled(), "JavaScript is disabled"); Function syncedFn = fn; if (syncedFn == null) { synchronized (config) { syncedFn = fn; if (syncedFn == null) { syncedFn = compile(function); fn = syncedFn; } } } return syncedFn; }
@Test public void testToFilterNotAllowed() { JavaScriptDimFilter javaScriptDimFilter = new JavaScriptDimFilter("dim", FN1, null, new JavaScriptConfig(false)); expectedException.expect(IllegalStateException.class); expectedException.expectMessage("JavaScript is disabled"); javaScriptDimFilter.toFilter(); Assert.assertTrue(false); }
@Test public void testToFilter() { JavaScriptDimFilter javaScriptDimFilter = new JavaScriptDimFilter( "dim", "function(x) { return true; }", null, JavaScriptConfig.getEnabledInstance() ); final Filter filter = javaScriptDimFilter.toFilter(); Assert.assertThat(filter, CoreMatchers.instanceOf(JavaScriptFilter.class)); }
/** * {@link #apply(Object)} can be called by multiple threads, so this function should be thread-safe to avoid extra * script compilation. */ @EnsuresNonNull("fn") private Function<Object, String> getCompiledScript() { // JavaScript configuration should be checked when it's actually used because someone might still want Druid // nodes to be able to deserialize JavaScript-based objects even though JavaScript is disabled. Preconditions.checkState(config.isEnabled(), "JavaScript is disabled"); Function<Object, String> syncedFn = fn; if (syncedFn == null) { synchronized (config) { syncedFn = fn; if (syncedFn == null) { syncedFn = compile(function); fn = syncedFn; } } } return syncedFn; }
@Test public void testJavascriptNotAllowed() { String function = "function(str) { return str.substring(0,3); }"; ExtractionFn extractionFn = new JavaScriptExtractionFn(function, false, new JavaScriptConfig(false)); expectedException.expect(IllegalStateException.class); expectedException.expectMessage("JavaScript is disabled"); extractionFn.apply("hey"); Assert.assertTrue(false); }
@Test public void testJavascriptSubstring() { String function = "function(str) { return str.substring(0,3); }"; ExtractionFn extractionFn = new JavaScriptExtractionFn(function, false, JavaScriptConfig.getEnabledInstance()); for (String str : testStrings) { String res = extractionFn.apply(str); Assert.assertEquals(str.substring(0, 3), res); } }
/** * This class can be used by multiple threads, so this function should be thread-safe to avoid extra * script compilation. */ @EnsuresNonNull("predicateFactory") private JavaScriptPredicateFactory getPredicateFactory() { // JavaScript configuration should be checked when it's actually used because someone might still want Druid // nodes to be able to deserialize JavaScript-based objects even though JavaScript is disabled. Preconditions.checkState(config.isEnabled(), "JavaScript is disabled"); JavaScriptPredicateFactory syncedFnPredicateFactory = predicateFactory; if (syncedFnPredicateFactory == null) { synchronized (config) { syncedFnPredicateFactory = predicateFactory; if (syncedFnPredicateFactory == null) { syncedFnPredicateFactory = new JavaScriptPredicateFactory(function, extractionFn); predicateFactory = syncedFnPredicateFactory; } } } return syncedFnPredicateFactory; }