wso2 Rest response from custom code - rest

I have the following usecase, where I have to create a rest url dynamically using the properties. For that I have created a custom Mediator which reads the properties and creates calls the backend service.
I am having an issue on how to send the response back to the user. It is an xml format. But I need to parse the xml and just send the text. For that I am using PayloadFactory. I am attaching my code here, can someone please suggest what I am doing wrong?
<api xmlns="http://ws.apache.org/ns/synapse" name="tririgaProxy" context="/services">
<resource methods="GET" url-mapping="/employee">
<inSequence>
<sequence key="tririgaConf"/>
<property name="triUser" expression="get-property('triUser')"/>
<property name="triPass" expression="get-property('triPass')"/>
<property name="triURL" expression="get-property('triURL')"/>
<property name="triWfName" expression="get-property('triPeople.database.employee.wfName')"/>
<class name="com.wso2.tririga.mediator.IncomingMediator"/>
<payloadFactory media-type="text">
<format><![CDATA[$1]</format>
<args>
<arg evaluator="xml" expression="/status/text()"/>
</args>
</payloadFactory>
</inSequence>
</resource>
Java Class:
package com.wso2.tririga.mediator;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.synapse.MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
import org.apache.synapse.util.PayloadHelper;
public class IncomingMediator extends AbstractMediator {
private static final Log log = LogFactory.getLog(IncomingMediator.class);
#Override
public boolean mediate(MessageContext msgContext) {
String triUser = String.valueOf(msgContext.getProperty("triUser"));
String triPass = String.valueOf(msgContext.getProperty("triPass"));
String triURL = String.valueOf(msgContext.getProperty("triURL"));
String triWfName = String.valueOf(msgContext.getProperty("triWfName"));
try {
URI uri = new URIBuilder(triURL)
.addParameter("USERNAME", triUser)
.addParameter("PASSWORD", triPass)
.addParameter("ioName", triWfName).build();
log.info("URI: "+uri.toString());
String response = execute(uri);
PayloadHelper.setTextPayload(msgContext, convertToXML(response));
} catch (URISyntaxException e) {
log.error("Error while creating URI", e);
}
return true;
}
private static String execute(URI uri) {
String responseBody = null;
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpGet get = new HttpGet();
((HttpRequestBase) get).setURI(uri);
ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
#Override
public String handleResponse(final HttpResponse response) throws ClientProtocolException, IOException {
int status = response.getStatusLine().getStatusCode();
if (status >= 200 && status < 300) {
HttpEntity entity = response.getEntity();
String responseStr = EntityUtils.toString(entity);
return "Successful".equalsIgnoreCase(responseStr) ? "RetCode=C;Message=Success" : "RetCode=F;Message=Failed because Itegration Exception";
} else {
throw new ClientProtocolException("Unexpected response status: " + status);
}
}
};
try {
responseBody = httpclient.execute(get, responseHandler);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} finally {
try {
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return responseBody;
}
private static String convertToXML(String response){
return"<status>"+response+"</status>";
}
}
I dont get any response back from here.

Since you need to transform the response message you need to do the payload transformation in the out sequence of the api.
currently what you are doing is transforming the message in the in sequence.

Related

ResourceAccessException received instead HttpServerErrorException

I have invoked rest Api in my microservice using RestTemplate. However incase of exceptions i have returned error data with HTTP response code as 500. But when i receive this response in my microservice , it is received as ResourceAccessException instead of HttpServerErrorException. Hence i lose the response body which i returned in my rest API. Spring web is of version 5.2.5
Add below component
import java.io.IOException;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.ResponseErrorHandler;
#Component
public class RestTemplateResponseErrorHandler implements ResponseErrorHandler {
#Override
public boolean hasError(ClientHttpResponse httpResponse) throws IOException {
return (httpResponse.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR
|| httpResponse.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR);
}
#Override
public void handleError(ClientHttpResponse httpResponse) throws IOException {
if (httpResponse.getStatusCode().series() == HttpStatus.Series.SERVER_ERROR) {
throw new HttpServerErrorException(HttpStatus.SERVICE_UNAVAILABLE);
} else if (httpResponse.getStatusCode().series() == HttpStatus.Series.CLIENT_ERROR) {
throw new HttpClientErrorException(HttpStatus.UNAUTHORIZED);
}
}
}
And handle exception like below while calling API
ResponseEntity<Object> res = null;
try {
res = restTemplate.exchange(completeUrl, HttpMethod.GET, null, Object.class);
if (res.getStatusCodeValue() == HttpStatus.OK.value()) {
}
} catch (HttpServerErrorException e) {
} catch (HttpClientErrorException e) {
}
The reason why you are getting this ResourceAccessException may be because you are using BufferingClientHttpRequestFactory. Without a full stack trace, I cannot be sure.
Look here for more details:
Throwing ResourceAccessException vs HttpClientErrorException for RestTemplate client in Spring

Vertx JWKS/JWT verification throws a 500 with no errors logged

I have a very basic Vertx demo I'm trying to create that fetches a JWK from an endpoint and creates an RSAPublicKey for verifying a JWT signature:
package example;
import com.auth0.jwk.JwkException;
import com.auth0.jwk.JwkProvider;
import com.auth0.jwt.interfaces.DecodedJWT;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpServer;
import io.vertx.ext.web.Router;
import com.auth0.jwk.UrlJwkProvider;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.interfaces.RSAPublicKey;
import com.auth0.jwt.interfaces.RSAKeyProvider;
import java.security.interfaces.RSAPrivateKey;
public class MainVerticle extends AbstractVerticle {
#Override
public void start(Promise<Void> startPromise) throws Exception {
HttpServer server = vertx.createHttpServer();
Router router = Router.router(vertx);
router.route().handler(routingContext -> {
String authHeader = routingContext.request().getHeader("Authorization");
// pull token from header
String token = authHeader.split(" ")[1];
URL jwksEndpoint = null;
try {
jwksEndpoint = new URL("http://localhost:1080/jwks");
} catch (MalformedURLException e) {
e.printStackTrace();
}
JwkProvider jwkProvider = new UrlJwkProvider(jwksEndpoint);
RSAKeyProvider keyProvider = new RSAKeyProvider() {
#Override
public RSAPublicKey getPublicKeyById(String kid) {
//Received 'kid' value might be null if it wasn't defined in the Token's header
RSAPublicKey publicKey = null;
try {
publicKey = (RSAPublicKey) jwkProvider.get(kid).getPublicKey();
} catch (JwkException e) {
e.printStackTrace();
}
return publicKey;
}
#Override
public RSAPrivateKey getPrivateKey() {
return null;
}
#Override
public String getPrivateKeyId() {
return null;
}
};
Algorithm algorithm = Algorithm.RSA256(keyProvider);
JWTVerifier verifier = JWT.require(algorithm)
.withIssuer("auth0")
.build();
DecodedJWT jwt = verifier.verify(token);
System.out.println(jwt);
routingContext.next();
});
router.route("/hello").handler(ctx -> {
ctx.response()
.putHeader("content-type", "text/html")
.end("<h1>Hello from non-clustered messenger example!</h1>");
});
server.requestHandler(router).listen(8888, http -> {
if(http.succeeded()) {
startPromise.complete();
System.out.println("HTTP server started on port 8888");
} else {
startPromise.fail(http.cause());
}
});
}
}
The problem is that when I make request to the /hello endpoint, the application immediately returns a 500. But nothing appears in the logs (even at debug level).
I've tried manually specifying the kid property to rule out the jwkProvider not returning properly
I'm at a loss at how to gain any more insight into what is failing.
Turns out to completely be my oversight. Wrapping that verifier.verify() call in a try/catch showed me that I was expecting an issuer. This is the same problem I was having while trying to achieve this in Quarkus! I was able to remove that from the builder and now this works perfectly.

HttpUrlConnection.connect() Query

After hours of trawling the internet and trying to make sense of the documentation I seem unable to find a resolution to this problem.
I have an application which is using an ASyncTask to connect to a server I have 3 addresses to "test" the connection.
Now the problem is when I use the Myconnection.connect() the background task just hangs if there is either no known address or a dead link.
How can I test this connection when with a dead link or dead server it hangs and does not receive any response
The errors in the Logcat are
07-02 12:47:13.101 13850-20562/nodomain.myapplication D/URL ERRORhttp://10.0.0.2/testdb/connection.php
07-02 12:47:13.339 13850-20562/nodomain.myapplication I/URL IS OK: [ 07-02 12:47:13.339 13850:20562 I/ ]Status : 200
07-02 12:47:13.344 13850-20562/nodomain.myapplication D/URL ERRORhttp://localhost/myPage.php
As you can see the only URL I get a response from is www.google.com
My code is below:
package nodomain.myapplication;
import android.os.AsyncTask;
import android.util.Log;
import org.w3c.dom.Text;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
/**
* Created by Shab on 02/07/2017.
*/
public class bgWorker extends AsyncTask<Void, Integer, Void> {
#Override
protected Void doInBackground(Void... params)
{
String db_Username = "root";
String db_Password = "";
String db_Name = "testdb";
String url1 = "http://10.0.0.2/testdb/connection.php"; //DEAD? (NO RESPONSE)
(Program Hang until exception is called)
String url2 = "http://www.google.com"; //OK RESPONSE 200
String url3 = "http://localhost/myPage.php"; //NO RESPONSE
try {
getResponseCodes(url1);
getResponseCodes(url2);
getResponseCodes(url3);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
}
private String encodeURLString(String value) {
String encodedString = "";
try {
encodedString = URLEncoder.encode(value, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return encodedString;
}
public static int getResponseCodes(String TheURL) throws MalformedURLException,IOException
{
URL oUrl = new URL(TheURL);
HttpURLConnection oHuC = (HttpURLConnection) oUrl.openConnection();
oHuC.setRequestMethod("HEAD");
int response = 0;
try{
oHuC.connect();
response = oHuC.getResponseCode();
if(response == 200)
{
Log.i("URL IS OK","");
}else{
Log.i("URL IS NOT OK","");
}
Log.i("", "Status : " + response);
}catch(IOException e){
Log.d("URL ERROR" + oUrl, "D");
}
return response;
}
}
Even with the IF statement testing the response for a 200 OK it only manages to interpret one response from the 3 URL due to the URL IS OK output.

My Post Request returns a 500 internal server error in Jersey

I am trying to post data in Jersey but all I get is a 500 error. My GET requests are all working fine.
Below is my client code.
package main;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
public class MainClass {
public static void main(String[] args) {
try {
Client client = Client.create();
client.addFilter(new HTTPBasicAuthFilter("admin", "admin"));
WebResource webResource = client
.resource("http://localhost:7307/mysite/rest_service/postdataclass/postData");
String input = "{\"name\":\"Violent Soho\",\"last\":\"Jesus Stole My Girlfriend\"}";
ClientResponse response = webResource.type("application/json")
.post(ClientResponse.class, input);
if (response.getStatus() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatus());
}
System.out.println("Output from Server .... \n");
String output = response.getEntity(String.class);
System.out.println(output);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
And Here is my other class
package service.utils;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import beans.AASample;
#Path("postdataclass")
public class PostSample {
#GET
#Path("/sayHell")
public Response sayHell() {
return Response.status(Response.Status.OK).entity("Hell").build();
}
#POST
#Path("/postData")
#Consumes(MediaType.APPLICATION_JSON)
public Response postData(AASample sample) {
return Response.status(Response.Status.OK).entity("Profile " + sample.toString()).build();
}
}
And my AAClass
package beans;
public class AASample {
private String name;
private String last;
public AASample(String name, String last) {
super();
this.name = name;
this.last = last;
}
public AASample() {
super();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLast() {
return last;
}
public void setLast(String last) {
this.last = last;
}
#Override
public String toString() {
return "AASample [name=" + name + ", last=" + last + "]";
}
}
Below is the Server Log when I Make the Post Request.
Jul 08, 2016 8:35:22 PM org.glassfish.jersey.filter.LoggingFilter log
INFO: 3 * Server has received a request on thread http-nio-8090-exec-4
3 > POST http://localhost:8090/mysite/rest_service/postdataclass/postData
3 > accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
3 > authorization: Basic YWRtaW46YWRtaW4=
3 > connection: keep-alive
3 > content-length: 43
3 > content-type: application/json
3 > host: localhost:8090
3 > user-agent: Java/1.8.0_20
Jul 08, 2016 8:35:23 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [Spot Buddy Service] in context with path [/mysite] threw exception [org.glassfish.jersey.server.ContainerException: java.lang.AbstractMethodError: com.fasterxml.jackson.jaxrs.base.ProviderBase._configForReading(Lcom/fasterxml/jackson/databind/ObjectMapper;[Ljava/lang/annotation/Annotation;)Lcom/fasterxml/jackson/jaxrs/cfg/EndpointConfigBase;] with root cause
java.lang.AbstractMethodError: com.fasterxml.jackson.jaxrs.base.ProviderBase._configForReading(Lcom/fasterxml/jackson/databind/ObjectMapper;[Ljava/lang/annotation/Annotation;)Lcom/fasterxml/jackson/jaxrs/cfg/EndpointConfigBase;
at com.fasterxml.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:644)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:260)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:236)
I converted my data to a json object manually. changed post method to
#POST
#Path("/postData")
#Consumes(MediaType.APPLICATION_JSON)
public Response postData(String sample) {
AASample object = StringToObjectConverter.getObject(sample);
if(object != null){
return Response.status(Response.Status.OK).entity("Object " + object.toString()).build();
}else{
return Response.status(Response.Status.OK).entity("We Failed Decoding :" + sample +":").build();
}
}
StringToObjectConverter class
package main
import java.io.IOException;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import beans.AASample;
public class StringToObjectConverter {
public static AASample getObject(String postedData) {
AASample aaSample = null;
ObjectMapper mapper = new ObjectMapper();
try {
aaSample = mapper.readValue(postedData, AASample.class);
} catch (JsonGenerationException e) {
aaSample = null;
} catch (JsonMappingException e) {
aaSample = null;
} catch (IOException e) {
aaSample = null;
}
return aaSample;
}
}

How to verify digital signature of SOAP call?

I wrote an interceptor in Apache CXF and get a SoapMessage. How do I get the raw XML from the SOAP message without changing the data to hurt the verification of the digital signature?
I refer to org.apache.cxf.binding.soap.SoapMessage:
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.binding.soap.interceptor.EndpointSelectionInterceptor;
import org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class XmlSignatureVerifyInInterceptor extends AbstractSoapInterceptor {
private static final Logger log = LogManager.getLogger(XmlSignatureVerifyInInterceptor.class);
public XmlSignatureVerifyInInterceptor() {
super(Phase.READ);
log.entry();
addAfter(ReadHeadersInterceptor.class.getName());
addAfter(EndpointSelectionInterceptor.class.getName());
}
#Override
public void handleMessage(SoapMessage soapMessage) throws Fault {
log.entry(soapMessage);
}
}
Cheers and thank you in advance!
Fireball
If you are refering a javax.xml.soap.SOAPMessage, and you want a String result of XML, use ByteArrayOutputStream:
SOAPMessage message;
ByteArrayOutputStream out = new ByteArrayOutputStream();
String msg = "";
try {
message.writeTo(out);
msg = out.toString("UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
I use UTF-8 as encoding, you can change it to any others.