Monday, August 20, 2012

How to integrate with other web services without creating OSGi packages

How to integrate with other web services without creating OSGi packages:
A lot of enterprise grade systems require some sort of integration with other services these days, to extend and bring in more features into the systems. In this blog post I would like to show a quick and easy way to integrate CQ5 with other web services. Examples below will be showing a RESTful webservice but other webservices like SOAP will take similar approach.
Webservices integration usually involves building a integration layer. A Java Servlet would definitely be a good candidate. But to avoid building / compiling / packaging / deploying such code into an OSGi container, one can easily write a JSP (on the fly) in CQ to handle the integration.
Create an integration layer page:

This integration page is basically to create an instance of a CQ Page so that the rest of the content pages can communicate to it (Things under /app are not exposed or cannot be called directly). And extra benefit about this CQ Page -> You can control who has access to it!
Note the above page is using “Demo – API Page Template”, and here is the mapping:


And apipage.jsp is nothing more than what you want to surface in a typical Servlet.  Here is snippet of the code:
if (request.getParameter("action") != null) {
if (request.getParameter("action").equals("getSomething")) {
Node demoNode = resourceResolver.getResource(INTEGRATION_DESIGN_NODEPATH).adaptTo(Node.class);
response.setContentType("application/json");
out.write(getSomething(demoNode));

} else if (request.getParameter("action").equals("getCategories")) {
Node demoNode = resourceResolver.getResource(INTEGRATION_DESIGN_NODEPATH).adaptTo(Node.class);
response.setContentType("application/json");
out.write(getCategories(demoNode));

} else if (request.getParameter("action").equals("getFields") &&
request.getParameter("param1") != null &&
request.getParameter("param2") != null) {
response.setContentType("application/json");
out.write(getFields(
request.getParameter("param1"),
request.getParameter("param2"));

} else {
response.setContentType("application/json");
out.write("{\"error\":\"error\"}");
}
}


And derived from the above, we now have the following links to retrieve data:
http://_server_:_port_/content/integrationdemo/en/integration/integrationapi?action=getSomething
http://_server_:_port_/content/integrationdemo/en/integration/integrationapi?action=getCategories
http://_server_:_port_/content/integrationdemo/en/integration/integrationapi?action=getFields&param1=test&param2=data

The integration implementation will be per your requirements, but at a high level you can pretty much do everything-in-a-servlet inside a JSP. JSPs are Servlets after all. Here is a snippet of a http call (to a webservice) inside the same JSP:

static String getFields(String apiKey, String accessToken, String someJson) {
HttpClient httpClient = new HttpClient();
HttpClientParams httpClientParams = new HttpClientParams();
DefaultHttpMethodRetryHandler defaultHttpMethodRetryHandler = new DefaultHttpMethodRetryHandler(0, false);
httpClientParams.setParameter(HttpClientParams.RETRY_HANDLER, defaultHttpMethodRetryHandler);
httpClient.setParams(httpClientParams);

PostMethod post = new PostMethod(EXTERNAL_WEBSERVICE_API_URL+apiKey.trim()+"/URL_EXAMPLE/test?oauth_token="+accessToken.trim());
post.addRequestHeader("Accept", "application/json");
post.addRequestHeader("Content-Type", "application/json");
post.setRequestBody(someJson);

try {
httpClient.executeMethod(post);
String result = post.getResponseBodyAsString();

if (result != null && !result.equals("")) {
JSONObject returnObj = new JSONObject(result);
return returnObj.toString();
} else {
return "";
}
} catch (Exception ex) {
return ex.getMessage();
}
}


And finally, as an option (if you want to integration the CQ authoring experience with an external webservice), you can expose the data retrieved inside a CQ Component dialog field, you will need to configure the widget to retrieve webservice data. Details are documented in:
http://dev.day.com/docs/en/cq/current/widgets-api/index.html?class=CQ.form.Selection
Here’s a quick example:

And the result:


Enjoy~

DIGITAL JUICE

No comments:

Post a Comment

Thank's!