IBM App Connect Enterprise - Aggregate Group Node Results - ibm-integration-bus

I'm using the Group Nodes in App Connect ACE 11 to call a service multiple times and trying to aggregate the the responses. Everything works fine and the below is the result of InputRoot.ComIbmGroupCompleteNode.Group.
{
"msg": {
"GroupProperties": {
"GroupId": "010000000000000000000000000000001000000000000000",
"GroupName": "TSTGRP",
"GroupCreationTime": 1593669682652,
"GroupCommitTime": 1593669682707,
"GroupCompleteTime": 1593669682806,
"GroupOutputTime": 1593669682806,
"GroupStatus": "Completed"
},
"Context": {
"HTTP": {
"RequestIdentifier": "45564854000000000e000000db851d0ecc11000000000000"
},
"RouterList": {}
},
"Replies": {
"FLDR": {
"ReplyId": "534f41503000000067e55223146300000400000000000000",
"RequestSendTime": 1593669682674,
"ReplyReceiptTime": 1593669682706,
"Reply": {
"Root": {
"HTTPResponseHeader": {
"X-Original-HTTP-Status-Line": "HTTP/1.1 200 OK",
"X-Original-HTTP-Status-Code": 200,
"Date": "Thu, 02 Jul 2020 06:01:17 GMT",
"Content-Type": "application/json; charset=utf-8",
"Content-Length": "83",
"Connection": "keep-alive",
"Set-Cookie": "__cfduid=dfbd2cc294d944ed4cfdf6b72a343f8dc1593669677; expires=Sat, 01-Aug-20 06:01:17 GMT; path=/; domain=.typicode.com; HttpOnly; SameSite=Lax",
"X-Powered-By": "Express",
"X-Ratelimit-Limit": "10000",
"X-Ratelimit-Remaining": "9999",
"X-Ratelimit-Reset": "1592660247",
"Vary": "Origin, Accept-Encoding",
"Access-Control-Allow-Credentials": "true",
"Cache-Control": "max-age=43200",
"Pragma": "no-cache",
"Expires": "-1",
"X-Content-Type-Options": "nosniff",
"Etag": "W/\"53-hfEnumeNh6YirfjyjaujcOPPT+s\"",
"Via": "1.1 vegur",
"CF-Cache-Status": "HIT",
"Age": "15242",
"Accept-Ranges": "bytes",
"cf-request-id": "03afb689ec00007f11da290200000001",
"Server": "cloudflare",
"CF-RAY": "5ac626bcaa097f11-CMB"
},
"JSON": {
"Data": {
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
}
}
}
},
"FLDR": {
"ReplyId": "534f415031000000273b5323146300000400000000000000",
"RequestSendTime": 1593669682707,
"ReplyReceiptTime": 1593669682737,
"Reply": {
"Root": {
"HTTPResponseHeader": {
"X-Original-HTTP-Status-Line": "HTTP/1.1 200 OK",
"X-Original-HTTP-Status-Code": 200,
"Date": "Thu, 02 Jul 2020 06:01:17 GMT",
"Content-Type": "application/json; charset=utf-8",
"Content-Length": "99",
"Connection": "keep-alive",
"Set-Cookie": "__cfduid=debd2bf084ee690942fb5d3439e41fa331593669677; expires=Sat, 01-Aug-20 06:01:17 GMT; path=/; domain=.typicode.com; HttpOnly; SameSite=Lax",
"X-Powered-By": "Express",
"X-Ratelimit-Limit": "500",
"X-Ratelimit-Remaining": "497",
"X-Ratelimit-Reset": "1593684076",
"Vary": "Origin, Accept-Encoding",
"Access-Control-Allow-Credentials": "true",
"Cache-Control": "max-age=43200",
"Pragma": "no-cache",
"Expires": "-1",
"X-Content-Type-Options": "nosniff",
"Etag": "W/\"63-+s0zIP5ZEQN9hypVJUneLybJ+L0\"",
"Via": "1.1 vegur",
"CF-Cache-Status": "HIT",
"Age": "8713",
"Accept-Ranges": "bytes",
"cf-request-id": "03afb68a0900007f29ad07c200000001",
"Server": "cloudflare",
"CF-RAY": "5ac626bcdc137f29-CMB"
},
"JSON": {
"Data": {
"userId": 1,
"id": 2,
"title": "quis ut nam facilis et officia qui",
"completed": false
}
}
}
}
},
"FLDR": {
"ReplyId": "534f4150320000000bbb5323146300000400000000000000",
"RequestSendTime": 1593669682707,
"ReplyReceiptTime": 1593669682737,
"Reply": {
"Root": {
"HTTPResponseHeader": {
"X-Original-HTTP-Status-Line": "HTTP/1.1 200 OK",
"X-Original-HTTP-Status-Code": 200,
"Date": "Thu, 02 Jul 2020 06:01:17 GMT",
"Content-Type": "application/json; charset=utf-8",
"Content-Length": "84",
"Connection": "keep-alive",
"Set-Cookie": "__cfduid=dfbd2cc294d944ed4cfdf6b72a343f8dc1593669677; expires=Sat, 01-Aug-20 06:01:17 GMT; path=/; domain=.typicode.com; HttpOnly; SameSite=Lax",
"X-Powered-By": "Express",
"X-Ratelimit-Limit": "500",
"X-Ratelimit-Remaining": "499",
"X-Ratelimit-Reset": "1593684076",
"Vary": "Origin, Accept-Encoding",
"Access-Control-Allow-Credentials": "true",
"Cache-Control": "max-age=43200",
"Pragma": "no-cache",
"Expires": "-1",
"X-Content-Type-Options": "nosniff",
"Etag": "W/\"54-J3JtLgWuXjgj1OZdyAcKAqOaKHo\"",
"Via": "1.1 vegur",
"CF-Cache-Status": "HIT",
"Age": "8713",
"Accept-Ranges": "bytes",
"cf-request-id": "03afb68a0c00007f11da291200000001",
"Server": "cloudflare",
"CF-RAY": "5ac626bcea187f11-CMB"
},
"JSON": {
"Data": {
"userId": 1,
"id": 3,
"title": "fugiat veniam minus",
"completed": false
}
}
}
}
}
}
}
}
My question is how can I access the 3 JSON.Data elements and create a combined response. I know this is not a valid JSON and FLDR is a repeating key. Also this is not an array. How can I access these elements and create a combined response like this?
{
"result1": {
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
},
"result2": {
"userId": 1,
"id": 2,
"title": "quis ut nam facilis et officia qui",
"completed": false
},
"result3": {
"userId": 1,
"id": 3,
"title": "fugiat veniam minus",
"completed": false
}
}
Any help would be very much appreciated.

If you have a message tree containing that structure then you can access any part of it - regardless of whether it would be a valid JSON document.
Have you tried writing a normal FOR loop in ESQL to iterate over the occurrences of FLDR?
Note: this code is completely un-tested and probably contains syntax errors and defects...
DECLARE index INTEGER 1;
FOR refFLDR AS InputRoot.ComIbmGroupCompleteNode.Group.msg.Replies.FLDR[] DO
DECLARE fieldName 'Result' || index;
CREATE LASTCHILD OF OutputRoot.JSON.Data TYPE Name NAME fieldName FROM refFLDR;
SET index = index + 1;
END FOR;

Related

API Call from Nuxt3 SSR application to Strapi4 API endpoint shows servers host and not the requests host in header

I am sending a request from a Nuxt3 SSR app (test.example.com) to a custom strapi endpoint (test-backend.example.com)
I'm making the call from Nuxt3 like this from app.vue
<script setup>
import { useStore } from '#/stores/index'
let data = reactive({})
[data] = await Promise.all([
useFetch(`${useRuntimeConfig().API_URL}api/debug`),
])
store.setApiData(data.data)
</script>
To hit this custom strapi endpoint at /api/debug
module.exports = {
async debug(ctx, next) {
ctx.body = {
ctx: ctx,
reqOrigin: ctx.request.origin,
}
}
};
Reading the request headers using ctx.request.origin returns the backend host and not the frontend host.
"ctx": {
"request": {
"method": "GET",
"url": "/api/debug",
"header": {
"host": "test-backend.example.com",
"x-real-ip": "203.96.140.24",
"x-forwarded-for": "203.96.140.24",
"connection": "close",
"cache-control": "no-cache",
"postman-token": "946f9d5f-b9b6-4dc0-a52b-95fd84b81de8",
"user-agent": "PostmanRuntime/7.6.0",
"accept": "*/*",
"accept-encoding": "gzip, deflate"
}
},
"response": {
"status": 200,
"message": "OK",
"header": {
"content-security-policy": "connect-src 'self' https:;img-src 'self' data: blob:;media-src 'self' data: blob:;default-src 'self';base-uri 'self';block-all-mixed-content;font-src 'self' https: data:;frame-ancestors 'self';object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline'",
"x-dns-prefetch-control": "off",
"expect-ct": "max-age=0",
"x-frame-options": "SAMEORIGIN",
"strict-transport-security": "max-age=31536000; includeSubDomains",
"x-download-options": "noopen",
"x-content-type-options": "nosniff",
"x-permitted-cross-domain-policies": "none",
"referrer-policy": "no-referrer",
"vary": "Origin",
"content-type": "application/json; charset=utf-8",
"x-powered-by": "Strapi <strapi.io>"
}
},
"app": {
"subdomainOffset": 2,
"proxy": false,
"env": "production"
},
"originalUrl": "/api/debug",
"req": "<original node req>",
"res": "<original node res>",
"socket": "<original node socket>"
},
"reqOrigin": "http://test-backend.example.com"
Logging ctx on the backend shows that ctx.request.header.host is test-backend.example.com. I was expecting host to be text.example.com where the fetch originated from. Not the host to which the request was being sent.
How do I get the request host and not the servers host?

Why does changing maxResults cause the total number of results to change in Google API / Gmail API?

Why does changing the maxResults parameter cause the resultSizeEstimate to drastically change when calling gmail.users.messages.list()?
The Google API docs lists resultSizeEstimate as: Estimated total number of results.
... which means this final result set should not change just by altering the number of items returned per page.
Example A: maxResults: 1 ... resultSizeEstimate: 8
{
"config": {
"url": "https://www.googleapis.com/gmail/v1/users/me/messages?q=before%3A2021%2F1%2F9&maxResults=1",
"method": "GET",
"headers": {
"Accept-Encoding": "gzip",
"User-Agent": "google-api-nodejs-client/0.7.2 (gzip)",
"Authorization": "Bearer [snip]",
"Accept": "application/json"
},
"params": {
"q": "before:2021/1/9",
"maxResults": 1
},
"responseType": "json"
},
"data": {
"messages": [ ... ],
"nextPageToken": "14911817971227869758",
"resultSizeEstimate": 8
},
"headers": {
"alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"",
"cache-control": "private",
"connection": "close",
"content-encoding": "gzip",
"content-type": "application/json; charset=UTF-8",
"date": "Sun, 09 Jan 2022 12:59:48 GMT",
"server": "ESF",
"transfer-encoding": "chunked",
"vary": "Origin, X-Origin, Referer",
"x-content-type-options": "nosniff",
"x-frame-options": "SAMEORIGIN",
"x-xss-protection": "0"
},
"status": 200,
"statusText": "OK"
}
Example B: maxResults: 2 ... resultSizeEstimate: 12
{
"config": {
"url": "https://www.googleapis.com/gmail/v1/users/me/messages?q=before%3A2021%2F1%2F9&maxResults=2",
"method": "GET",
"headers": {
"Accept-Encoding": "gzip",
"User-Agent": "google-api-nodejs-client/0.7.2 (gzip)",
"Authorization": "Bearer [snip]",
"Accept": "application/json"
},
"params": {
"q": "before:2021/1/9",
"maxResults": 2
},
"responseType": "json"
},
"data": {
"messages": [ ... ],
"nextPageToken": "16903415066875011466",
"resultSizeEstimate": 12
},
"headers": {
"alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"",
"cache-control": "private",
"connection": "close",
"content-encoding": "gzip",
"content-type": "application/json; charset=UTF-8",
"date": "Sun, 09 Jan 2022 13:10:48 GMT",
"server": "ESF",
"transfer-encoding": "chunked",
"vary": "Origin, X-Origin, Referer",
"x-content-type-options": "nosniff",
"x-frame-options": "SAMEORIGIN",
"x-xss-protection": "0"
},
"status": 200,
"statusText": "OK"
}
Example C: maxResults: (not set) ... resultSizeEstimate: 412
{
"config": {
"url": "https://www.googleapis.com/gmail/v1/users/me/messages?q=before%3A2021%2F1%2F9",
"method": "GET",
"headers": {
"Accept-Encoding": "gzip",
"User-Agent": "google-api-nodejs-client/0.7.2 (gzip)",
"Authorization": "Bearer [snip]",
"Accept": "application/json"
},
"params": {
"q": "before:2021/1/9"
},
"responseType": "json"
},
"data": {
"messages": [ ... ],
"nextPageToken": "16942818266524948378",
"resultSizeEstimate": 412
},
"headers": {
"alt-svc": "h3=\":443\"; ma=2592000,h3-29=\":443\"; ma=2592000,h3-Q050=\":443\"; ma=2592000,h3-Q046=\":443\"; ma=2592000,h3-Q043=\":443\"; ma=2592000,quic=\":443\"; ma=2592000; v=\"46,43\"",
"cache-control": "private",
"connection": "close",
"content-encoding": "gzip",
"content-type": "application/json; charset=UTF-8",
"date": "Sun, 09 Jan 2022 13:09:05 GMT",
"server": "ESF",
"transfer-encoding": "chunked",
"vary": "Origin, X-Origin, Referer",
"x-content-type-options": "nosniff",
"x-frame-options": "SAMEORIGIN",
"x-xss-protection": "0"
},
"status": 200,
"statusText": "OK"
}
This was previously reported in Issue Tracker and was considered to be intended behavior by Google, since resultSizeEstimate is not expected to be exact; it's an "estimate":
the reason why resultSizeEstimate shows differents values is due to its estimation. As mentioned in the documentation resultSizeEstimate is just an estimated total number of results but not the exact number of results.
Reference:
users.messages.list method returns different amount of messages when using “maxResults” parameter

Error message from API when sending POST with Cypress

I try to send an API request with cy.request but there seems to be something wrong with the data format. My code looks as follows:
cy.request({
url: Cypress.env("RtmApiUrl") + "/test-plan/",
method: "POST",
headers: {
"Authorization": "Bearer " + Cypress.env('RtmApiToken'),
"content-type": "application/json",
body: {
"projectKey": "QAIR",
"summary": "API Test Regression",
"description": "Full regression",
"parentTestKey": "F-QAIR-TP-8",
"priority": {
"id": 3,
"name": "Medium"
},
"status": {
"id": 10005,
"name": "Backlog"
},
"includedTestCases": []
},
},
});
And the console output from Cypress Test Runner:
CypressError: `cy.request()` failed on:
https://rtm-api.hexygen.com/api/test-plan/
The response we received from your web server was:
> 400: Bad Request
This was considered a failure because the status code was not `2xx` or `3xx`.
If you do not want status codes to cause failures pass the option: `failOnStatusCode: false`
-----------------------------------------------------------
The request we sent was:
Method: POST
URL: https://rtm-api.hexygen.com/api/test-plan/
Headers: {
"Connection": "keep-alive",
"Authorization": "Bearer <some Token>",
"content-type": "application/json",
"body": {
"projectKey": "QAIR",
"summary": "API Test Regression",
"description": "Full regression",
"parentTestKey": "F-QAIR-TP-8",
"priority": {
"id": 3,
"name": "Medium"
},
"status": {
"id": 10005,
"name": "Backlog"
},
"includedTestCases": []
},
"user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.85 Safari/537.36",
"accept": "*/*",
"accept-encoding": "gzip, deflate",
"content-length": 0
}
-----------------------------------------------------------
The response we got was:
Status: 400 - Bad Request
Headers: {
"server": "Cowboy",
"connection": "keep-alive",
"x-content-type-options": "nosniff",
"x-xss-protection": "1; mode=block",
"cache-control": "no-cache, no-store, max-age=0, must-revalidate",
"pragma": "no-cache",
"expires": "0",
"strict-transport-security": "max-age=31536000 ; includeSubDomains",
"x-frame-options": "DENY",
"content-type": "application/json",
"content-length": "69",
"date": "Tue, 13 Jul 2021 07:32:36 GMT",
"via": "1.1 vegur"
}
Body: {
"errorMessages": [
"No content to map to Object due to end of input"
]
}
I already tried the same combination of header and body with Postman and curl and it worked. Is there something I missed?
Any help is appreciated. Thanks in advance.
Folks, I missed a bracket at the end of the headers block. So this was a real classic layer 8 issue...
cy.request({
url: Cypress.env("RtmApiUrl") + "/test-plan/",
method: "POST",
headers: {
"Authorization": "Bearer " + Cypress.env('RtmApiToken'),
"content-type": "application/json"
},
body: {
"projectKey": "QAIR",
"summary": "API Test Regression",
"description": "Full regression",
"parentTestKey": "F-QAIR-TP-8",
"priority": {
"id": 3,
"name": "Medium"
},
"status": {
"id": 10005,
"name": "Backlog"
},
"includedTestCases": []
},
},
});

Laravel echo server won't start

Laravel echo server keeps returning failed status on my server
Code
laravel-echo-server.json
{
"authHost": "http://example.com",
"authEndpoint": "/broadcasting/auth",
"clients": [
{
"appId": "311dr094tf98745ce",
"key": "fa43bffb3rth63f5ac9c386916ae28e6"
}
],
"database": "redis",
"databaseConfig": {
"redis": {},
"sqlite": {
"databasePath": "/database/laravel-echo-server.sqlite"
}
},
"devMode": false,
"host": null,
"port": "6001",
"protocol": "http",
"socketio": {},
"secureOptions": 67108864,
"sslCertPath": "",
"sslKeyPath": "",
"sslCertChainPath": "",
"sslPassphrase": "",
"subscribers": {
"http": true,
"redis": true
},
"apiOriginAllow": {
"allowCors": true,
"allowOrigin": "http://localhost:80",
"allowMethods": "GET, POST",
"allowHeaders": "Origin, Content-Type, X-Auth-Token, X-Requested-With, Accept, Authorization, X-CSRF-TOKEN, X-Socket-Id"
}
}
echo-pm2.json
{
"name": "echo",
"script": "laravel-echo-server.json",
"args": "start"
}
then i run pm2 start echo-pm2.json and status is online but when i visit my web page i keep getting
GET https://www.example.com:6001/socket.io/?EIO=3&transport=polling&t=NA2SNHk net::ERR_TIMED_OUT
Any idea?
"authHost": "http://example.com"
I have this set to the url of my localhost, not sure if it helps you
Solved
The problem was my url was set to https (GET https://www.example.com) while my actual address is running on http (GET http://www.example.com)
so that extra S... :)

Facebook analytics doesn't recognize platform

I have FB analytics configured for iOS and android app. It does recognize iOS platform when viewing events correctly. But for android it only qualifies it as android about 30% of all.
Here's how those events are shown in FB analytics debugging screen: ('inne wartości' stands for 'other')
I wonder how FB does the recognition? By advertising id? Read docs through but didn't find info about this anywhere.
Here's a FB response that gets recognized as android: (obfuscated few details):
{
"req": {
"method": "POST",
"url": "https://graph.facebook.com/v2.6/000000000/activities",
"data": {
"advertiser_id": "2e9ab235-84c0-4b22-8421-xxxxxxxxxxxxx",
"advertiser_tracking_enabled": 1,
"application_tracking_enabled": 1,
"bundle_id": "com.myapp",
"bundle_short_version": "1.7.0",
"event": "CUSTOM_APP_EVENTS",
"custom_events": [
{
"_appVersion": "1.7.0",
"_eventName": "App Launched",
"_logTime": 1476295031,
"fb_currency": "USD"
}
]
},
"headers": {
"user-agent": "Segment.io/1.0",
"content-type": "application/json"
}
},
"header": {
"access-control-allow-origin": "*",
"pragma": "no-cache",
"cache-control": "private, no-cache, no-store, must-revalidate",
"facebook-api-version": "v2.6",
"expires": "Sat, 01 Jan 2000 00:00:00 GMT",
"content-type": "text/javascript; charset=UTF-8",
"x-fb-trace-id": "BH4kXNYDDL+",
"x-fb-rev": "2617769",
"x-fb-debug": "eNcBCpuFfVirTkclVvZ0WeYh60r+2tBIqg6lKPCrWNtGASVULq6jrVwQxqYulMUyCI3ZaBhZRQ64xdxdXOQg2w==",
"date": "Wed, 12 Oct 2016 17:57:24 GMT",
"connection": "close",
"content-length": "16"
},
"status": 200,
"text": "{\"success\":true}"
}
And this one is not recognized as android:
{
"req": {
"method": "POST",
"url": "https://graph.facebook.com/v2.6/000000000000/activities",
"data": {
"advertiser_id": "88697a4d-f658-41d3-84db-xxxxxxxxxx",
"advertiser_tracking_enabled": 1,
"application_tracking_enabled": 1,
"bundle_id": "com.myapp",
"bundle_short_version": "1.7.0",
"event": "CUSTOM_APP_EVENTS",
"custom_events": [
{
"_appVersion": "1.7.0",
"_eventName": "App Launched",
"_logTime": 1476206487,
"fb_currency": "USD"
}
]
},
"headers": {
"user-agent": "Segment.io/1.0",
"content-type": "application/json"
}
},
"header": {
"access-control-allow-origin": "*",
"pragma": "no-cache",
"cache-control": "private, no-cache, no-store, must-revalidate",
"facebook-api-version": "v2.6",
"expires": "Sat, 01 Jan 2000 00:00:00 GMT",
"content-type": "text/javascript; charset=UTF-8",
"x-fb-trace-id": "AqASb9qsUSx",
"x-fb-rev": "2613995",
"x-fb-debug": "aDLUDoC+7vmlVY28UsEtusYgzdkmxK8qVrn4gCo29ovLw9Us27Gh/Iy1163dfTDF5rKg/JWiv3xsfq3hugijlg==",
"date": "Tue, 11 Oct 2016 17:21:37 GMT",
"connection": "close",
"content-length": "16"
},
"status": 200,
"text": "{\"success\":true}"
}
I can't see any interesting changes that that would point to an android platform.
Update
As advised by Ramkumar, I tried posting events with FB sdk and it indeed worked. I'd really like to keep using segment, so keeping this as solution is not possible in my app.
I wonder what's missing from the params that segment sends to FB. Is this because of session_id which is in there when using FB SDK but is absent in segment request? See gist with dump from adb logcat when using FB SDK
From your post, it looks like you are using segment.io to send events to our servers. If you use the FB SDK to send events you will not see this problem - could you please give that a try?

Resources