E9.2 Forming Orchestration Input for x-www-form-urlencoded

AndrewCoutts

AndrewCoutts

Member
Hello,

I'm trying to create an orchestration that will allow me to receive the following input but am unsure how to handle it.
I think this is something that I will need to use Groovy/JRuby to parse.

When I analyse the incoming post it looks like the content-type is x-www-form-urlencoded
This is the body of what is getting posted

[('ITEM-DESCRIPTION[1]', 'Valve'), ('ITEM-NUMBER[1]', '564646'),('ITEM-DESCRIPTION[2]', 'O-RING'), ('ITEM-NUMBER[2]', '123123')]

Does anyone know how would get this array of information into my orchestration so I can loop through the elements of this array?
 
ewwwwwwwwwwwwww that is yucky noncompliant crap.

I do think you need to do some very specific scripting to parse it and make it intelligible for downstream operations. I was going to suggest replacing parenths with curlys and off to the races, but then I see that it tosses ordinal array values in with the field description. WOW. What gymnastics the developer must have had to go thru to make this work in the first place.

Now i'm invested. I'm going to feed this to chatGPT and see what it says.

Here's what it says. This is usually step 1 of me working a script with ChatGPT. You need to "shoehorn" the script into Orchestrator's specific implementation.

To convert the given input string into a well-structured JSON string using Groovy, we need to parse the input and then format it accordingly. The input string suggests a list of tuples where each tuple consists of a field name and its value. Additionally, the field names indicate that some elements are part of an array, as denoted by the ordinal numbers in square brackets.

The Groovy script to achieve this would look something like this:

```groovy
def input = "[('ITEM-DESCRIPTION[1]', 'Valve'), ('ITEM-NUMBER[1]', '564646'),('ITEM-DESCRIPTION[2]', 'O-RING'), ('ITEM-NUMBER[2]', '123123')]"

// Remove the brackets and split the string into tuples
def tuples = input.replaceAll("\\[|\\]", "").split("\\), \\(")

// Process each tuple and organize them into a map
def items = [:].withDefault { [:] }
tuples.each { tuple ->
// Remove the parentheses and split the tuple into key-value pairs
def (key, value) = tuple.replaceAll("[\\(\\)']", "").split(", ")

// Extract the index and actual key from the key string
def (actualKey, index) = key =~ /([A-Z-]+)\[(\d+)\]/.find().with { it[1], it[2].toInteger() }

// Add the value to the corresponding array in the map
items[actualKey] = items[actualKey].withDefault { [] }
items[actualKey][index - 1] = value
}

// Convert the map to JSON
def jsonOutput = new groovy.json.JsonBuilder(items).toPrettyString()

return jsonOutput
```

This script does the following:

1. Removes the outer brackets and splits the string into individual tuples.
2. Iterates over each tuple, parsing out the key and value.
3. Extracts the index and actual key from each key string.
4. Organizes the values into a map where each key is associated with an array of values.
5. Converts the map into a JSON string using Groovy's `JsonBuilder`.

The resulting JSON string will be a structured representation of your input data.
 
Here's the prompt that generated that response. Used ChatGPT 4.0:

Hello I have a strange input string, and I want you to translate that to a usable, well-structured JSON string using Groovy. Here's the input string. Note that there is an "array" ordinal next to the field names for repeating elements. "[('ITEM-DESCRIPTION[1]', 'Valve'), ('ITEM-NUMBER[1]', '564646'),('ITEM-DESCRIPTION[2]', 'O-RING'), ('ITEM-NUMBER[2]', '123123')]"
 
Wow, thank you so much for that help!!
Yea it's an interesting data format for sure, haha.

Now I just struggling to get it into an input for the Groovy script.

Is this how you reference using the whole Orchestration Input as the Input the Groovy Script?

1702677385304.png
 
Last edited:
I wrestled with chatGPT a bit, but this got me good results in the groovy. You can see how I shoehorned the chatGPT code into the Orch groovy template:

Code:
import com.oracle.e1.common.OrchestrationAttributes;
import java.text.SimpleDateFormat;
import groovy.json.JsonBuilder;
HashMap<String, Object> main(OrchestrationAttributes orchAttr, HashMap inputMap)
{
    HashMap<String, Object> returnMap = new HashMap<String, Object>();
    // Add logic here
    String input = "[('ITEM-DESCRIPTION[1]', 'Valve'), ('ITEM-NUMBER[1]', '564646'),('ITEM-DESCRIPTION[2]', 'O-RING'), ('ITEM-NUMBER[2]', '123123')]"

    // Removing brackets and splitting by '),'
    String[] pairs = input.replaceAll("\\[|\\]", "").split("\\),")

    List<Map<String, String>> items = []
    Map<String, String> currentItem = [:]

    pairs.each { pair ->
        // Splitting each pair into key and value
        String[] keyValue = pair.trim().replaceAll("[\\(\\)']", "").split(", ")
        if (keyValue.length == 2) {
            // Extracting key and value
            String keyWithIndex = keyValue[0].split("\\[")[0]
            String value = keyValue[1]

            // Removing the index from the key
            String key = keyWithIndex.replaceAll("\\d", "")

            // Adding key-value to the current item
            currentItem[key] = value

            // When ITEM-NUMBER is found, add current item to items list and reset current item
            if (keyWithIndex.contains("ITEM-NUMBER")) {
                items.add(currentItem)
                currentItem = [:]
            }
        }
    }

    // Creating JSON
    JsonBuilder jsonBuilder = new JsonBuilder(items)
    String jsonOutput = jsonBuilder.toPrettyString()

    returnMap.put("Output String", jsonOutput);

    return returnMap;
}
 
And if you make it look like this in the outputs area you should get a nice wellformed array out of the script for downstream. Might want to name it something other than "Output String" :)

1702678383719.png
 
Sorry it didn't show me your reply until I had gone ham down my chatGPT rabbithole. I'll show you the input part Monday if you still need help.
 
That same code modified to take the input string from a parameter to the component. You need to define the input as inputString to make this all work.

Code:
import com.oracle.e1.common.OrchestrationAttributes;
import java.text.SimpleDateFormat;
import groovy.json.JsonBuilder;
HashMap<String, Object> main(OrchestrationAttributes orchAttr, HashMap inputMap)
{
    HashMap<String, Object> returnMap = new HashMap<String, Object>();
    // Add logic here
    String input = (String)inputMap.get("inputString");
    
    // Removing brackets and splitting by '),'
    String[] pairs = input.replaceAll("\\[|\\]", "").split("\\),")

    List<Map<String, String>> items = []
    Map<String, String> currentItem = [:]

    pairs.each { pair ->
        // Splitting each pair into key and value
        String[] keyValue = pair.trim().replaceAll("[\\(\\)']", "").split(", ")
        if (keyValue.length == 2) {
            // Extracting key and value
            String keyWithIndex = keyValue[0].split("\\[")[0]
            String value = keyValue[1]

            // Removing the index from the key
            String key = keyWithIndex.replaceAll("\\d", "")

            // Adding key-value to the current item
            currentItem[key] = value

            // When ITEM-NUMBER is found, add current item to items list and reset current item
            if (keyWithIndex.contains("ITEM-NUMBER")) {
                items.add(currentItem)
                currentItem = [:]
            }
        }
    }

    // Creating JSON
    JsonBuilder jsonBuilder = new JsonBuilder(items)
    String jsonOutput = jsonBuilder.toPrettyString()

    returnMap.put("Output String", jsonOutput);

    return returnMap;
}
 
Thanks so much, Dave! I think with this I've got everything in place to parse the incoming request. I've simulated it with raw input and it seems to be working. Now I just need to work with the vendor to somehow get them have them get a token or auth in their post to Orchestrator.
 
Back
Top