akka http - How to add json data to post request? - akka

I am querying a search api and I need to add the query params in json as body to a post request.
val headers: scala.collection.immutable.Seq[HttpHeader] = scala.collection.immutable.Seq(
RawHeader("accept", "application/json"),
RawHeader("authorization", "xxxxxxxxxxxxxxxxxxxx"),
RawHeader("content-type", "application/json"),
RawHeader("x-customer-id", "123456789")
)
val formData = FormData(Map(
"Keywords" -> "query", "Count" -> "25"
))
val request = HttpRequest(HttpMethods.POST, "https://api.xxx.com/services/xxx/v1/search?client_id=xxxxxx", headers, formData.toEntity)
Will using formData.toEntity send it as json in body of the post?

I created a class for search query and serialized it and created an HttpEntity like so:
case class SearchObject(keyWords: String, count: Int)
val reqHeaders: scala.collection.immutable.Seq[HttpHeader] = scala.collection.immutable.Seq(
RawHeader("accept", "application/json"),
RawHeader("authorization", "xxxxxxxxxxxxxxxxxxxx"),
RawHeader("content-type", "application/json"),
RawHeader("x-customer-id", "123456789")
)
val searchObject = net.liftweb.json.Serialization.write(req) //req is search object
val searchObjectEntity = HttpEntity(ContentTypes.`application/json`, searchObject)
val request = HttpRequest(HttpMethods.POST, "https://api.xxxxxxxx.com/services/xxxxxx/v1/search?client_id=45854689", reqHeaders, searchObjectEntity)

Related

Lambda Authorizer of type Request not working in Kotlin

I've been trying to use a custom authorizer ( lambda authorizer ) of type Request for a certain HTTP API in Kotlin.
Taking inspiration from this, I wrote the following :
class AuthorizerHandler : RequestHandler<Map<String, Any>, AuthorizerResponse>{
override fun handleRequest(input: Map<String, Any>, context: Context?): AuthorizerResponse {
val LOG = LogManager.getLogger(AuthorizerHandler::class.java)
LOG.info(input)
val headers = input["headers"]!! as Map<*, *>
val authorization = headers["authorization"]!! as String
val arn = input["routeArn"]!! as String
val tokenBody: TokenBody = TokenBody.fromToken(authorization)
LOG.info("SUB : ${tokenBody.userID}")
val proxyContext = input["requestContext"] as Map<*, *>
val principalId = proxyContext["accountId"] as String
val statement = IamPolicyResponse.Statement.builder().withResource(listOf("*"))
.withEffect("Allow")
.withAction("execute-api:Invoke")
.build()
val policyDocument = IamPolicyResponse.PolicyDocument.builder()
.withStatement(listOf(statement))
.withVersion("2012-10-17")
.build()
return AuthorizerResponse(principalId = tokenBody.userID, policyDocument = policyDocument)
}
}
TokenBody is custom class with init function fromToken that helps me deconstruct the token. It's working as expected and tokenBody.userID gives me the user's sub.
AuthorizerResponse is also a custom class which looks like this :
class AuthorizerResponse (
#JsonProperty("principalId")
val principalId: String? = null,
#JsonProperty("policyDocument")
val policyDocument: IamPolicyResponse.PolicyDocument? = null,
#JsonProperty("context")
val context: Map<String, String>? = null,
)
First I was supplying arn as the Resource when building my statement. Calling the API resulted in
{
"message": "Internal Server Error"
}
Changing Resource to * doesn't help either and throws the same 500 Internal Server Error.
Similarly, I've tried accountID as principalID as well but that doesn't work either.
I've checked the logs of the Authorizer lambda but that doesn't throw any error so it's technically working as expected after getting invoked properly.
Any ideas on how this can be fixed?
Edit : Mentioned the type of API.

Passing a String List in a SOAP request in Flutter

I am making a SOAP Request and this is how my request should be sent:
<id></id>
<fieldList>
<string>string</string>
<string>string</string>
</fieldList>
This is how I have built my envelope:
final int id = 21;
List<String> fieldList = new List<String>();
fieldList = [
"pinNumber:PIN0000074",
"dispatchArrivedTime:13.05",
"towedStatus:C"
];
var envelope = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
"<soap:Envelope "
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" "
"xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
"<soap:Body>"
"<update xmlns=\"http://example.com/\">"
"<id>${id}</id>"
"<fieldList>${fieldList}</fieldList>"
"</update>"
"</soap:Body>"
"</soap:Envelope>";
final response = await http.post(
'http://example.com/vc/ws/towedvehicletable.asmx',
headers: {
"Content-Type": "text/xml; charset=utf-8",
"SOAPAction": "http://example.com/update",
"Host": "example.com"
//"Accept": "text/xml"
},
body: envelope);
However, this approach does not work. It would be really helpful if somebody could show me how to pass a String List into my request. I am using Flutter and Dart. Thanks
Just map list of strings and then join it:
List<String> fieldList = ['test1', 'test2'];
final xmlValues = fieldList.map((v) => '<string>$v</string>').join();
print(xmlValues);
prints:
<string>test1</string><string>test2</string>
There's also a package for working with XML. It allows you to both parse and construct XML documents.

Why is captured azure eventhub information for SystemProperties and Properites empty?

I am using Azure EventHub and capturing the contents to blob storage using https://learn.microsoft.com/en-us/azure/event-hubs/event-hubs-capture-overview.
Now for the generated Avro files, why is the information stored in the properties and System properties fields empty?
NOTE Azure is populating these fields
I publish the data using a POST request with my payload as the body and authorization headers set.
Am I missing additional headers which would be required to make Azure fill these columns?
edit
so the event hub client`s POST method looks like this:
private val SB_URL = "https://$namespace.servicebus.windows.net/$eventHub"
private val HEADER_AUTHORIZATION = AzureUtil.getSasToken(SB_URL, sas_key_name, sas_key)
private val HEADER_CONTENT_TYPE = "application/atom+xml;type=entry;charset=utf-8"
private val REQ_URL = "https://$namespace.servicebus.windows.net/$eventHub/messages"
private val REQ_TIMEOUT = "60"
private val REQ_API_VERSION = "2014-01"
private val client = OkHttpClient()
private val JSON = "application/json; charset=utf-8".toMediaType()
private var callback: Callback? = null
fun registerCallback(cb: Callback) {
callback = cb
}
fun send(message: String) {
val request = Request.Builder()
.url("$REQ_URL?timeout=$REQ_TIMEOUT&api-version=$REQ_API_VERSION")
.addHeader("Content-Type", HEADER_CONTENT_TYPE)
.addHeader("Authorization", HEADER_AUTHORIZATION)
.post(message.toRequestBody(JSON))
.build()
val call = client.newCall(request)
try {
val response = call.execute()
callback!!.onResponse(call, response)
} catch (error: IOException) {
callback!!.onFailure(call, error)
}
}

Windows.Web.HttpClient: Cookies will not be sent

I send a HTTP Get Request with a Basic Authentification to the Login-Endpoint of the Host:
request = new HttpRequestMessage();
// Configuration Item: Login URL Suffix
request.RequestUri = new Uri(string.Format("https://{0}/{1}", Host, loginSuffix));
request.Method = Windows.Web.Http.HttpMethod.Get;
var info = User + ":" + Password;
var token = Convert.ToBase64String(Encoding.UTF8.GetBytes(info));
request.Headers.Authorization = new HttpCredentialsHeaderValue("Basic", token);
_httpClient = CreateHttpClient(ref cookieManager);
response = await _httpClient.SendRequestAsync(request, HttpCompletionOption.ResponseContentRead);
response.EnsureSuccessStatusCode();
responseBodyAsText = await response.Content.ReadAsStringAsync();
The HttpClient is created with a Filter, to set Cookies later:
private HttpClient CreateHttpClient(ref HttpCookieManager _cookieManager)
{
HttpBaseProtocolFilter _filter = new HttpBaseProtocolFilter();
HttpClient _httpClient = new Windows.Web.Http.HttpClient(_filter);
_cookieManager = _filter.CookieManager;
return _httpClient;
}
From the Response the SET-COOKIE Header can be read.
string[] Queries;
response.Headers.TryGetValue("Set-Cookie", out tmpString);
if (tmpString != null)
Queries = tmpString.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
I´m looking for a Cookie with a defined Name (CookieKeyName), which will be set in the next Request.
foreach (var query in Queries)
{
if (query.Contains(CookieKeyName))
{
staticCookieKey = query.Substring(0, query.IndexOf("="));
staticCookieValue = query.Substring(query.IndexOf("=") + 1);
}
}
I would expect, that the HttpClient will use the received Set-Cookie in the response for this URL as Cookie in every following Request automatically.
I´m preparing the next Request and setting the Cookie by myself:
request.RequestUri = new Uri(string.Format("https://{0}/qcbin", Host));
request.Method = Windows.Web.Http.HttpMethod.Get;
HttpCookie _cookie = new Windows.Web.Http.HttpCookie(staticCookieKey, Host, "/");
_cookie.Value = staticCookieValue;
bool replaced = cookieManager.SetCookie(_cookie);
The following Sending of the Requests provides to a Web Exception 401, because the Server expects for this URL the previously in the Response received Cookie.
response = await _httpClient.SendRequestAsync(request, HttpCompletionOption.ResponseContentRead);
response.EnsureSuccessStatusCode();
responseBodyAsText = await response.Content.ReadAsStringAsync();
Looking with Fiddler on the Line, the second Request contains no Cookie Header. Even Setting of the Cookie in CookieManager nor the proceeding of the Set-Cookie i the first Response by the HttpClient is working.
Hint: The length of the value of the Cookies is about 6000 chars (coming from a IBM Data Power).
Thank you in advance for help.

how to take only JSON response from SOAPUI

I am working on project which is giving XML and JSON type of response. I need to take only JSON response from SOAPUI to process for next step.
Is there any SOAPUI api available to get only JSON type of response by groovy script.
Thanks in advance.
Please check this response SoapUI Groovy Script’s JSON Responses Is Empty When Using Testrunner
import groovy.json.JsonSlurper
//provide the correct rest test step name
def stepName='testStepForPing'
def step = context.testCase.getTestStepByName(stepName)
def response = new String(step.testRequest.messageExchange.response.responseContent)
log.info response
def json = new JsonSlurper().parseText(response)
Assuming it's a REST service, by default this approach will fetch the response in JSON format.
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
def response = groovyUtils.getXmlHolder("RequestStepName#Response")
// as a string -> def response = context.expand('${RequestStepName#Response}')
You can get it as xml using #ResponseAsXml.
In the SOAPUI Javascript context I developed this algorithm.
var xmlHolder = com.eviware.soapui.support.XmlHolder(messageExchange.responseContent);
var nodes = xmlHolder.getDomNodes("//SOAP-ENV:Envelope/SOAP-ENV:Body/ns:xxxxxx");
var obj = {};
toJsonObject(nodes[0], obj);
function toJsonObject(xmlObject, jsonObject) {
for (var i = 0; i < xmlObject.getLength(); i++) {
var node = xmlObject.item(i);
if (node.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
if (node.getLength() == 1) {
if (node.hasChildNodes()) {
jsonObject[node.getNodeName()] = String(node.item(0).getNodeValue());
}
} else {
if (node.hasChildNodes()) {
jsonObject[node.getNodeName()] = {};
jsonObject[node.getNodeName()] = toJsonObject(node, jsonObject[node.getNodeName()]);
}
}
}
}
return jsonObject;
}
log.info(JSON.stringify(obj));
context.setProperty('JSON: ', JSON.stringify(obj));