Mulesoft download zip file via APIKit Router - anypoint-studio

I am having trouble with browser showing save/download prompt for zip file on http endpoint wiht APIKit Router.
I have a sub flow that gets S3 object and sets payload to #[message.payload.getObjectContent] which works fine with http listener going straight to flow, but if using APIKit router browser returns nothing.
I think it might have something to do with my raml.
/GetPackage
get:
responses:
200:
description: Success
body:
200:
application/zip
I also read something about...
Content-Disposition: attachment;filename=file.zip
Some help/direction would be much appreciated
Tnx!

Figured out a solution. It wasn't enough just having application/zip in RAML.
Needed to set two properties in Flow (with Property component):
Content-Disposition: attachment;filename=filename.zip
Content-Type: application/zip
Configuration XML that I used:
<set-property propertyName="Content-Disposition" value="attachment;filename=filename.zip" doc:name="Content-Disposition"/>
<set-property propertyName="Content-Type" value="application/zip" doc:name="Content-Type"/>

Related

How to send a csv file upload request from Jmeter

I have a request in which the user uploads a csv file and then the file is validated based on a few criteria. I have captured the request from blazemeter (refer the screenshot of the request captured)
But its failing when I hit this using Jmeter. (I am trying to send the exact same request along with the file attached in the "File Upload" option).
I've checked in Developer's tool and the actually request sent is :
------WebKitFormBoundaryBk6Qf9RTb4vFvkKw
Content-Disposition: form-data; name="file"; filename="EmployeeCSV.csv"
Content-Type: application/vnd.ms-excel
------WebKitFormBoundaryBk6Qf9RTb4vFvkKw
Content-Disposition: form-data; name="fileExtension"
csv
------WebKitFormBoundaryBk6Qf9RTb4vFvkKw
Content-Disposition: form-data; name="organisationId"
ZUVMbzBudFM5T2Y2bVNtUHFWWmZCRmJhWFZFTkJGMEVuNk9WKzBsQ2dUWT0=
------WebKitFormBoundaryBk6Qf9RTb4vFvkKw
Content-Disposition: form-data; name="schemeIdSf"
d0dqVXd5b25wVFArWTFkc3l0dUV5R3V0STlqZ2owVE5FVCtxVGhEZUxESmJydVAzYjBLSkxqdWxLMmQva29WSg==
------WebKitFormBoundaryBk6Qf9RTb4vFvkKw
Content-Disposition: form-data; name="fileGUID"
1612429088749
------WebKitFormBoundaryBk6Qf9RTb4vFvkKw--
Can someone help me out on how can I send the above mentioned request in Jmeter?
The HTTP Request sampler setup doesn't seem correct to me, you need to define the file(s) you're uploading under "Files Upload" tab like:
I would recommend re-recording your file upload event using JMeter's HTTP(S) Test Script Recorder, JMeter should be smart enough to generate proper HTTP Request sampler and HTTP Header Manager configuration.
Just make sure to copy your EmployeeCSV.csv to "bin" folder of your JMeter installation during recording, only this way JMeter will be able to properly capture and build the request. More information: Recording File Uploads with JMeter

Mule - Anypoint studio freezes on http response returning a pdf

I'm new to Mule and Anypoint studio.
I'm integrating docusign in mulesoft. I'm having a weird issue.
One of the api of docusingn '/v2/accounts/{accountId}/envelopes/{envelopeId}/documents/{documentId}' will return a pdf doucment as the response.
However Mulesoft hangs and doesnt respond properly. The same command when run using curl command it works fine. Any help here pls
curl -i -H 'X-DocuSign-Authentication: { "Username":"asdf#asdf.com.au", "Password": "asdf#123", "IntegratorKey":"a59asdfssadfdsc0af6237a37f"}' https://demo.docusign.net/restapi/v2/accounts/c62afb10-455a-4f48-87cd-eb0f0949c9bd/envelopes/c8ed9a1d-dbb6-458f-b674-b8ecff9824b5/documents/combined > /data/t.pdf
Above command works fine. But not this one
<flow name="docusignGet">
<flow-ref name="docusignInit" doc:name="docusignInit"/>
<flow-ref name="docusignCredentials" doc:name="docusignCredentials"/>
<http:request config-ref="Docusign_HTTP_Request_Configuration" path="/v2/accounts/{accountId}/envelopes/{envelopeId}/documents/{documentId}" method="GET" doc:name="HTTP">
<http:request-builder>
<http:uri-param paramName="accountId" value="#[sessionVars.docuSignAccountId]"/>
<http:uri-param paramName="envelopeId" value="7cadba0e-5fc6-4858-b0ea-c6eb13847a22"/>
<http:uri-param paramName="documentId" value="0"/>
</http:request-builder>
</http:request>
</flow>
I added Object to Byte-Array transformer too. Same result.
Any help pls
Thanks in advance
UPDATE
I found out the freeze issue. logging was root cause for the freeze.
So i disabled all the logs. now its not freezing, however the result is not obtained. Any help here ..
The HTTP response will be some thing like this (obtained from curl)
< HTTP/1.1 200 OK
< Cache-Control: no-cache
< Content-Length: 175512
< Content-Type: application/pdf
< X-RateLimit-Reset: 1527051600
< X-RateLimit-Limit: 1000
< X-RateLimit-Remaining: 1000
< X-DocuSign-TraceToken: f0bfe1b3-674d-42f0-a410-1641e6f7cdc7
< Content-Disposition: file; filename="Testing-_Please_sign_and_report.pdf"; documentid="combined"; filename*=UTF-8''Testing-_Please_sign_and_report.pdf
< Date: Wed, 23 May 2018 04:04:54 GMT
< Strict-Transport-Security: max-age=31536000; includeSubDomains
<
{ [16384 bytes data]
9 171k 9 16384 0 0 8192 0 0:00:21 0:00:02 0:00:19 6097* schannel: client wants to read 102400 bytes
* schannel: encrypted data buffer: offset 1360 length 103424
* schannel: encrypted data got 46871
* schannel: encrypted data buffer: offset 48231 length 103424
* schannel: decrypted data length: 409
either its returning a file by parts. What i want is this HTTP connector to act as proxy and return the same payload back to the caller after streaming all the bytes. Let the caller then do what ever it wants (in my case its a Django server).
However i'm having an error.
No serializer found for class org.glassfish.grizzly.utils.BufferInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS) )
I tried to add Object to ByteArray transformer after HTTP. But it didnt work .
I want the below command to work the way it works for docusign
curl -i -v -X GET http://localhost:8081/api/docusign_get > tt.pdf
Thanks in advance
Check your HTTP Request/Response is being generated correctly.
In your log4j2.xml file change, HttpMessageLogger to DEBUG level
<!-- Http Logger shows wire traffic on DEBUG -->
<AsyncLogger name="org.mule.module.http.internal.HttpMessageLogger" level="DEBUG"/>
You should be able to see the request/response in the console output, compare it to the curl session, add -v to the curl command to get the request and response.
NB I prefer to use Fiddler for this, as amongst other things, it is better at handling binary data.
Got it working.
It turned out to be RAML issue. The RAML file what i had was having this
/docusign_get:
get:
queryParameters:
responses:
200:
body:
application/json:
where as the correct is
/docusign_get:
get:
queryParameters:
responses:
200:
body:
application/pdf:
didnt imagine that Mule is so dependent of RAML file

Which versions of graphql-js and graphql-relay-js are required to support file upload via the Relay Mutation getFiles function?

I am currently trying to upload a file via Relay but I am receiving a syntax error from our GraphQL server implementation whenever I try to execute the mutation. I am currently using graphql-js-0.4.18 and graphql-relay-js-0.3.6. I am assuming that one (or both) of these package versions is the culprit. Does anyone know which minimum versions of these packages I would need to properly support file uploads? I am forced to port these packages to a different language which is why I am concerned about the minimum versions required. Thanks in advance!
Mutation Request
------WebKitFormBoundaryKwC5gIWABIRSXoeW
Content-Disposition: form-data; name="query"
mutation UploadFileMutation($input_0:CTI_Mutation_UploadFileInput!) {
uploadFile(input:$input_0) {
clientMutationId,
...F0
}
}
fragment F0 on CTI_Mutation_UploadFilePayload {
success
}
------WebKitFormBoundaryKwC5gIWABIRSXoeW
Content-Disposition: form-data; name="variables"
{"input_0":{"fileName":"test_file_upload.txt","clientMutationId":"3"}}
------WebKitFormBoundaryKwC5gIWABIRSXoeW
Content-Disposition: form-data; name="file"; filename="test_file_upload.txt"
Content-Type: text/plain
------WebKitFormBoundaryKwC5gIWABIRSXoeW--
Mutation Response
{"errors":[{"message":"Syntax Error GraphQL request (1:2) Invalid number, expected digit but got: \"-\".\n\n1: ------WebKitFormBoundaryKwC5gIWABIRSXoeW\n ^\n2: Content-Disposition: form-data; name=\"query\"\n","locations":[{"column":2,"line":1}]}]}
It turns out that this was not a GraphQL / Relay issue at all. I simply had to add support to my WebServer for multipart/form=data processing and now I am able to successfully upload files.

Mule-ESB HTTP redirect does not work when followRedirects=false

I have a simple flow that didn’t work for mule. In my setup, I am listening on one port for HTTP traffic and forwarding traffic on another port which I believe is the most typical ESB use case. The proxy/gateway flow works except when the target application issues redirect. Does anyone know of any tricks to address this? Note that I can not use the "HTTP-Proxy pattern" from mule as I intend to extend this flow for more complex use case.
Mule Flow
<http:listener-config name=“HTTP_IN" host=“localhost" port="12344" doc:name=“IN_EP" />
<http:request-config name=“HTTP_OUT" host=“localhost" port="8380" doc:name=“OUT_EP"/>
<flow name="test2Flow2">
<http:listener config-ref=“HTTP_IN" path="*" doc:name="IN"/>
<logger level="INFO" doc:name="Request Logger"/>
<http:request config-ref=“HTTP_OUT" path="#[message.inboundProperties.'http.request.path']" method="#[message.inboundProperties.'http.method']" doc:name="OUT" followRedirects="false" />
<response>
<logger level="INFO" doc:name="Response Logger"/>
</response>
</flow>
Case 1: followRedirects=true (default)
In this case mule gets HTTP 302 from target end point and it internally navigates to the redirected page and serves the page to the client. This is great if I am using Mule as a gateway to some web services. However for HTTP traffic from browser, if we allow this to happen, all the relative URLs will break from the rendered page.
Case 2: followRedirects=false
In this case mule gets HTTP 302 from target end point and it drops the response after logging it. Mule just send HTTP 200 on the browser with empty HTML page. See logs below for case 2. I like to send the HTTP 302 response to the end-user.
Request Logged (Case 2)
INFO 2015-10-01 13:01:48,333 [[test2].APP_A_IN.worker.01] org.mule.api.processor.LoggerMessageProcessor:
org.mule.DefaultMuleMessage
{
Message properties:
INVOCATION scoped properties:
INBOUND scoped properties:
accept=text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
accept-encoding=gzip, deflate, sdch
accept-language=en-US,en;q=0.8
cache-control=max-age=0
connection=keep-alive
dnt=1
host=localhost:12344
http.listener.path=/*
http.method=GET
http.query.params=ParameterMap{[]}
http.query.string=
http.relative.path=/app_a
http.remote.address=/127.0.0.1:53372
http.request.path=/app_a
http.request.uri=/app_a
http.scheme=http
http.uri.params=ParameterMap{[]}
http.version=HTTP/1.1
upgrade-insecure-requests=1
user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
x-firephp-version=0.0.6
OUTBOUND scoped properties:
SESSION scoped properties:
}
Response Logged (Case 2)
INFO 2015-10-01 13:01:48,420 [[test2].APP_A_IN.worker.01] org.mule.api.processor.LoggerMessageProcessor:
org.mule.DefaultMuleMessage
{
Message properties:
INVOCATION scoped properties:
INBOUND scoped properties:
date=Thu, 01 Oct 2015 17:01:48 GMT
http.reason=Moved Temporarily
http.status=302
location=http://localhost:8380/app_a/
server=Apache-Coyote/1.1
transfer-encoding=chunked
OUTBOUND scoped properties:
SESSION scoped properties:
}
I think the problem is that you are not copying the properties from the requester to the listener's response. I suggest using a copy-properties element right after the requester. The inbound properties will be lost otherwise: you need them as outbound at that point.
Some properties like the http.status might need to be mapped to headers explicitly using a response-builder though.
HTH

Why mule's http:rest-service-component does not support PUT method?

I want to call rest service in flow, at first, I use http:outbound-endpoint as following:
<http:outbound-endpoint exchange-pattern="request-response"
address="http://localhost:7081#[message.inboundProperties['http.request']]" doc:name="Call Lower REST" method="PUT">
EDIT:
Request:
PUT http://localhost:8080/ae2/app/add?nonce=23ddd&name=app1&timestamp=123332&user=foo HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/xml
Content-Length: 0
Host: localhost:8080
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
It throws an exception:
Root Exception stack trace:
java.lang.Exception: The HTTP method or content type is unsupported!
at org.mule.transport.http.transformers.HttpRequestBodyToParamMap.transformMessage(HttpRequestBodyToParamMap.java:56)
at org.mule.transformer.AbstractMessageTransformer.transform(AbstractMessageTransformer.java:145)
at org.mule.transformer.AbstractMessageTransformer.transform(AbstractMessageTransformer.java:93)
Then I read some document, and I found the http:rest-service-component, it can call the backend rest service, but it does not support PUT method, the document says, and I tried.
So, Why this component does not support PUT? Or is there anthoer component can be used?
It is not being thrown from the outbound endpoint. Somewhere in your flow you are using:
<http:body-to-parameter-map-transformer doc:name="Body to Parameter Map" />
In you config here: mule's http-proxy cannot be used in flow? - you are using it a few lines down after your first logger.
This transformer will return the message properties as a hash map of name-value pairs. This transformer handles GET and POST with application/x-www-form-urlencoded content type. This transformer does not support PUT or DELETE.
You are PUTing XML so theres no need to use this transformer.
If you still need it for POST, then you can wrap this transformer in a choice so it only gets used for GET and POST. For example:
<choice doc:name="Choice">
<when expression="#[message.inboundProperties['http.method'] == 'POST']">
<http:body-to-parameter-map-transformer doc:name="Body to Parameter Map" />
...
</when>
</choice>
Otherwise remove it.