Is there any way to handle wiremock scenarions manually? - wiremock

I'm using wiremock (rodolpheche/wiremock) for local stubbing. I want to get one of two stubs without any dependency to qyery or params. For example:
I call GET http://foo.bar/identifier/{id} (id is always same)
I need to get one of two mocks, depending on my process:
good { "status": 0 }
bad {"status": 999, "errors": [{"error": 1}, {"error": 2}] }
Can this be done using any wiremock features?
For now i'm replacing a stub file in wiremock, but i want this to be automated somehow...

Related

How do I avoid duplicate fields in Json request payload ? I'm using Apache Camel with REST

I wanted to parse json request by identifying duplicate fields in the request body. E.g. Assume I have below request.
`"employee": {
"name": "abc",
"name": "xyz",
"id": "6754",
"title": "supervisor",
}`
The employee request above has duplicate name field. ideally during json validation/parsing the second duplicate field takes precedence over first but I want to invalidate this kind of json request. How do I achieve this in Camel REST. Below is the approach that I tried but nothing worked. In myorg.apache.camel.builder.RouteBuilder, I tried configuring DataFormatProperty to use DeserializationFeature FAIL_ON_READING_DUP_TREE_KEY but its not failing. How do I fail the request for invalid json request which has duplicate fields.?
`#Override
public void configure() throws Exception {
restConfiguration().bindingMode(RestBindingMode.json).component("servlet")
.jsonDataFormat(JsonParser.Feature.STRICT_DUPLICATE_DETECTION.name())
.dataFormatProperty("prettyPrint", "true")
.dataFormatProperty("json.in.enableFeatures",
"FAIL_ON_NUMBERS_FOR_ENUMS,USE_BIG_DECIMAL_FOR_FLOATS,FAIL_ON_READING_DUP_TREE_KEY"
+ ",FAIL_ON_UNKNOWN_PROPERTIES,ADJUST_DATES_TO_CONTEXT_TIME_ZONE,"
+ JsonParser.Feature.STRICT_DUPLICATE_DETECTION.name())
.dataFormatProperty("json.in.disableFeatures", "FAIL_ON_EMPTY_BEANS").enableCORS(true)`
This may come from the fact that Camel is using XStream as default JSON library (see here).
Did you already try to force the use of Jackson library ?

Smartsheet API response codes with python SDK?

I am using the Smartsheet python SDK to do bulk operations (deletes, updates, etc.) on a Smartsheet. As my process becomes more complex, I've realized that I need to include some internal checks to make sure I am not encountering errors when sending multiple calls per minute as Smartsheet suggests in their API Best Practices.
My question is this: How do I access and parse the API responses while using SDK functions such as Sheets.delete_rows()? For instance, some of my requests using this function can trigger status: 500 Internal Server Error which mean the request was properly formatted but the operation failed on the Smartsheet end.
I can view these responses in my log file (or in terminal while running interactively) but how do I access them from within my script so I can, for example, sleep() my process for xx seconds if encountering such a response?
If you are looking to know the results of a request you can store the response in a variable and inspect that for determining the next steps your process should take. In the case of the DELETE Rows request a Result object is returned.
deleteRows = smartsheet_client.Sheets.delete_rows({{sheetId}}, [ {{rowId1}}, {{rowId2}}, {{rowId3}}])
print(deleteRows)
If the request was successful the response would look like this:
{"data": [7411278123689860], "message": "SUCCESS", "result": [7411278123689860], "resultCode": 0}
If there was an issue, rows weren't found for example, the response would look like this:
{"result": {"code": 1006, "errorCode": 1006, "message": "Not Found", "name": "ApiError", "recommendation": "Do not retry without fixing the problem. ", "refId": "jv6o8uyrya2s", "shouldRetry": false, "statusCode": 404}}
All of the Smartsheet SDKs will backoff and retry by default. Other errors will be thrown as exceptions.
There is a way to increase the default timeout (to allow more retries) when creating the client. However, the Python-specific way to do it doesn't seem to be documented yet. I'll add it to the queue. In the meantime, I think the Ruby example below will be the closest to how Python probably does it, but you might want to read through the various ways to do this.
C#: https://github.com/smartsheet-platform/smartsheet-csharp-sdk/blob/master/ADVANCED.md#sample-retryhttpclient
Java: https://github.com/smartsheet-platform/smartsheet-java-sdk/blob/master/ADVANCED.md#sample-retryhttpclient
Node.js: https://github.com/smartsheet-platform/smartsheet-javascript-sdk#retry-configuration
Ruby: https://github.com/smartsheet-platform/smartsheet-ruby-sdk#retry-configuration

Can apiary.io echo back request data?

If I have an apiary.io API described like this:
### Create a User [POST]
+ Request (application/json; charset=utf-8)
{
"user_id": 1053,
"username": "demo#demo.com",
"email": "demo#demo.com",
"active": "true"
}
+ Response 201 (application/json)
{
"user_id": 1053,
"username": "demo#demo.com",
"email": "demo#demo.com",
"active": "true"
}
When I call it from my application and pass it data, it will always pass me back the described payload no matter what data I pass in.
Is there a way to get it to echo back the exact data that I passed in instead of the described payload?
According to Apiary docs/examples you can not, only static request-response mocking. Also you could track this issue.
If you want to use kind of advanced mocks I would suggest you wiremock. It's not so fancy, but way more feature reach. You could run it as a service and update mock mappings at runtime by sending HTTP requests.
Please check solution for your question using wiremock. Related documentation.

REST: Update resource with unknown (server-generated) value

I have a resource foo with the following structure:
GET /foo/1 returns:
{
"id": 1,
"server-key": "abcdef",
"status": "expired"
}
Status can either be active or expired. If it is expired I want the server to generate a new one.
Normally I'd issue PUT/PATCH foo/1 with the new key, but client doesn't know the key-generation algorithm.
I could also do a POST foo/1/server-key with no body, but that feels strange (I know this isn't very scientific reason though).
Any good ideas/patterns?
In case when you've got expired entity just make POST call on /foo without any parameters and server should return new entity (and HTTP response code should be 201):
{
"id": 2,
"server-key": "xyz",
"status": "active"
}
If some resourece is expired it is unconvinient to make it active again by PUT/PATCH request.
The approach I would adopt is to set a null value to server-key and let the server deal with it, but I do that because it's a consistent behavior in my APIs for the server to fill missing values with defaults.
Other than that, a simple POST to the URI as suggested in the other answer is adequate.
I think that you should use a PUT/PATCH method in your case to ask for generate a token if expired. Generally it's not really RESTful to put an action name within the resource path ;-)
I would see something like that:
Get the element: GET /foo/1
If the status is expired, ask for a new server key to be generated: POST /foo/1. In this case, this method will be used to execute an action to reinitialize the key on the server side
Using the method PUT corresponds to update the complete representation with a new one provided by the client. With the method PATCH, you will do a partial update of the representation.
Here is a link that could give you some hints about the way to design a Web API (RESTful service): https://templth.wordpress.com/2014/12/15/designing-a-web-api/.
Hope it helps you,
Thierry

Marketo "Import Lead" fails with error 610 Requested resource not found

I'm trying to batch update a bunch of existing records through Marketo's REST API. According to the documentation, the Import Lead function seems to be ideal for this.
In short, I'm getting the error "610 Resource Not Found" upon using the curl sample from the documentation. Here are some steps I've taken.
Fetching the auth_token is not a problem:
$ curl "https://<identity_path>/identity/oauth/token?
grant_type=client_credentials&client_id=<my_client_id>
&client_secret=<my_client_secret>"
Proving the token is valid, fetching a single lead isn't a problem as well:
# Fetch the record - outputs just fine
$ curl "https://<rest_path>/rest/v1/lead/1.json?access_token=<access_token>"
# output:
{
"requestId": "ab9d#12345abc45",
"result": [
{
"id": 1,
"updatedAt": "2014-09-18T13:00:00+0000",
"lastName": "Potter",
"email": "harry#hogwartz.co.uk",
"createdAt": "2014-09-18T12:00:00+0000",
"firstName": "Harry"
}
],
"success": true
}
Now here's the pain, when I try to upload a CSV file using the Import Lead function. Like so:
# "Import Lead" function
$ curl -i -F format=csv -F file=#test.csv -F access_token=<access_token>
"https://<rest_path>/rest/bulk/v1/leads.json"
# results in the following error
{
"requestId": "f2b6#14888a7385a",
"success": false,
"errors": [
{
"code": "610",
"message": "Requested resource not found"
}
]
}
The error codes documentation only states Requested resource not found, nothing else. So my question is: what is causing the 610 error code - and how can I fix it?
Further steps I've tried, with no success:
Placing the access_token as url parameter (e.g. appending '?access_token=xxx' to the url), with no effect.
Stripping down the CSV (yes, it's comma seperated) to a bare minimum (e.g. only fields 'id' and 'lastName')
Looked at the question Marketo API and Python, Post request failing
Verified that the CSV doesn't have some funky line endings
I have no idea if there are specific requirements for the CSV file, like column orders, though...
Any tips or suggestions?
Error code 610 can represent something akin to a '404' for urls under the REST endpoint, i.e. your rest_path. I'm guessing this is why you are getting that '404': Marketo's docs show REST paths as starting with '/rest', yet their rest endpoint ends with /rest, so if you follow their directions you get an url like, xxxx.mktorest.com/rest/rest/v1/lead/..., i.e. with '/rest' twice. This is not correct. Your url must have only one 'rest/'.
I went through the same trouble, just want to share some points that help resolve my problem.
Bulk API endpoints are not prefixed with ‘/rest’ like other endpoints.
Bulk Import uses the same permissions model as the Marketo REST API and does not require any additional special permissions in order to use, though specific permissions are required for each set of endpoints.
As #Ethan Herdrick suggested, the endpoints in the documentation are sometimes prefixed with an extra /rest, make sure to remove that.
If you're a beginner and need step-by-step instructions to set up permissions for Marketo REST API: Quick Start Guide for Marketo REST API