MuleSoft AnypointStudio - mule

I have scripts:
<set-variable value="#[attributes.headers['Authorization']]" doc:name="apikey" doc:id="69f6509e-8c0c-4832-854e-d7c07675cb49" variableName="apiKey"/>
<http:request method="GET" doc:name="Request" doc:id="86d51474-a71e-438c-bb24-59471424c4f9" config-ref="HTTP_Request_configuration">
<http:headers ><![CDATA[#[output application/java
---
{
Authorization : vars.apiKey
}]]]></http:headers>
</http:request>
and in the postman I have in Headers Key: Authorization and value the apiKey.
After call in Postman I have this message in AS:
HTTP GET on resource failed: bad request (400)
Why I have bad request?

anypThe developers using the library should be able to disable certain fields in the JSON output. The list of disabled fields should be configurable. The flows responsible for logging in the JSON structure should be able to read the configuration and should not log those fields. This feature will be required in higher environments in case the team decides to disable certain fields in UAT and Prod.

Related

How to customise an error message generated by the Anypoint API manager standard policy?

There is an API running on the CloudHub (Mule 4.4) and protected with the standard SLA Rate Limit policy.
We have a requirement to provide a custom error message body instead of the default one generated by the policy when authentication fails.
The default error body returned by the policy looks like this:
{
"error": "Invalid client id or secret"
}
When I run the application in debugger in Studio, it is intercepting the exception and I can see that the error type produced by the policy is CLIENT-ID-ENFORCEMENT:INVALID_CREDENTIALS.
This as well indicates that the exception is reaching the Mule application itself. So, it must be a way to override the default handler with the custom one.
First, I've tried adding the handler for error type to HTTP request processing flow beside the other API Kit errors. It did not intercept the error.
Then, I've defined a separate error handler for the error type and set it as a "Default Error Handler" in the global configuration.
<configuration doc:name="Configuration" doc:id="7a7e22cd-2ee7-42ee-af15-eaf2693d72d9" defaultErrorHandler-ref="apiErrorHandler" />
<error-handler name="apiErrorHandler">
<on-error-propagate enableNotifications="true" logException="true" type="CLIENT-ID-ENFORCEMENT:*">
<ee:transform xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{message: "Unauthorised"}]]></ee:set-payload>
</ee:message>
</on-error-propagate>
</error-handler>
This didn't work as well.
Can you pls advise the right way to customise the error messages returned the standard SLA policy?
To be clear, I'm well aware that it is possible to code your own custom policy. But the intention is to keep the standard one and just customise the response for some error types.
This is not currently possible. Policies have to handle their own errors, they can not be intercepted in the flow.

How to get HTTP Status code from Mule application

I am using Anypoint Studio 6.1 and Mule 3.8.1 and have a flow that calls MongoDB. I want to see how to get the HTTP status so I can configure my exception handling. When I disconnect MongoDB and run the Mule workflow it fails as expected, but the HTTP status is returned as null when I try this expression message.inboundProperties['http.status'] and the exception message code is -1, but when I play the error through to the end of the workflow the status shows as 500 in Postman.
How can I get the HTTP status?
Thanks
message.inboundProperties['http.status'] will give the http.status code when a HTTP Request invocation is made within the flow. If the flow is trying to invoke DB, then you may need to have a catch exception strategy inside the error handling of the flow to catch the desired exception. If the exception is matched, you can set the http.status and exception payload to be sent to the client end.
If you are using APIKit Router then you can use the following code:
<apikit:mapping-exception-strategy name="apiKitGlobalExceptionMapping">
<apikit:mapping statusCode="500">
<apikit:exception value="java.lang.Exception"/>
<set-property propertyName="Content-Type" value="application/json" doc:name="Property" />
<set-payload value="{ "message": "Internal server error" }" doc:name="Set Payload" />
</apikit:mapping>
For more details you can check here

Applying custom-security-filter to multiple flows in Mule configuration

I have a mule application where there is login flow. The flow contains an http endpoint which takes user/password as form post parameter. Once the user/password is matched we create an auth token and store it in the database. And, then later send it in the login api response.
Now, I have multiple other flows in the same mule configuration file. Each of them represents a specific endpoint/api. Now I want to apply a custom-security-filter to all the flows apart from login endpoint flow.
One way is to keep adding the custom-security-filter component in each of the flows. I don't want to do that. Rather I want to mention it once that this security filter is applicable to all the flows apart from login flow.
Is that possible in Mule?
You could use a choice and only apply authorization filtering if the request is not for your login endpoint. e.g.
<choice doc:name="Choice">
<when expression="[Is this a login request?]">
<!-- Do nothing -->
</when>
<otherwise>
<!-- User must be authorized -->
<mule-ss:authorization-filter doc:name="Authorize"
requiredAuthorities="ROLE_REQUIRED_AUTH" />
</otherwise>
</choice>

Cannot consume AMQP messages using the Mule Requester when triggered via HTTP requests

I currently have a flow that is triggered using a specific HTTP request path, which should then make a request to a RabbitMQ server hosted locally. However, I cannot seem to see the output of the Mule Requester module; I see the HTTP request instead. Here is the gist of my current flow:
<flow name="get-queue-messages-manually" doc:name="get-queue-messages-manually" initialState="started">
<http:inbound-endpoint exchange-pattern="request-response" host="localhost" port="8081" path="getqueue" contentType="text/plain" doc:name="HTTP"/>
<mulerequester:request returnClass="java.io.String" config-ref="Mule_Requester" resource="amqp://myexchange" doc:name="Mule Requester"/>
<logger level="INFO" doc:name="Logger"/>
<echo-component doc:name="Echo"/>
</flow>
I am able to send messages to the exchange and have them be enqueued without a problem, but I cannot seem to extract any. As I understand it, the Mule Requester module allows one to make a request for resources at any point in a flow; I believe I also read that it causes an asynchronous operation, which may be the problem here. In that case, how would I be able to retrieve the queued message, and not the HTTP request?
I have also looked into the Mulesoft AMQP documentation, and though the URI specs mention the format amdq://{exchange}/amqp-queue.{queue}, it doesn't seem that the Mule Requester accepts this, as it only seems to take exchange names only. The console logs do contain a line which states that a private queue has been created, and from a little bit of searching, is an indication that a queue name is not specified? Not quite sure how that can be done in this component, however.
Note that the reason I have the HTTP request element first is that I do not want the flow firing off the moment a message is received, and therefore the HTTP component is used to ensure that the messages are read only when requested. Without the HTTP component, everything is swell.
Thanks in advance for any pointers on this issue - been struggling with this for some time now.
Well, now I feel silly. This can indeed be done using the Mule Requester. The format for the resource field should be: amqp://amqp-queue.{queueName}. Once I used the queue name instead of the exchange, I finally see the message in the payload. Hope this helps others! (There seems to be a restriction with accepting own answers; I'll accept this answer once that is lifted)

Timeout error in Until Successful

We have a flow where we have implemented a soap client to send soap messages to Service provider.
We need to retry the service call for 3 times if it fails. So we have used HTTP Outbound Endpoint inside until successful scope.
It is doing retry as expected, but in case of success scenario, even if we get the response from the service, we are observing a time out error as below.
[DispatchThread: 1] org.apache.cxf.endpoint.ClientImpl: Timed out waiting for response to operation {http://support.cxf.module.mule.org/}invoke.
Observation:
I have removed the until successfully and had the HTTP Outbound endpoint directly, in this case there is no timeout error.
I later tried having until successfully and had an acknowledge expression to accept the response, still the same time out response.
failureExpression="#[message.inboundProperties['http.status'] != 200]" ackExpression="#[message.correlationId]"
Could any one please suggest, how to configure the until successful for accepting the response and not throwing time out error.
The ackExpression has nothing to do with "accept the response", it's for generating a value that will be used as the new message payload after the flow has passed the current event to the until-successful message processor.
Try setting a response-timeout on your outbound HTTP endpoint to see if it helps: maybe the default timeout used in the context of the until-successful scope is too big and creates this issue.
I found a solution for this.
Earlier I had only HttpOutbound endpoint inside Until-Successful and I am facing Timeout issue.
Now I included Soap component also inside Until-successful scope it is working fine.
Since until successful allow us to have only one component inside, I have wrapped soap component and HttpOutbound endpoint iside a processor chain.
<until-successful objectStore-ref="objectStore"
maxRetries="3" secondsBetweenRetries="2" deadLetterQueue-ref="xxxx"
doc:name="UntilSuccessfulService" >
<processor-chain doc:name="Processor Chain">
<cxf:jaxws-client operation="Request1" serviceClass="xxxxxxx" enableMuleSoapHeaders="true" doc:name="SOAP"/>
<http:outbound-endpoint exchange-pattern="request-response" method="POST" doc:name="HTTP" host="localhost" path="cService" port="xxxx" connector-ref="HTTP_HTTPS"/>
</processor-chain>
</until-successful>
Thanks David and all for your responses.