Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
<commons.validator.version>1.6</commons.validator.version>
<commons-io.version>2.16.1</commons-io.version>
<commons-csv.version>1.4</commons-csv.version>
<commons-jexl.version>3.0</commons-jexl.version>
<commons-jexl.version>3.1</commons-jexl.version>
<commons-lang.version>2.6</commons-lang.version>
<commons-lang3.version>3.5</commons-lang3.version>
<commons-math3.version>3.6.1</commons-math3.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,38 @@
import com.google.gson.JsonObject;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
* This class {@link DirectiveConfig} defines the configuration for the Wrangler.
* This class {@link DirectiveConfig} defines the configuration for the
* Wrangler.
* It specifies the directive exclusions -- meaning directives that should
* not be accessible to the users and as well as directive aliases.
*
* {
* "exclusions" : [
* "parse-as-csv",
* "parse-as-excel",
* "set",
* "invoke-http"
* ],
* "aliases" : {
* "json-parser" : "parse-as-json",
* "js-parser" : "parse-as-json"
* }
* }
* "exclusions" : [
* "parse-as-csv",
* "parse-as-excel",
* "set",
* "invoke-http"
* ],
* "aliases" : {
* "json-parser" : "parse-as-json",
* "js-parser" : "parse-as-json"
* }
* "jexlInclusions" : [
* {
* "className": "com.xyz.JsonParser",
* "methods": ["parse"],
* "properties": ["offset"]
* }
* ]
* }
*/
@Deprecated
public final class DirectiveConfig {
Expand All @@ -54,6 +63,19 @@ public final class DirectiveConfig {
// RecipeParser to be aliased.
private final Map<String, String> aliases = new HashMap<>();

/**
* The JEXL inclusions rules.
*/
private final List<JexlInclusion> jexlInclusions = new ArrayList<>();

/**
* Gets the list of JEXL inclusions.
*
* @return the list of JEXL inclusions
*/
public List<JexlInclusion> getJexlInclusions() {
return Collections.unmodifiableList(jexlInclusions);
}

/**
* Checks if a directive is aliased.
Expand Down Expand Up @@ -110,6 +132,7 @@ public JsonElement toJson() {
JsonObject object = new JsonObject();
object.add("exclusions", gson.toJsonTree(exclusions));
object.add("aliases", gson.toJsonTree(aliases));
object.add("jexlInclusions", gson.toJsonTree(jexlInclusions));
return object;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,29 @@

package io.cdap.wrangler.api;

import javax.annotation.Nullable;

/**
* {@link DirectiveContext} provides the context object to the processing of
* directives.
*/
public interface DirectiveContext extends DirectiveEnforcer, DirectiveAlias {
/**
* Gets the DirectiveConfig.
*
* @return the DirectiveConfig
*/
@Nullable
default DirectiveConfig getConfig() {
return null;
}

/**
* Checks if secure JEXL feature is enabled.
*
* @return true if enabled
*/
default boolean isSecureJexlFeatureEnabled() {
return false;
}
}
115 changes: 115 additions & 0 deletions wrangler-api/src/main/java/io/cdap/wrangler/api/JexlInclusion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
* Copyright © 2024 Cask Data, Inc.
*
* 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.
*/

package io.cdap.wrangler.api;

import io.cdap.wrangler.api.annotations.PublicEvolving;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nullable;

/**
* Defines custom class, method, and property inclusion rules.
*/
@PublicEvolving
public final class JexlInclusion implements Serializable {
private static final long serialVersionUID = 1L;

/**
* The name of the class to include.
*/
private final String className;

/**
* The list of allowed methods for the class.
*/
private final List<String> methods;

/**
* The list of allowed properties for the class.
*/
private final List<String> properties;

/**
* Default constructor required for Gson serialization/deserialization.
*/
private JexlInclusion() {
this.className = null;
this.methods = Collections.emptyList();
this.properties = Collections.emptyList();
}

/**
* Constructs a JexlInclusion.
*
* @param className the name of the class
* @param methods the list of allowed methods
* @param properties the list of allowed properties
*/
public JexlInclusion(final String className,
@Nullable final List<String> methods,
@Nullable final List<String> properties) {
this.className = className;
this.methods = (methods == null) ? Collections.emptyList() : methods;
this.properties = (properties == null) ? Collections.emptyList() : properties;
}

/**
* Gets the class name.
*
* @return the class name
*/
public String getClassName() {
return className;
}

/**
* Gets the list of allowed methods.
*
* @return the allowed methods
*/
public List<String> getMethods() {
return methods;
}

/**
* Gets the list of allowed properties.
*
* @return the allowed properties
*/
public List<String> getProperties() {
return properties;
}

/**
* Checks if all methods are allowed.
*
* @return true if all methods are allowed
*/
public boolean isAllMethods() {
return methods.isEmpty() || methods.contains("*");
}

/**
* Checks if all properties are allowed.
*
* @return true if all properties are allowed
*/
public boolean isAllProperties() {
return properties.isEmpty() || properties.contains("*");
}
}
5 changes: 5 additions & 0 deletions wrangler-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@
<groupId>io.cdap.cdap</groupId>
<artifactId>cdap-api</artifactId>
<version>${cdap.version}</version>
</dependency>
<dependency>
<groupId>io.cdap.cdap</groupId>
<artifactId>cdap-features</artifactId>
<version>${cdap.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import io.cdap.wrangler.expression.ELContext;
import io.cdap.wrangler.expression.ELException;
import io.cdap.wrangler.expression.ELResult;
import io.cdap.wrangler.utils.JexlHelper;

import java.util.List;

Expand All @@ -54,7 +55,7 @@ public class IncrementTransientVariable implements Directive {
public static final String NAME = "increment-variable";
private String variable;
private long incrementBy;
private EL el;
private EL el;

@Override
public UsageDefinition define() {
Expand All @@ -69,9 +70,10 @@ public UsageDefinition define() {
public void initialize(Arguments args) throws DirectiveParseException {
this.variable = ((Identifier) args.value("variable")).value();
this.incrementBy = ((Numeric) args.value("value")).value().longValue();
String expression = ((Expression) args.value("condition")).value();
Expression expression = args.value("condition");
try {
el = EL.compile(expression);
this.el = EL.compile(expression.value(), JexlHelper.getJexlInclusions(args),
JexlHelper.isSecureJexlFeatureEnabled(args));
} catch (ELException e) {
throw new DirectiveParseException(NAME, e.getMessage(), e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import io.cdap.wrangler.expression.ELContext;
import io.cdap.wrangler.expression.ELException;
import io.cdap.wrangler.expression.ELResult;
import io.cdap.wrangler.utils.JexlHelper;

import java.util.List;

Expand All @@ -56,7 +57,7 @@ public class SetTransientVariable implements Directive {
public static final String NAME = "set-variable";
private EL el;
private String variable;

@Override
public UsageDefinition define() {
UsageDefinition.Builder builder = UsageDefinition.builder(NAME);
Expand All @@ -68,9 +69,10 @@ public UsageDefinition define() {
@Override
public void initialize(Arguments args) throws DirectiveParseException {
this.variable = ((Identifier) args.value("variable")).value();
String expression = ((Expression) args.value("condition")).value();
Expression expression = args.value("condition");
try {
el = EL.compile(expression);
this.el = EL.compile(expression.value(), JexlHelper.getJexlInclusions(args),
JexlHelper.isSecureJexlFeatureEnabled(args));
} catch (ELException e) {
throw new DirectiveParseException(NAME, e.getMessage(), e);
}
Expand Down
6 changes: 4 additions & 2 deletions wrangler-core/src/main/java/io/cdap/directives/row/Fail.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import io.cdap.wrangler.expression.ELContext;
import io.cdap.wrangler.expression.ELException;
import io.cdap.wrangler.expression.ELResult;
import io.cdap.wrangler.utils.JexlHelper;

import java.util.List;

Expand All @@ -53,7 +54,7 @@ public class Fail implements Directive, Lineage {
public static final String NAME = "fail";
private String condition;
private EL el;

@Override
public UsageDefinition define() {
UsageDefinition.Builder builder = UsageDefinition.builder(NAME);
Expand All @@ -70,7 +71,8 @@ public void initialize(Arguments args) throws DirectiveParseException {
}
condition = expression.value();
try {
el = EL.compile(condition);
this.el = EL.compile(expression.value(), JexlHelper.getJexlInclusions(args),
JexlHelper.isSecureJexlFeatureEnabled(args));
} catch (ELException e) {
throw new DirectiveParseException(NAME, e.getMessage(), e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import io.cdap.wrangler.expression.EL;
import io.cdap.wrangler.expression.ELContext;
import io.cdap.wrangler.expression.ELException;
import io.cdap.wrangler.utils.JexlHelper;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -61,7 +62,7 @@ public class RecordConditionFilter implements Directive, Lineage {
public static final String NAME = "filter-row";
private EL el;
private boolean isTrue;

@Override
public UsageDefinition define() {
UsageDefinition.Builder builder = UsageDefinition.builder(NAME);
Expand All @@ -76,9 +77,10 @@ public void initialize(Arguments args) throws DirectiveParseException {
if (args.contains("type")) {
isTrue = ((Bool) args.value("type")).value();
}
String condition = ((Expression) args.value("condition")).value();
Expression expression = args.value("condition");
try {
el = EL.compile(condition);
this.el = EL.compile(expression.value(), JexlHelper.getJexlInclusions(args),
JexlHelper.isSecureJexlFeatureEnabled(args));
} catch (ELException e) {
throw new DirectiveParseException(NAME, e.getMessage(), e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import io.cdap.wrangler.expression.ELContext;
import io.cdap.wrangler.expression.ELException;
import io.cdap.wrangler.expression.ELResult;
import io.cdap.wrangler.utils.JexlHelper;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -66,7 +67,7 @@ public class SendToError implements Directive, Lineage {
private String condition;
private String metric = null;
private String message = null;

@Override
public UsageDefinition define() {
UsageDefinition.Builder builder = UsageDefinition.builder(NAME);
Expand All @@ -78,9 +79,10 @@ public UsageDefinition define() {

@Override
public void initialize(Arguments args) throws DirectiveParseException {
condition = ((Expression) args.value("condition")).value();
Expression expression = args.value("condition");
condition = expression.value();
try {
el = EL.compile(condition);
this.el = EL.compile(condition, JexlHelper.getJexlInclusions(args), JexlHelper.isSecureJexlFeatureEnabled(args));
} catch (ELException e) {
throw new DirectiveParseException(
NAME, String.format(" Invalid condition '%s'.", condition)
Expand Down
Loading
Loading