Wiremock Request Templating for JSON Payload with multiple allowed keys, but same response - wiremock

Trying to mock an API endpoint that allows a request with 2 possible payloads, but the same response:
Request Option 1
{
"key1": "value1"
}
Request Option 2
{
"key2": "value2"
}
Based on the Request Templating documentation, I see that there's an option to define some regex for matchesJsonPath.
However, I'm unable to figure out how to provide a configuration that will allow key1 or key2.
This is what I'd tried, but it doesn't seem to work:
{
// ... other configs
"request": {
"bodyPatterns": [
{
"matchesJsonPath": "$.(key1|key2)"
}
]
}
}
Is it possible to provide 1 definition that supports both payloads, or do I have to create 2 stubs?
Note: I am using a standalone Wiremock Docker image, so options for more complex handling using Java are limited.

Your JsonPath matcher is formatted incorrectly. You need to apply a filter/script (denoted by ?()). More information about how JsonPath matchers work can be found here.
Here is what the properly formatted JsonPath matcher could look like:
{
"matchesJsonPath": "$[?(#.key1 || #.key2)]"
}
If you need the key1 and key2 to have specific values, that would look like:
{
"matchesJsonPath": "$[?(#.key1 == 'value1' || #.key2 == 'value2')]"
}

Related

Document AI Contract Processor - batchProcessDocuments ignores fieldMask

My aim is to reduce the json file size, which contains the base64 image sections of the documents by default.
I am using the Document AI - Contract Processor in US region, nodejs SDK.
It is my understanding that setting fieldMask attribute in batchProcessDocuments request filters out the properties that will be in the resulting json.
I want to keep only the entities property.
Here are my call parameters:
const documentai = require('#google-cloud/documentai').v1;
const client = new documentai.DocumentProcessorServiceClient(options);
let params = {
"name": "projects/XXX/locations/us/processors/3e85a4841d13ce5",
"region": "us",
"inputDocuments": {
"gcsDocuments": {
"documents": [{
"mimeType": "application/pdf",
"gcsUri": "gs://bubble-bucket-XXX/files/CymbalContract.pdf"
}]
}
},
"documentOutputConfig": {
"gcsOutputConfig": {
"gcsUri": "gs://bubble-bucket-XXXX/ocr/"
},
"fieldMask": {
"paths": [
"entities"
]
}
}
};
client.batchProcessDocuments(params, function(error, operation) {
if (error) {
return reject(error);
}
return resolve({
"operationName": operation.name
});
});
However, the resulting json is still containing the full set of data.
Am I missing something here?
The auto-generated documentation for the Node.JS Client Library is a little hard to follow, but it looks like the fieldMask should be a member of the gcsOutputConfig instead of the documentOutputConfig. (I'm surprised the API didn't throw an error)
https://cloud.google.com/nodejs/docs/reference/documentai/latest/documentai/protos.google.cloud.documentai.v1.documentoutputconfig.gcsoutputconfig
The REST Docs are a little more clear
https://cloud.google.com/document-ai/docs/reference/rest/v1/DocumentOutputConfig#gcsoutputconfig
Note: For a REST API call and for other client libraries, the fieldMask is structured as a string (e.g. text,entities,pages.pageNumber)
I haven't tried this with the Node Client libraries before, but I'd recommend trying this as well if moving the parameter doesn't work on its own.
https://cloud.google.com/document-ai/docs/send-request#async-processor

Akka Flow how to apply filter on a JSON data coming from Kafka Topic

JSON data coming from Kafka Topic like
{
"Action": "die",
"Actor": {
"Attributes": {
"exit": "0",
"node.name": "node-1",
"name": "6a5426de4d6e"
},
"ID": "09a2576ec87e416aaa943f566e54a375d9c325885038195125c4674b104276b6"
}
}
My Akka Flow code snippet is like below
def getEvents: Flow[KafkaMessage, ConsumerMessage.CommittableOffset, NotUsed] =
Flow[KafkaMessage]
.via(getfromSource) //akka source
.wireTap(_.value.map(pprint.log(_))) // I am able to console all the events from kafka topic.
I want to apply filter (get all exit=0) condition on top of the events getting from the topic by using .filter . But unable to make it work . Any guidance or reference will be helpful
From your comments, getfromSource returns Either[Throwable,TopicEvent] so you have to do something like this:
Flow[KafkaMessage]
.via(getfromSource)
.filter {
case Right(event) => event.Actor.Attributes.exitCode.toInt > 0
case Left(_) => false // or true? Up to you..
}
Note that the pattern matching can be simplified if you want to.

Talend read JSON data from tRESTRequest

I am trying to learn Talend.
Scenario:
I have to create a REST endpoint (i am using tRESTRequest) which takes a POST request at http://localhost:8086/emp/create and accepts below json and prints each json field and sends a sample json response containing only name field.
How can I do so ?
How to read the json data into a java component like tJava?
Structure:
{
"emp" :
[
{
"id":"123",
"name": "testemp1"
},
{
"id":"456",
"name": "testemp2"
}
]
}
Expected Response:
{
"emp" :
[
{
"name": "testemp1"
},
{
"name": "testemp2"
}
]
}
I am using tRESTRequest -> tExtractJSONFields -> tRESTResponse.
For looping on the right elements and parsing the contents, please see my answer JSON Deserialization on Talend
I did not understand the second question. When deserializing JSON, the data will already be available in the usual row format for processing further. Beginner tutorials will show you the standard structure. The component tJava is - of course - an exception to that rule. Handling data is different in this component and not neccessarily row based.
Talend has an excellent knowledge base for components and examples, see https://help.talend.com/

Best practice to POST with optional parameters

I need to define the simple request which will be posting data to the endpoint. I want to send JSON object but depending on the situation it should contain 3 or 4 fields.
1 /endpoint?option=one
{
"parameter1": 123,
"parameter2": 12.2,
"parameter3": 33.2,
"parameter4": "test"
}
2 /endpoint?option=two
{
"parameter1": 123,
"parameter2": 12.2,
"parameter3": 33.2
}
Generate the JSON and send it, in the server you check if the JSON has the field "parameter4".
If the field isn't there, then you can save it as NULL.
EDIT
In Java you can check it like this;
if (jsonObject.has("parameter4")) {
// You have the parameter
}

Cypher Http request with match parameters

I'd like to execute an http cypher query with parameters like :
{"statements":
[
{"statement":"MATCH path=(p:Person {props})-[*..100]->() RETURN [n in nodes(path)]",
"parameters":{"props":{"name":"Lucille"}}
}
]
}
However i get the following error Parameter maps cannot be used in MATCH patterns (use a literal map instead, eg. \"{id: {param}.id}\").
I have no idea how to use a literal map here.
Thanks for your help !
You can either have:
{
"statements": [{
"statement": "MATCH path=(p:Person { name: {name} })-[*..100]->() ...",
"parameters": { "name": "Lucille" }
}]
}
or MATCH path=(p:Person { name: props.{name} }) ... while keeping you initial parameters
The reason is given in this comment:
"Unlike properties in CREATE, MATCH requires the map to be a literal. This is because the property names must be known in advance, when the query is compiled, in order to efficiently plan its execution."
I think your query would become:
MATCH path=(p:Person {id: {props}.id })-[*..100]->()
RETURN [n in nodes(path)]