diff --git a/common/build.gradle b/common/build.gradle
index 79077317a1..4d5cb95740 100644
--- a/common/build.gradle
+++ b/common/build.gradle
@@ -34,6 +34,7 @@ dependencies {
exclude group: 'com.google.j2objc', module: 'j2objc-annotations'
exclude group: 'com.google.guava', module: 'listenablefuture'
}
+ compileOnly 'com.jayway.jsonpath:json-path:2.9.0'
}
lombok {
diff --git a/common/src/main/java/org/opensearch/ml/common/utils/StringUtils.java b/common/src/main/java/org/opensearch/ml/common/utils/StringUtils.java
index b9c69cd194..5bd3e3ecae 100644
--- a/common/src/main/java/org/opensearch/ml/common/utils/StringUtils.java
+++ b/common/src/main/java/org/opensearch/ml/common/utils/StringUtils.java
@@ -36,6 +36,8 @@
import static org.opensearch.ml.common.conversation.ConversationalIndexConstants.INTERACTIONS_ADDITIONAL_INFO_FIELD;
import static org.opensearch.ml.common.conversation.ConversationalIndexConstants.INTERACTIONS_RESPONSE_FIELD;
+import com.jayway.jsonpath.JsonPath;
+
@Log4j2
public class StringUtils {
@@ -56,6 +58,7 @@ public class StringUtils {
static {
gson = new Gson();
}
+ public static final String TO_STRING_FUNCTION_NAME = ".toString()";
public static boolean isValidJsonString(String Json) {
try {
@@ -239,4 +242,89 @@ public static String getErrorMessage(String errorMessage, String modelId, Boolea
return errorMessage + " Model ID: " + modelId;
}
}
+
+ public static String obtainFieldNameFromJsonPath(String jsonPath) {
+ String[] parts = jsonPath.split("\\.");
+
+ // Get the last part which is the field name
+ return parts[parts.length - 1];
+ }
+
+ public static String getJsonPath(String jsonPathWithSource) {
+ // Find the index of the first occurrence of "$."
+ int startIndex = jsonPathWithSource.indexOf("$.");
+
+ // Extract the substring from the startIndex to the end of the input string
+ return (startIndex != -1) ? jsonPathWithSource.substring(startIndex) : jsonPathWithSource;
+ }
+
+ /**
+ * Checks if the given input string matches the JSONPath format.
+ *
+ *
The JSONPath format is a way to navigate and extract data from JSON documents.
+ * It uses a syntax similar to XPath for XML documents. This method attempts to compile
+ * the input string as a JSONPath expression using the {@link com.jayway.jsonpath.JsonPath}
+ * library. If the compilation succeeds, it means the input string is a valid JSONPath
+ * expression.
+ *
+ * @param input the input string to be checked for JSONPath format validity
+ * @return true if the input string is a valid JSONPath expression, false otherwise
+ */
+ public static boolean isValidJSONPath(String input) {
+ if (input == null || input.isBlank()) {
+ return false;
+ }
+ try {
+ JsonPath.compile(input); // This will throw an exception if the path is invalid
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+
+ /**
+ * Collects the prefixes of the toString() method calls present in the values of the given map.
+ *
+ * @param map A map containing key-value pairs where the values may contain toString() method calls.
+ * @return A list of prefixes for the toString() method calls found in the map values.
+ */
+ public static List collectToStringPrefixes(Map map) {
+ List prefixes = new ArrayList<>();
+ for (String key : map.keySet()) {
+ String value = map.get(key);
+ if (value != null) {
+ Pattern pattern = Pattern.compile("\\$\\{parameters\\.(.+?)\\.toString\\(\\)\\}");
+ Matcher matcher = pattern.matcher(value);
+ while (matcher.find()) {
+ String prefix = matcher.group(1);
+ prefixes.add(prefix);
+ }
+ }
+ }
+ return prefixes;
+ }
+
+ /**
+ * Parses the given parameters map and processes the values containing toString() method calls.
+ *
+ * @param parameters A map containing key-value pairs where the values may contain toString() method calls.
+ * @return A new map with the processed values for the toString() method calls.
+ */
+ public static Map parseParameters(Map parameters) {
+ if (parameters != null) {
+ List toStringParametersPrefixes = collectToStringPrefixes(parameters);
+
+ if (!toStringParametersPrefixes.isEmpty()) {
+ for (String prefix : toStringParametersPrefixes) {
+ String value = parameters.get(prefix);
+ if (value != null) {
+ parameters.put(prefix + TO_STRING_FUNCTION_NAME, processTextDoc(value));
+ }
+ }
+ }
+ }
+ return parameters;
+ }
+
}
diff --git a/plugin/src/main/java/org/opensearch/ml/processor/MLInferenceIngestProcessor.java b/plugin/src/main/java/org/opensearch/ml/processor/MLInferenceIngestProcessor.java
index 7a475a2b87..d7f2ae44b7 100644
--- a/plugin/src/main/java/org/opensearch/ml/processor/MLInferenceIngestProcessor.java
+++ b/plugin/src/main/java/org/opensearch/ml/processor/MLInferenceIngestProcessor.java
@@ -6,7 +6,6 @@
import static org.opensearch.ml.processor.InferenceProcessorAttributes.*;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@@ -31,9 +30,7 @@
import org.opensearch.script.ScriptService;
import org.opensearch.script.TemplateScript;
-import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
-import com.jayway.jsonpath.Option;
/**
* MLInferenceIngestProcessor requires a modelId string to call model inferences
@@ -57,11 +54,6 @@ public class MLInferenceIngestProcessor extends AbstractProcessor implements Mod
// it can be overwritten using max_prediction_tasks when creating processor
public static final int DEFAULT_MAX_PREDICTION_TASKS = 10;
- private Configuration suppressExceptionConfiguration = Configuration
- .builder()
- .options(Option.SUPPRESS_EXCEPTIONS, Option.DEFAULT_PATH_LEAF_TO_NULL, Option.ALWAYS_RETURN_LIST)
- .build();
-
protected MLInferenceIngestProcessor(
String modelId,
List