Redirect link in Mule 4 - redirect

I have to create an endpoint and when it is called, it redirects me to a specific web page, how can I do this?
I investigated about the HTTP Response Builder, but it tells me that it is "Deprecated" and when I add it in the XML, Mule does not recognize it.

Just instruct the HTTP Listener to return a 302 status and a header Location with the new URL. That's how an HTTP redirection works.
Example:
<http:listener doc:name="Listener"config-ref="HTTP_Listener_config" path="/redirectme">
<http:response statusCode="302">
<http:headers ><![CDATA[
output application/java
---
{
"Location" : "http://somehost.com/some/other/url"
}
]]>
</http:headers>
</http:response>
</http:listener>
If you need to make it dynamic just replace by variables in the expressions and set the variables inside of the flow.
Example:
<http:response statusCode="#[vars.httpStatus default 200]">
...
{
"Location" : vars.someURL
}

Related

Can't add new attributes to the HTTP headers along with the existing request headers

My goal is to add caller and request-id to the HTTP headers.
However, I can't seem to get it right. Those are not added along with the existing headers.
What's wrong?
{
"headers": {
#foreach($header in $input.params().header.keySet())
"$header": "$util.escapeJavaScript($input.params().header.get($header))" #if($foreach.hasNext),#end
#end
"caller" : "$context.identity.caller",
"request-id" : "$context.requestId"
}
Are you trying to add it to your Integration Request headers? If so, this is not configured in the body mapping template. The mapping template is just for configuring the payload to the integration.
You should add a header named caller (or whatever you want) and set the mapping expression value to $context.identity.caller. Then API GW will send that value in the header to your integration.

Parameter based redirect in nginx

I have http requests such as the one below being sent to an nginx server:
GET /app/handler?id=1234&param1=cbd&param2=234
Now, I want to rewrite the request to a different handler depending on the id param in the request. eg. redirect to handler_even for even ids and handler_odd for odd ids. This is shown below:
GET /app/handler?id=1234&param1=cbd&param2=234 => /app/handler_even?id=1234&param1=cbd&param2=234
GET /app/handler?id=123&param1=cbd&param2=234 => /app/handler_odd?id=123&param1=cbd&param2=234
I can do the rewrite using proxy_pass, but I'm unsure how to redirect using the id parameter value. Any idea how I could go about this? Would using "if" be the best way to go about this?
Any pointers would be useful
Rather than use an if directive, you could use a map. To internally rewrite the URI use:
map $arg_id $handler {
default /app/handler_even;
~[13579]$ /app/handler_odd;
}
server {
...
location = /app/handler {
rewrite ^ $handler last;
}
...
}
The map should be located at the same level as your server directive (as shown above), i.e. within the http container.
See this document for details.

How to send JSONP request using int-http:outbound-gateway in Spring Integration?

I am trying to convert a request working as in below call to Spring Integration Async call
function sendToSomething(){
var formattedDate = $.datepicker.formatDate('yy-mm-dd', new Date());
var emailAddress = $("#prefferedemail").val();
// Call to Send email address to something
$.ajax(
{
global: false,
type : "POST",
url : "http://xyz.something.com/pub/rf?_ri_=X0Gzc2X"
+ "& EMAIL_PERMISSION_STATUS_=I&email_address_=" + emailAddress + "&SOURCE_CODE=CPK&EMAIL_PREF_CH_DT=" + formattedDate,
dataType : "jsonp",
}
);
}
}
Key point is its supposed to use http and jsonp
I am trying to configure something like below
<int:gateway id="asyncSomeIntService"
service-interface="com.staples.eoe.integration.AsyncSomeService" default-request-channel="someRequestChannel" />
<int-http:outbound-gateway url="http://xyz.something.com/pub/rf?_ri_=X0Gzc2X "&EMAIL_PERMISSION_STATUS_=I&email_address_={emailAddress}&SOURCE_CODE=CPK&EMAIL_PREF_CH_DT={formattedDate}"
http-method="POST" expected-response-type="java.lang.String" request-factory="requestFactory"
request-channel="someRequestChannel" reply-channel="someReplyChannel">
<int-http:uri-variable name="emailAddress" expression="headers.emailAddress" />
<int-http:uri-variable name="formattedDate" expression="headers.formattedDate" />
</int-http:outbound-gateway>
<bean id="requestFactory" class="org.springframework.http.client.SimpleClientHttpRequestFactory">
<property name="connectTimeout" value="5000" />
<property name="readTimeout" value="5000" />
</bean>
And the idea was to call from Server layer as below
Message<String> message = MessageBuilder
.withPayload("something")
.setHeader("formattedDate", "15-01-27")
.setHeader("emailAddress", customer.getPreferredEmail())
.build();
The Request submits the URL fine,
However I get part of response are as below
"It is likely that your input did not pass our validation process."
Is there a way to send JSONP request like in above ajax call using Spring Integration?
Good question though!
However if we go to the jQuery docs, we'll see this description for the dataType : "jsonp":
If jsonp is specified, $.ajax() will automatically append a query string parameter of (by default) callback=? to the URL. The jsonp and jsonpCallback properties of the settings passed to $.ajax() can be used to specify, respectively, the name of the query string parameter and the name of the JSONP callback function. The server should return valid JavaScript that passes the JSON response into the callback function. $.ajax() will execute the returned JavaScript, calling the JSONP callback function, before passing the JSON object contained in the response to the $.ajax() success handler.
So, since Spring Integration HTTP support isn't jQuery-based framework, we should go with standard JSONP rules and add that callback=? parameter to the url.
But... since we are in the Java I don't think that we will be able to execute a returned response as JavaScript. Although, do we need that since we can parse response body in the downstream using Java JSON abilities?

REST: Not able to add cookie

I am using Apache CXF framework for my REST based service.
In the HTTPServletResponse, I am adding a cookie (using addCookie(Cookie cookie) method) but it is not being added successfully because, whenever I call the same API again, I couldn't see/use the added cookie.
I am using a REST client to call the API and I could see Set-Cookie header in the Respose Headers, but it is not being set.
What would be the problem here?
Well, the cookie is set actually.You will notice that further requests to your api carry the cookie along with them in the "Request Headers". To check the cookie, include the following code snippet in your Service Implementation:
In the implementation class, add the following annotation
#Context
private HttpHeaders headers;
Now, in the method of that class where you want to check the headers, add this code
if(headers.getRequestHeaders() != null) {
for(Entry<String, List<String>> entry : headers.getRequestHeaders().entrySet()) {
System.out.println("entry.getKey() >>>>>>>>>>> "+entry.getKey());
System.out.println("entry.getValue() >>>>>>>>>> "+entry.getValue());
}
}
Here, entry.getKey() will show you the header name and entry.getValue() will be showing a list of string values that this key is holding. If set, your cookie will appear under the header "cookie". I hope that helps.
Thanks.

WSO2 Synapse: setting a URL parameter

I am trying to do something that seems straightforward but can't get it to work. Basically I want the WSO2 API manager to add a URL parameter to a REST call.
Setup and Problem
I have a WSO2 API manager installed. I also have a Tomcat running with a bogus servlet called someservlet that simply logs anything it receives and returns ok. I have added the servlet as an API in the manager, so I can either call the servlet directly or via WSO2 API mgr.
I can run
curl http://localhost:8080/someservlet/servlet/toto?blob=blib&secret=pass
and the servlet works fine, it tells me it's received the path /toto and parameters blob and secret.
I can run
curl -H "Authorization: Bearer [...]" --url "http://192.168.23.1:8280/someservlet/1.0/toto?blob=blib&secret=pass"
And it does exactly the same. So far, so good.
What I want is to run:
curl -H "Authorization: Bearer MqVQuHqLNphtPV3XF1CtXVmbyP8a" --url "http://192.168.23.1:8280/someservlet/1.0/toto?blob=blib"
(note that I've removed the secret parameter)
...and still get the same result.
So basically I want API manager to add the URL parameter secret=pass.
First thing I tried: property mediator
Use Synapse XML config with property REST_URL_POSTFIX.
I edited the API config file, and added
<property name="REST_URL_POSTFIX" value="/blob?toto=titi" scope="axis2" type="STRING"/>
Now if I run
curl -H "Authorization: Bearer [...]" --url "http://192.168.23.1:8280/someservlet/1.0/toti?blab=blib&secret=puss"
it's as if I ran someservlet/1.0/blob?toto=titi: all my path and parameters have disappeared and been repaced with the configured ones. Hey, that's how it's supposed to work, isn't it!
Problems:
this doesn't add something to the URL, it sets the URL postfix, meaning that existing parameters disappear (in the above example, blab=blib)
it has to start with a "/" to be a valid value, so I can't just add &secret=pass (of course, because of problem 1, this would be useless anyway)
So basically this doesn't enable me to append the final &secret=pass.
Second thing I tried: rewrite URL mediator
I found this mediator, and although it probably won't do the trick, it's a good lead: I can just call with secret=foo, and get the mediator to replace it with secret=pass.
I put this in the config file:
<rewrite>
<rewriterule>
<action type="replace" value="pass" fragment="query" regex="foo"/>
</rewriterule>
</rewrite>
This doesn't work. At first I thought I didn't have the action parameters right. But the error message is:
Malformed URL when processing /someservlet/1.0/toti?blab=blib&secret=foo
Malformed? There's more detail in the exception stack trace:
java.net.MalformedURLException: no protocol: /someservlet/1.0/toti?blab=blib&secret=foo
So what's happening is that the mediators (log or rewrite) receive a message whose "To:" field points to a URL with no protocol!
Of course I've been googling around, and there are some cases where I find other people have logMediator: To: /blabla, and other (most) cases where they have logMediator: To: http ://blabla. I don't really see what's causing the difference. :-(
So this is where I'm stuck!! :-(
Option to be tried
I'm aware that there's probably a sledgehammer solution that should work:
use property to store the full path and all parameters
implement my own mediator (e.g. in Java) to modify these parameters
use property REST_URL_POSTFIX to put the modified postfix on the call
However I feel that this problem should have a simpler solution.
I have a kind of hope that someone will point me to a simple resource (mediator, sample, syntax error, anything) that I haven't found and that does just what I want. Optimism... :-)
Thanks for reading. Any ideas?
As i understood, you are trying to append the secret=pass to your endpoint url.
When you invoke the API , i belive you are sending that parameter.
Same time you are sending "blab=blib" parameter also. But in the ESB you need to change that to "toto=titi"
The method you used is right.(ie: Using property REST_URL_POSTFIX) In that case it will replace all requets parameter.
But before using that, you can save the request parameter and using the "REST_URL_POSTFIX"
you can achive the final REST url you need. (yes, that is the final option you mentioned as "to be tried")
In the "TO" address, you will only have address after port number.
If you use "" POST_TO_URI" property yopu will see the full adress URL printed in the log, but we use that if there is any proxy server configured between BE service and ESB
I've solved my problem.
Here's what I do:
in the config file, get the URL postfix using REST_URL_POSTFIX and
put it in a property
edit the property in a Java mediator
use REST_URL_POSTFIX to set the new postfix in XML
For the 1rst step, I use this line:
<property name="querystrings" expression="get-property('axis2', 'REST_URL_POSTFIX')"/>
this took some time to corner, because there are many lines out there that don't work for me, it took the 2 parameters (axis2 and REST...) to get it straight.
For the second step, this is the config XML:
<class name="mypackage.AddUrlParamMediator">
<property name="paramName" value="mykey"/>
<property name="paramValue" value="mysecret"/>
</class>
this is the mediator class (without imports):
public class AddUrlParamMediator extends AbstractMediator {
private String paramName = "default";
private String paramValue = "default";
public void setParamName(String paramName) {
this.paramName = paramName;
}
public void setParamValue(String paramValue) {
this.paramValue = paramValue;
}
public boolean mediate(MessageContext synapseMsgContext) {
SynapseLog log = this.getLog(synapseMsgContext);
String urlNewParam = this.paramName + "=" + this.paramValue;
Object queryStringsPpty = synapseMsgContext.getProperty("querystrings");
if (queryStringsPpty == null) {
log.error("### queryStringPpty=null, exiting!");
return true;
}
String queryStrings = queryStringsPpty.toString();
queryStrings = (queryStrings.contains("?"))
? queryStrings + "&" + urlNewParam
: queryStrings + "?" + urlNewParam;
synapseMsgContext.setProperty("querystrings", queryStrings);
return true;
}
}
and of course here's the third step in the XML config:
<property name="REST_URL_POSTFIX" expression="get-property('querystrings')" scope="axis2" type="STRING"/>
So all this basically sets a parameter at the end of the URL.
Hope this helps others.
For anyone who may have the same issue, here's another solution, simpler and works.
Go to the carbon admin portal, to the list of APIs, find the relevant API and click on it.
This leads to the XML config of the API.
After the "address" field (and at the same level in the XML) add the field:
<property name="Authorization" value="stuff to add" scope="transport"/>
This adds the property "Authorization" with value "stuff".