How to set an enable null url parameter in WSO2 ESB API Resource - api

When I create a API resource in WSO2 ESB with the uri-template as:
/getbypage_xml/{usid}/{level}/{pageNum}/{lineNum}/?zzjgbm={zzjgbm}
thus, we plan the zzjgbm parameter is enable null, like
/getbypage_xml/{usid}/{level}/{pageNum}/{lineNum}
However, WSO2 ESB response 202 status code, means unacceptable.
Furthermore, if I use the following template
/getbypage_xml?usid={usid}&level={level}&pageNum={pageNum}&lineNum={lineNum}&zzjgbm={zzjgbm}
When I invoke
/getbypage_xml?usid={usid}&level={level}&pageNum={pageNum}&lineNum={lineNum}
or I change the order of parameters, the result is the same.
So, How do I set a uri-template enable the parameter is enable, and at once, when the parameter is existed, I can use get-property('uri.var.zzjgbm') to get
the value of it.

Related

how to pass an attribute over ActiveMQ in Mule 4

We are migrating from Mule 3 to Mule 4 and in one of our functionalities we need to publish messages to a topic and downstream another mule component is consuming from the queue which is bridged to the topic.
Nothing special here .
To ensure we are able to trace the flow via logs we were sending a 'TrackingId' attribute while publishing messages to the topic ( Mule 3 )
message.setOutboundProperty("XYZ_TrackingID", flowVars['idFromUI']);
return payload;
However when I try the same in Mule 4 we get the following exception :
ERROR 2020-12-20 10:09:12,214 [[MuleRuntime].cpuIntensive.14: [mycomponent].my_Flow.CPU_INTENSIVE
#66024695] org.mule.runtime.core.internal.exception.OnErrorPropagateHandler:
Message : groovy.lang.MissingMethodException: No signature of method:
org.mule.runtime.api.el.BindingContextUtils$MessageWrapper.setOutboundProperty() is applicable for
argument types: (java.lang.String, org.mule.weave.v2.el.ByteArrayBasedCursorStream) values:
[XYZ_TrackingID, "1234567"].\nError type : (set debug level logging or '-
Dmule.verbose.exceptions=true' for
everything)\n********************************************************************************
Checked internet and it seems in Mule4 setting outbound properties is removed as per here
So how do I achieve the same in Mule 4 ?
Don't even try to do that for several reasons. For one message structure is different, so output properties doesn't exist anymore and that method doesn't even exists. On the other hand, in Mule 4 components like the Groovy component can only return a value and cannot change the event. They can not decide to what that value is going to be assigned. You can set the target in the configuration (payload or a variable) and not change the attributes. Note that variables in Mule 4 are referenced by var., not by flowVars. like in Mule 3 (ie vars.idFromUI).
There is a simpler way to set message properties in the Mule 4 JMS connector. Use the properties element and pass it an object with the properties.
For example it could be something like this:
<jms:publish config-ref="JMS_config" destination="${bridgeDestination}" destinationType="TOPIC">
<jms:message>
<jms:body>#["bridged_" ++ payload]</jms:body>
<jms:properties>#[{
XYZ_TrackingID: vars.idFromUI
}]</jms:properties>
</jms:message>
</jms:publish>
It is in the documentation: https://docs.mulesoft.com/jms-connector/1.0/jms-publish#setting-user-properties. I adapted my example from there.
I am not sure if Correlation Id serves the purpose of a tracking ID for your scenario. But you can pass a CID as below. It's there in the mule documentation.
https://docs.mulesoft.com/jms-connector/1.7/jms-publish
<jms:publish config-ref="JMS_config" sendCorrelationId="ALWAYS" destination="#[attributes.headers.replyTo.destination]">
<jms:message correlationId="#[attributes.headers.correlationId]"/>
</jms:publish>
If your priority is to customise the Tracking ID you want to publish, then try passing below format. The key names may differ as per your use case.
<jms:publish config-ref="JMS_config" destination="${bridgeDestination}" destinationType="TOPIC">
<jms:message>
<jms:body>#["bridged_" ++ payload]</jms:body>
<jms:properties>#[{
AUTH_TYPE: 'jwt',
AUTH_TOKEN: attributes.queryParams.token
}]</jms:properties>
</jms:message>
</jms:publish>
In the above the expression attributes.queryParams.token is basically trying to access a token query parameters which is passed to JMS as a property AUTH_TOKEN key-name , consumed by the API through a HTTP Listener or Requestor earlier.
However, attributes.headers.correlationId is a header. Both queryParams and headers are part of attributes in Mule 4.

Apache Camel : How to setHeader value as null

How do we set header value as null in apache camel exchange message from a processor. I am delivering message to a RabbitMQ exchange and it expects one of the header value to be set as null.
I have tried below approaches from my processor just before delivering the message
exchange.getOut().setHeader("headername","");
But this sets up an empty string to the header.
I also tried
exchange.getOut().setHeader("headername",null);
But in this case the header itself is not visible.
Please let me know if any more information is needed.
The camel-rabbitmq component does not support headers with null values. They are filtered out in the source code.
https://github.com/apache/camel/blob/fab7a58e56e128286f327aba16c09553b26cb846/components/camel-rabbitmq/src/main/java/org/apache/camel/component/rabbitmq/RabbitMQMessageConverter.java#L171
Its a odd requirement/use-case to have to send a null value. And hence why I ask you to explain this more. There must be very good reason to consider changing Camel.
Camel has implemented a fix for this which is backported to the 2.22.1 and 2.21.3 versions and will be available there onwards. For those who are interested to know how this can be achieved, please have a look at Camel-12654 Jira issue.
camel-rabbitmq component and endpoint now support a URI option allowNullHeaders which is false by default. If you want to send custom headers with value as null, set its value to true. For example
from("rabbitmq://hostname:port/exchangeName?allowNullHeaders=true").....
This will configure camel-rabbitmq converter to set headers with null values. Now from your processor, you can do something like this
exchange.getOut().setHeader("headername",null);
This will instruct camel-rabbitmq producer, not to skip and headers which have null values.

How to extract sessionId from Citrus HttpRequest

I tried to test the a set of REST services using Citrus Java DSL. After authentication the services expect the same, valid session id of the first request.
On the server side I can see, that there exists a random session-id, but at the second request, the session-id is null.
I've tried to set handleCookies to true in the endpoint configuration and tried to extract some header information (set-cookie) but without success. The EndpointConfiguration is reused during the different requests.
CitrusEndpoints.http()
.client()
.handleCookies(true)
How can I force the Endpoint to reuse the negotiated session-id or how can I extract it from the request / response?
Thanks in advance for any ideas and hints.
The response to your 1st request should have a header set
Set-Cookie: JSESSIONID=ABCDEFG;path=/api/foo
You can extract this information in your receive operation
http()
.client(todoClient)
.receive()
.response(HttpStatus.OK)
.extractFromHeader("Set-Cookie", "cookie")
.payload("{ \"foo\": \"bar\" }");
After that we have to post process the new ${cookie} value in order to extract the actual session id name and value into a new variable ${sessionId}.
createVariable("sessionId", "citrus:substringBefore(${cookie}, ';')");
Now we have a variable ${sessionId} that only contains the name and value of the session id - in our example this is JSESSIONID=ABCDEFG.
In further requests you can use the variable in order to set proper Cookie header information
http()
.client(todoClient)
.send()
.get("/api/foo")
.header("Cookie", "${sessionId}")
.accept(ContentType.APPLICATION_JSON.getMimeType());

WSO2 api manager always expect query parameter issue in case query and path parameter?

Does anyone know how to use WSO2 api manager to specify all query parameters as optional through URL pattern specification in WSO2 API Manager UI(Paath Params also present in the same URI)? for example, I have a API which will be registered in WSO2 api manager , and its uri is 'search//?type="xx"&status="yy"', currently both of these 2 query parameters (type & status) are optional and is pathparam.
I specified URL Pattern "search/{stationcode}*". Now I am calling with path param only, it gives Error "No matching resource found in the API for the given request".
I call "search/TAMK", it is not working. But if I use "search/TAMK?" or "search/TAMK*" or "search/TAMK*", it works just fine.
I tried to use "search/{stationcode}/*", but still it did not solve the issue. It is always expecting one character for queryparam. Can any one please help me to solve this. Without query parameter it should work, right?
I would suggest you to use the new API Manager (1.9) and try the following.
Create an API with the backend URL of
http://...../search
when you define the URL patterns you can define the following pattern
/{stationcode}*
and you can add 'type' and 'status' as optional parameters in the design view of the API creation page. You can choose the parameter type as 'query' and Required as 'False'

correct Http Request header field to pass some flags

Can someone suggest correct HTTP request header field to use to pass some flag using Rest API call. Can I use 'expect' request element for this use case?
Use Case:
Read client request header-->read the flag(say value is 1 or 0) --> do task A for value=1 or task B for value=0
No, that is not an appropriate use of the Expect header. Depending on your exact use case, you can use (a) a custom header, (b) a query parameter, or (c) embed the flag in the entity being sent to the server. Without more information, it's impossible to say which is most appropriate for your situation.