SoapUI correlation (property transfer) - properties

I have a REST request that respond with the following:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6IlQwWE8xNnAtMmZzMWxremV5",
"expires_in": 2592000,
"token_type": "Bearer"
}
I want to take the value of access_token, store it in a property and reuse it for two subsequent requests.
Following some tutorial here, when running the request that obtains the access_token I get a:
error parsing target property: error unexpected element CDATA
But why?
There is no CDATA in my raw response.

If you've problems using transfer properties step to get the JSON value from your response, you can use a groovy test step to achieve your goal.
So create a groovy test step to parse your response, get your value and set it as a property (for example at testCase level) with the follow code:
import groovy.json.JsonSlurper
// get response using the name of your test step
def response = context.expand('${REST Test Request#Response}')
// parse response
def jsonResp = new JsonSlurper().parseText(response)
// get the token an set as a property in the testCase
testRunner.testCase.setPropertyValue('access_token',jsonResp.access_token)
Then in the other testSteps (REST or SOAP...) you can use the follow code to get the access_token value you set in the testCase:
${#TestCase#access_token}
Hope this helps,

Related

Why aren't HTTP Headers passed from AWS API Gateway to Step functions

I have an api gateway set up with integration to a step function - the integration is working well and my function is executed. However I have a need to access the headers on the initial request to the api gateway (as they need to be passed on to an API call made by one of the steps in the step function) I've added the http headers to the API Gateway Method Request and also done this in the HTTP Headers section of the Integration Request, then in the mapping template I have
#set($inputbody = $input.json('$'))
{
"method": "$context.httpMethod",
"input": "$util.escapeJavaScript($inputbody)",
"stateMachineArn": "MyStateMachineARN",
"headers": {
#foreach($param in $input.params().header.keySet())
"$param": "$util.escapeJavaScript($input.params().header.get($param))"
#if($foreach.hasNext),#end
#end
}
}
When I test this I see the headers after the request body has been transformed - before it executes the step function
Thu Dec 23 09:35:28 UTC 2021 : Endpoint request body after transformations: {
"method": "POST",
"input": "{\"surname\":\"TESTSURNAME\"}",
"stateMachineArn": "MyStateMachineARN",
"headers": {
"HeaderA": "ValueA"
, "HeaderB": "ValueB"
}
}
But in the step functions I am struggling to see the headers - the input I can see at the start of the execution is only
{
"surname::"TESTSURNAME"
}
I have inputPath set to $ and the same for the payload.
All the suggestions I've found online point to the mapping template but I can not get it to work - any ideas what I'm doing wrong?
The API Gateway -> Step Function integration uses StartExecution as the action for the integration. Checking the documentation for StartExecution request syntax, it turns out that headers is unfortunately not one of the allowable fields that can be passed. To pass the headers in it looks like you would need to add them onto the input.

Schedule refresh not working for web.contents based query

This is the message I get when I am trying to get the token data using web.contents query from "VMware vRealize Automation API":
There was an error when processing the data in the dataset.
Please try again later or contact support. If you contact support, please provide these details.
Data source error
{"error":{"code":"ModelRefresh_ShortMessage_ProcessingError","pbi.error":{"code":"ModelRefresh_ShortMessage_ProcessingError","parameters":
{},"details":[{"code":"Message","detail":{"type":1,"value":"Web.Contents failed to get contents from 'https://xxxxxxxxx.com/identity/api/tokens'
(404): Not Found"}}],"exceptionCulprit":1}}}
Table: GetToken.
The url passed to the first parameter of Web.Contents (authUrl = "https://xxxxxxxxx.com/identity/api/tokens") is accessible but always return the HTTP ERROR 405, probably
because this API uses a a JSON object in the request body parameter with the users credentials to obtain the Response.
API
My query
The main issues:
Your API uses HTTP POST verses GET, so you need to set Options[Content]
You can get refresh errors on the service unless you use Options[RelativePath]
You can "opt-in" to handling errors for specific HTTP Status codes, combined with Value.MetaData you get more detailed error messages.
Let it generate JSON for you from records and lists by using Query or Content parameters see: docs: Web.Contents
This is equivalent to your curl POST request
let
BaseUrl = "https://www.example.com",
Options = [
RelativePath = "/identity/api/tokens",
Headers = [
Accept="application/json"
],
Content = [
username = "username",
password = "password",
tenant = "tenant"
],
ManualStatusHandling = {400, 405}
],
// wrap 'Response' in 'Binary.Buffer' if you are using it multiple times
response = Web.Contents(BaseUrl, Options),
buffered = Binary.Buffer(response),
response_metadata = Value.Metadata(response),
status_code = response_metadata[Response.Status],
from_json = Json.Document(final_result)
in
from_json
I have related Web.Contents examples here, like Chaining Web.Contents requests: ninmonkeys.com/Power-Query-Custom-Functions-Cheat-Sheet

How to obtain response to be used on hooks

I am trying to make a simplified version of test report where I am generating a single HTML file report containing only assertion and error response message when there is any (attempting to not publish all the logs and steps).
I understand that we have hooks in karate. However I have looked for karate objects in the github but unable to found any objects where I can extract the response from (to be passed to the js function called on hook)
What I am doing right now is this:
Config:
//karate-config.js
karate.configure('afterScenario', karate.call('classpath:hooks.js'));
Hook:
//hooks.js
//Looking on how to extract the response and log it here
function(){
var info = karate.tags;
karate.log('Tags', info);
}
Am I missing anything on the karate objects? Or this should be achieved in another way?
Thanks a lot!
Try this:
var response = karate.get('response');
EDIT better example:
Background:
* configure afterScenario = function(){ karate.log('***', karate.get("response.headers['X-Karate']")) }
Scenario:
Given url 'http://httpbin.org'
And path 'headers'
And header X-Karate = 'test'
When method get
# this will fail
Then status 400
I have tried with both karate.get('response') and response directly, and both work. If you use karate.call() pass the response as a parameter.

Can Postman Variables be Passed Into Header?

I am trying to string a few Postman requests together for testing.
In the first request I set a global variable as a test script.
tests['Status code is 200'] = (responseCode.code === 200);
if (responseCode.code === 200) {
try {
let jwt = responseBody.replace(/"/g, '');
pm.globals.set("jwt", jwt);
console.log("Variable will be set to", jwt);
}
catch(e) {
console.log(e);
}
}
In the second request I run a pre-request script as
let jwt = pm.globals.get("jwt");
Then I try to pass it into the header
Is it possible to pass a value into the header when running tests in the runner?
When running tests in the Runner the second request fails due to having an invalid jwt, and the Postman docs only show examples passing variables into the URL.
It's covered in postman auth.
Authenticate to get the JWT(oken) - Token API request
Add the test in to capture the token
var jsonData = JSON.parse(responseBody);
postman.setEnvironmentVariable("jwt", jsonData.token);
Authorization > Type > Bearer Token
Token: {{jwt}}
Setup your Environment
Select the Environment
Select Keep variable values from the Collection Runner dialog (if you are running it in command line)
Note: I'm using version 6.3.0.

API Connect 5 - Error attempting to read the urlopen response data

I'm trying to create a REST API from a SOAP Service using IBM API Connect 5. I have followed all the steps described in this guide (https://www.ibm.com/support/knowledgecenter/en/SSFS6T/com.ibm.apic.apionprem.doc/tutorial_apionprem_expose_SOAP.html).
So, after dragging the web service block from palette, ensuring the correctness of endpoint and publishing the API, I have tried to call the API from the browser. Unfortunately, the API return the following message:
<errorResponse>
<httpCode>500</httpCode>
<httpMessage>Internal Server Error</httpMessage>
<moreInformation>Error attempting to read the urlopen response
data</moreInformation>
</errorResponse>
To testing purpose, I have logged the request and I have tried the request on SOAPUI. The service return the response correctly.
What is the problem?
In my case, the problem was in the backend charset (Content-Type: text/xml;charset=iso-8859-1).
For example, backend returns text/xml in German (or French). Api Connect cannot process character ΓΌ. It needs Content-Type: text/xml;charset=UTF-8.
I had a similar issue, in my case was the accept. if you have an Invoke and the content-type or the accept, is not matching the one of the request, or the response that you got, APIC is getting mad.
Please, check if the formats to send (contentType) and receive (accept) are the same of that your API expected. In my case the error occurs because the API returns a String and my default code is configured to receive a JSON body.
//define a JSON-PLAIN TEXT protocol
private HttpEntity<String> httpEntityWithBody(Object objToParse){
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + "xxx token xxx");
headers.set("Accept", MediaType.TEXT_PLAIN_VALUE);
headers.setContentType(MediaType.APPLICATION_JSON);
Gson gson = new GsonBuilder().create();
String json = gson.toJson(objToParse);
HttpEntity<String> httpEntity = new HttpEntity<String>(json, headers);
return httpEntity;
}
//calling the API to APIC...
ParameterizedTypeReference<String> responseType = new
ParameterizedTypeReference<String>(){};
ResponseEntity<String> result =
rest.exchange(builder.buildAndExpand(urlParams).toUri(), HttpMethod.PUT, httpEntityWithBody(myDTO), responseType);
String statusCode = result.getStatusCodeValue();
String message = result.getBody();