Using regex to negate a filter in wiremock jsonpath - jsonpath

I am using wiremock for stubbing and it uses Jayway JsonPath.
I want to create a stub only when the json element doesn't contain exactly 10 digits.
stub is
"request": {
"bodyPatterns": [
{
"matchingJsonPath": "$.employees[?(#.employeeContact =~/[^0-9]{10}/)]"
}
]
}
I have tried multiple combinations like:
1. $.employees[?(#.employeeContact =~/[^0-9]{10}/)]
2. $.employees[?(#.employeeContact =~/^[0-9]{10}/)]
3. $.employees[?(#.employeeContact !=~/[0-9]{10}/)]
4. $.employees[?(#.employeeContact <>~/[^0-9]{10}/)]
But none of these have worked.
Example json which should NOT work:
{
"employee": {
"employeeContact": "1234567890"
}
}
while these employee should work (anything other than 10 digits):
1. "employeeContact": "1a34567890" // character in between
2. "employeeContact": "12345678901" // more than 10
3. "employeeContact": "123456789" // less than 10
4. "employeeContact": "123456 89" //space

You could use the logical or operator to match for lengths less than 10 and greater than 10.
"bodyPatterns": [
"or": [
{ "matchingJsonPath": "$.employees[?(#.employeeContact =~/[^0-9]{1,9}/)]" },
{ "matchingJsonPath": "$.employees[?(#.employeeContact =~/[^0-9]{11,}/)]" }
]
]

This is what worked for me:
"bodyPatterns": [{
"matchesJsonPath": "$.employees[?(#.employeeContact =~/[^0-9]{1,9}/ || $.employees[?(#.employeeContact =~/[^0-9]{11,}/)]"
}]
Watch that it is matchesJsonPath instead of matchingJsonPath.
Even with that "or" didnt work with my wiremock 2.28.1 so may well be a wiremock bug.

Related

Firestore Pagination : how to set Cursor for startAt using Rest Api

I'm using firebase firestore using Rest API to get data limited by 5 documents only, ordered by a field called LikesCount.
When I want to fetch the next 5 documents I have to use startAt and pass the LikesCount value of the last document from the first 5 documents.
But in this way, it will fetch wrong data when there is another document with the same LikesCount value So I tried and searched a lot about how to pass the last Document id in addition to the LikesCount value But all of them did not work In addition, I tested the pagination using the Web SDK and it was working correctly because you can pass the document snapshot easily, but what does the document snapshot object include? So that we can understand the structure of the Cursor and apply it to the REST API.
I tried to use this method to pass the Document ID as referenceValue
{
"structuredQuery": {
"from": [{
"collectionId": "Users"
}],
"where": {
"compositeFilter": {
"op": "AND",
"filters": []
}
},
"orderBy": [{
"field": {
"fieldPath": "LikesCount"
},
"direction": "DESCENDING"
}],
"startAt":
{ "values": [
{
"integerValue": "6"
},
{
"referenceValue": "projects/myprojectid/databases/(default)/documents/Posts/xEvmJ1LLHwTKVREQfXtX"
}
],
"before": false
},
"limit":5
}
}
But an error will occur : Cursor has too many values.
also, I tried to pass only the referenceValue and it still did not return the correct 5 documents.
Thanks in advance :)
Your orderBy() has 1 field (LikesCount) but your startAt() has 2 fields. I suspect that is the reason for the error message?
Passing the integerValue won't work. If there are 13 results with the value 6, then each time you make the above call you'd get the same first 5 results.
When you say:
I tried only passing the referenceValue and still did not get the correct 5 documents
what documents are you getting? What documents were you expecting to get?

Pact exact match of a field within an array

I am writing a pact test for a request that filters out the response data by a certain field, hense I would like to create a matcher that would match an array of objects with an exact match on that field.
I tried doing the following two aproaches:
body: eachLike({
color: 'red',
name: like('any'),
}),
body: eachLike({
color: extractPayload('red'),
name: like('any'),
}),
Bot both of them produce the same result:
"matchingRules": {
"$.body": {
"min": 1
},
"$.body[*].*": {
"match": "type"
},
"$.body[*].name": {
"match": "type"
}
}
It seems to me that having "$.body[*].*": {"match": "type"} in there negates the exact matching for the color field. Am I wrong in that assumption, or is there a correct approach that would resolve this issue?
Yes, the issue is that the type matching is cascading and is not being reset.
The equal matcher (V3 only) will reset the matching rule for this context.
It's available in the latest beta: https://github.com/pact-foundation/pact-js/tree/feat/v3.0.0#using-the-v3-matching-rules
To work it in v2, I would use the regex that matches a single string value here.

AWS Step Functions: Filter an array using JsonPath

I need to filter an array in my AWS Step Functions state. This seems like something I should easily be able to achieve with JsonPath but I am struggling for some reason.
The state I want to process looks like this:
{
"items": [
{
"id": "A"
},
{
"id": "B"
},
{
"id": "C"
}
]
}
I want to filter this array by removing entries for which id is not in a specified whitelist.
To do this, I define a Pass state in the following way:
"ApplyFilter": {
"Type": "Pass",
"ResultPath": "$.items",
"InputPath": "$.items.[?(#.id in ['A'])]",
"Next": "MapDeployments"
}
This makes use of the JsonPath in operator.
Unfortunately when I execute the state machine I receive an error:
{
"error": "States.Runtime",
"cause": "An error occurred while executing the state 'ApplyFilter' (entered at the event id #8). Invalid path '$.items.[?(#.id in ['A'])]' : com.jayway.jsonpath.InvalidPathException: com.jayway.jsonpath.InvalidPathException: Space not allowed in path"
}
However, I don't understand what is incorrect with the syntax. When I test here everything works correctly.
What is wrong with what I have done? Is there another way of achieving this sort of filter using JsonPath?
According to the official AWS docs for Step Functions,
The following in paths are not supported # .. , : ? *
https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-paths.html

JSON Path not working properly with athena

I have a lambda function that converts my logs to this format:
{
"events": [
{
"field1": "value",
"field2": "value",
"field3": "value"
}, (...)
]
}
When I query it on S3, I get in this format:
[
{
"events": [
{ (...) }
]
}
]
And I'm trying to run a custom classifier for it because the data I want is inside the objects kept by 'events' and not events itself.
So I started with the simplest path I could think that worked in my tests (https://jsonpath.curiousconcept.com/)
$.events[*]
And, sure, worked in the tests but when I run a crawler against the file, the table created includes only an events field with a struct inside it.
So I tried a bunch of other paths:
$[*].events
$[*].['events']
$[*].['events'].[*]
$.[*].events[*]
$.events[*].[*]
Some of these does not even make sense and absolutely every one of those got me an schema with an events field marked as array.
Can anyone point me to a better direction to handle this issue?

Logstash grok filter help - hexedecimal?

Ok im fishing out, amongst other things, the first segment of a unique ID from a log line with a grok filter, like this (Its only the first segment that I care about, throw away the rest). This segment is hex ,and I want it in binary.
The line:
Transaction: 000178ec-XXXX-XXXX-XXXX-XXXXXXXXXXXX
The filter is like :
Transaction: %{BASE16NUM:transaction_id}-%{GREEDYDATA:otherpartsidontcareabout}
But it just gives me this result:
{
"transaction_id": [
[
"000178ec"
],
"otherpartsidontcareabout":
[
"XXXX-XXXX-XXXX-XXXXXXXXXXXX"
]]
}
Where I had expected it to be transformed into decimal:
{
"transaction_id": [
[
"96492"
],
"otherpartsidontcareabout":
[
"XXXX-XXXX-XXXX-XXXXXXXXXXXX"
]]
}
Am I doing this wrong? Im really stuck.
BASE16NUM just indicates the pattern of the text. To convert it to an integer you are going to have to do something like this:
filter {
ruby {
code => "event['transaction_id'] = event['transaction_id'].hex"
}
}
or for logstash 5
filter {
ruby {
code => "event.set('transaction_id', event.get('transaction_id').hex)"
}
}

Resources