Wednesday, July 08, 2015

Creating Portlet URLs


Listed below are various ways to create portlet action and render phase URLs

Creating URL within/to the current portlet.

1. Using Taglib:

For Render URL

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>

<portlet:renderURL var="myRenderURL1" windowState="<%=LiferayWindowState.NORMAL.toString()%>">
<portlet:param name="mvcPath" value="/html/view/myresponse.jsp"/>
</portlet:renderURL>

Similarly action URL looks like below
<portlet:actionURL var="myActionURL1" windowState="<%=LiferayWindowState.NORMAL.toString()%>">
<portlet:param name="cmd" value="update"/>
</portlet:actionURL>

2. Using Java code

For render URL
PortletURL myRenderURL2=renderResponse.createRenderURL();
myRenderURL2.setWindowState(LiferayWindowState.NORMAL);
myRenderURL2.setParameter("cmd", "view");
Similarly action URL looks like below
PortletURL myActionURL2=renderResponse.createActionURL();
myActionURL2.setWindowState(LiferayWindowState.NORMAL);
myActionURL2.setParameter("cmd", "update");

Creating URL outside the current portlet, that is URL to the other page or portlet.


PortletURL myRenderURL3= PortletURLFactoryUtil.create(request,  themeDisplay.getPortletDisplay().getId(), themeDisplay.getPlid(), PortletRequest.RENDER_PHASE);

 myRenderURL3.setWindowState(LiferayWindowState.NORMAL);
 myRenderURL3.setPortletMode(LiferayPortletMode.VIEW);
 myRenderURL3.setParameter("jspPage", "/season/rainy.jsp");

Here themeDisplay.getPortletDisplay().getId() is the id of the current portlet to be viewed or it can be the id of the other portlet to be viewed and themeDisplay.getPlid() is the page layout Id of the current page and can point to the plid of some other page on which the portlet is deployed.


Tuesday, June 30, 2015

Invoke custom portlet service using Java Reflection


Requirement:
Create a custom service 'myPojo' in a custom portlet named 'my-portlet'.
Access the above service in a Liferay jsp via hook.
This can be achieved by placing the service jar in the tomcat-lib but in certain scenarios where the access and deployment restrictions are applied and deployment does not allow to manually deploy the service jar to tomcat-lib below approach will be helpful.

Portlet name : my-portlet
Service Entity : MyPojo
Method to invoke: getMyPojo
Pojo property to read : _myField (exact name can be verified from the service generated model implementation class MyPojoModelImpl)




ClassLoader classLoader = PortletBeanLocatorUtil.getBeanLocator("my-portlet").getClassLoader();
Class clazz = classLoader.loadClass("com.informatick.hub.service.MyPojoLocalServiceUtil");
java.lang.reflect.Method method = clazz.getMethod("getMyPojo", long.class);
Object retunedObject = method.invoke(clazz.newInstance(), classPK);
    
java.lang.reflect.Field ouaField;
Class beanClass = retunedObject.getClass().getSuperclass().getSuperclass();
        
 ouaField = beanClass.getDeclaredField("_myField");
 ouaField.setAccessible(true);
 String tempString = (String) ouaField.get(retunedObject);

 long oua = 0;
 oua = GetterUtil.getLong(tempString);

 System.out.println("Returned vvalue : "+oua) 



Wednesday, April 30, 2014

Liferay : Advance Web Content Structures and Templates

The post details about the functionality to have multiple views for a web content article.

Currently only one view can be rendered for a article, but in real word scenarios there are occasions when different view are needed for the same content on same or different pages in Liferay.
Below are the steps with detailed code to achieve the above feature:

Step 1:
Create a new structure

<?xml version="1.0"?>

<root>
 <dynamic-element name="Name" type="text" index-type="" repeatable="false">
  <meta-data>
   <entry name="displayAsTooltip"><![CDATA[true]]></entry>
   <entry name="required"><![CDATA[true]]></entry>
   <entry name="instructions"><![CDATA[]]></entry>
   <entry name="label"><![CDATA[Name]]></entry>
   <entry name="predefinedValue"><![CDATA[]]></entry>
  </meta-data>
 </dynamic-element>
 <dynamic-element name="Address" type="text" index-type="" repeatable="false">
  <meta-data>
   <entry name="displayAsTooltip"><![CDATA[false]]></entry>
   <entry name="required"><![CDATA[true]]></entry>
   <entry name="instructions"><![CDATA[]]></entry>
   <entry name="label"><![CDATA[Address]]></entry>
   <entry name="predefinedValue"><![CDATA[]]></entry>
  </meta-data>
 </dynamic-element>
</root>



Step 2:
Create a new template


<p>
 <span style="font-size: 12px; ">
  <em><strong>Name: </strong>${Name.getData()}</em>
 </span>
</p>
<p>
 <span style="font-size: 12px; ">
  <em><strong>Address:</strong>${Address.getData()}</em>
 </span>
</p>




Step 3:
Create a web content based on structure and template created in step 1 and step 2. Populate some data in the web content.

Now our focus will be to create a new view for the content created in above in step 3

Step 4:
Thus create a new structure which will be dummy structure and fields here will not be relevant
<?xml version="1.0"?>

<root>
 <dynamic-element name="Dummy" type="text" index-type="" repeatable="false">
  <meta-data>
   <entry name="displayAsTooltip"><![CDATA[true]]></entry>
   <entry name="required"><![CDATA[true]]></entry>
   <entry name="instructions"><![CDATA[]]></entry>
   <entry name="label"><![CDATA[Dummy]]></entry>
   <entry name="predefinedValue"><![CDATA[]]></entry>
  </meta-data>
 </dynamic-element>

</root>





Step 5:
Create a new template, based upon structure creates in step 4, and will be considered as second view of the content created in step 3:

#set ($articleId = "10813")

#set ($renderUrl  = $request.render-url)
#set ($namespace = $request.portlet-namespace)
#set ($groupId = $getterUtil.getLong($groupId))

##
## Getting services
##
#set ($journalArticleService = 
 $serviceLocator.findService('com.liferay.portlet.journal.service.JournalArticleLocalService'))


#set ($article = $journalArticleService.getLatestArticle($groupId,$articleId))

<h3>Details</h3>
<br />
<table class="taglib-search-iterator">
 <tr class="results-header">
  <th class="col-1">Name</th>
  <th class="col-1">Address</th>
 </tr>
  
       #set ($document = $saxReaderUtil.read($article.content))
       #set ($root = $document.getRootElement())
       
       #set ($nameD = 
         $root.selectSingleNode(
           "dynamic-element[@name='Name']/dynamic-content"))
           
       #set ($addressD = 
         $root.selectSingleNode(
           "dynamic-element[@name='Address']/dynamic-content"))


   
      <tr class="results-row first">
       <td class="align-left col-1 valign-left">
       ${nameD.text}
       </td>

            <td class="align-left col-2 valign-middle">
           ${addressD.text}
       </td>

      </tr>
                   
</table>



Here $articleId is the article id of the content created in step 3.

Step 6:
Create a web content based on structure and template created in step 4 and step 5. The purpose of this content will be to display the data from the content created in step 3.


Liferay: Selecting multiple categories in Search portlet and Category Navigation portlet

Below is the original post which helps you to modify search and category navigation portlet and as a result user will be able to select multiple categories.

For more details go to:
http://liferaythought.wordpress.com/2013/04/30/selecting-multiple-categories/

Friday, April 18, 2014

RSA Encryption/Decryption - Part 2

My previous post on RSA details about basics of RSA and how to generate public and private key in java.


Encryption in Java



         public static byte[] encrypt(String text, PublicKey key) {
  byte[] cipherText = null;
  try {
   // get an RSA cipher object and print the provider
   final Cipher cipher = Cipher.getInstance(ALGORITHM);
   // encrypt the plain text using the public key
   cipher.init(Cipher.ENCRYPT_MODE, key);
   cipherText = cipher.doFinal(text.getBytes());

  } catch (Exception e) {
   e.printStackTrace();
  }
  return cipherText;
 }




Decryption in Java



         public static String decrypt(byte[] text, PrivateKey key) {
  byte[] decryptedText = null;
  try {
   // get an RSA cipher object and print the provider
   final Cipher cipher = Cipher.getInstance(ALGORITHM);

   // decrypt the text using the private key
   cipher.init(Cipher.DECRYPT_MODE, key);
   decryptedText = cipher.doFinal(text);

  } catch (Exception ex) {
   ex.printStackTrace();
  }

  return new String(decryptedText);
 }


RSA Encryption/Decryption - Part 1


What is Cryptography?

Cryptography is the practice or techniques for securing a communication in the presence of others. It is about constructing and analyzing protocols that overcome the influence of adversaries and are related to various aspects in information security such as data confidentiality, data integrity, authentication.

What is Encryption?

Encryption is one of the ways to achieve data security by translation of data into secret code or unreadable format called cipher text.

What is Decryption?

Decryption is the reverse of encryption that is converting cipher text to its original message, i.e. plain or readable text.

What is RSA?

RSA is one of the widely used public key cryptography for secure data communication. RSA stands for Ron Rivest, Adi Shamir and Leonard Adleman, who first publicly described it in 1978. Public key cryptohraphy is also called Asymmetric cryptography which requires two separate keys, one which is private key (secret key) and another which is public key. the public key is used to encrypt text while private key is used to decrypt text.

How to generate public/private key in java?




public static void generateKey(String private_key, String public_key) {
  try {
   final KeyPairGenerator keyGen = KeyPairGenerator
     .getInstance(ALGORITHM);
   keyGen.initialize(512);
   final KeyPair key = keyGen.generateKeyPair();

   File privateKeyFile = new File(private_key);
   File publicKeyFile = new File(public_key);

   // Create files to store public and private key
   if (privateKeyFile.getParentFile() != null) {
    privateKeyFile.getParentFile().mkdirs();
   }
   privateKeyFile.createNewFile();

   if (publicKeyFile.getParentFile() != null) {
    publicKeyFile.getParentFile().mkdirs();
   }
   publicKeyFile.createNewFile();

   // Saving the Public key in a file
   ObjectOutputStream publicKeyOS = new ObjectOutputStream(
     new FileOutputStream(publicKeyFile));
   publicKeyOS.writeObject(key.getPublic());
   publicKeyOS.close();

   // Saving the Private key in a file
   ObjectOutputStream privateKeyOS = new ObjectOutputStream(
     new FileOutputStream(privateKeyFile));
   privateKeyOS.writeObject(key.getPrivate());
   privateKeyOS.close();
  } catch (Exception e) {
   e.printStackTrace();
  }

 }

To call

generateKey("c:/rsa/key/public.key", "c:/rsa/key/private.key");
My next post on RSA details about how to encrypt and decrypt in java using  public and private key generated above.

Thursday, January 16, 2014

Liferay: Custom 404 Page for plugins

Liferay portal runs and is configured as ROOT application with in tomcat sever.
By default, if tried to request a plugin in Liferay (say we have a theme plugin named as "error-theme"), a 404 Error is raised and the user is served Tomcat's default 404 error page as below:


To make your 404 page a bit more presentable, provide the user with a link back into your site, as well as hide the Tomcat version in use, you can easily add a custom 404 error page.

Step 1:

Create a jsp name it 404.jsp, with below content:


The requested resource is not available. Please provide the correct URL or try again later.
<br/>
<a href="#" onclick="javascript:history.go(-1);">Go back to main site.</a>

Step 2:

Now create a new directory as error-theme/docroot/errors in Lifeay IDE and copy the above created 404.jsp to it.

Step 3:

Last step is to add the below code to the web deployment descriptor (web.xml) of the plugin:

         <error-page>
  <error-code>404</error-code>
  <location>/errors/404.jsp</location>
 </error-page>

Now, when someone goes to the plugin link that does not exist, they get the custom 404 page we created.





Tuesday, January 14, 2014

JQuery : Declare a function



Method 1: The Javascript way

The simple way to declare a  function in javascript:


function callMe (count) {
     return (count+5);
}

console.log(callMe(13));
//output: 18

Disadvantage: If you wanted a quick function to test something then maybe that’s the only occasion you would use this. It’s not good coding and doesn’t promote code reuse.


Method 2: Creating your JQuery function

The simple way to declare a  function in javascript:


<div id="mydiv">i am here</div>

jQuery.fn.extend({
    mytext: function () {
        var text = $(this).text();
        var mytexts = '';
        var toggle = true; //lower/uppper toggle
            $.each(text, function(i, nome) {
                mytexts += (toggle) ? nome.toUpperCase() : nome.toLowerCase();
                toggle = (toggle) ? false : true;
            });
    return mytexts;
    }
});

console.log($('#mydiv').zigzag());
//output: #1 i aM HeRe

//chained example
console.log($('#mydiv').zigzag().toLowerCase());
//output: #1 i am here


Method 1: Functions in custom namespaces

If your writing functions in a custom namespace you must declare them in this way. Extra functions can be added to the namespace you just need to add a comma after each one (except the last one!).


JQUERY4U = {
    callme: function(count) {
        return (count + 5);
    }
}
//function call
JQUERY4U.callme(13);

Reference post: Full credit goes to the original post, which made the topic so easy to understand (visit for more details).


Thursday, June 27, 2013

Liferay 6: Monitoring tomcat.

The Liferay tomcat bundle is available for download on http://www.liferay.com/downloads/liferay-portal/available-releases and instant use. It ships pre-configured with hypersonic database and you can switch to mysql, oracle, etc for permanent solutions.

When moving your site or solution to production server there is always uncertainty on how much the load will be coming at peak time, how many request the tomcat will be able to server with Liferay. Although the Apache tomcat comes with tomcat-manager application that allows you to monitor all the resources via JMX beans. but since this have been removed in Liferay-tomcat bundle thus it is hard to monitor the resources and threads the tomcat server is consuming. Thus to over come this shortcoming, below are the steps to enable the monitoring in the tomcat:

Server Details
Liferay: 6.1.2 GA2 Enterprise
Tomcat Bundle: 7.0.27
Java 6

Step 1:
Stop the running Liferay tomcat server and clean the temp and work folder.

Step 2:
Download the vanilla apache tomcat server of the same version and unzip it at some temporary location.

Step 3:
Copy host-manager and manager application <tomcat>/webapps directory to liferay installation at <liferay-tomcat-bundle>/tomcat-7.0.27/webapps

Step 4:
Create a manager.xml file at location <liferay-tomcat-bundle>/tomcat-7.0.27/conf/Catalina/localhost.
And the following content to it and save it

<Context antiResourceLocking="false" privileged="true" useHttpOnly="true">
 
 </Context>
Step 5:
Now open file <liferay-tomcat-bundle>/tomcat-7.0.27/conf/tomcat-users.xml in edit mode. And the below content inside the tag <tomcat-users>.

<tomcat-users>
...

  <role rolename="tomcat"/>
  <role rolename="manager-gui"/>
  <role rolename="standard"/>
  <role rolename="manager"/>
  <role rolename="admin"/>
  <user username="tomcat" password="tomcat" roles="manager,admin,standard,manager-gui,tomcat"/>

...
</tomcat-users>

Step 6:
Now restart the tomcat server and go to the URL: http://localhost:8080/manager/html and you will be prompted for username and password which should be the same as defined above.



And now you can monitor the tomcat resources and can tune them accordingly.



Monday, May 13, 2013

Java Reflection API: Calling methods

Moving forward from my previous article: Java Reflection API: Constructing Objects

Using Java Reflection you can inspect the methods of classes and invoke them at runtime. This is done via the Java class java.lang.reflect.Method. Below are the details to achieve the same:

Obtaining Methods
You can obtain the methods from the Class object:
Method[] methods = mClass.getMethods();

The Method[] array will have one Method instance for each public method declared in the class.

If you know the precise parameter types of the method you want to access, you can do so rather than obtain the array of all methods. This example returns the public method named "mMethod", in the given class which takes a String as parameter:
Method method = mClass.getMethod("mMethod", new Class[]{String.class});
If the method trying to access takes no parameters, pass null as the parameter type array:
Method method = mClass.getMethod("mMethod", null);
Parameters and Return types
To access details about method parameters and return types, do the below:
Class[] parameterTypes = method.getParameterTypes();

Class returnType = method.getReturnType();
Calling methods

The null parameter is the object you want to invoke the method on. If the method is static you supply null instead of an object instance. In this example, if mMethod(String.class) is not static, you need to supply a valid mObject instance instead of null;

The Method.invoke(Object target, Object ... parameters) method takes an optional amount of parameters, but you must supply exactly one parameter per argument in the method you are invoking. In this case it was a method taking a String, so one String must be supplied.
Method method = mClass.getMethod("mMethod", String.class);
Object returnValue = method.invoke(null, "value-1");


Java Reflection API: Constructing Objects


Moving forward from my previous article: Java Reflection API: Introduction

Using Java Reflection API, you can instantiate objects at runtime and invoke class constructors.
Getting Constructor
To get the list of all public constructors declared use the below code:
Constructor[]
constructors = mClass.getConstructors();

Here Constructor[] is an array of type java.lang.reflect.Constructor. However If you have the precise parameter types of the constructor you want to access, you can do so rather than obtain the array all constructors. Below example returns the public constructor of the given class which takes String as parameter:
Constructor constructor
= mClass.getConstructor(new Class[]{String.class});

Further to read all the input parameters of a constructor, do like this:
Class[] parameterTypes =
constructor.getParameterTypes();

Do the below to create an object using Java Reflection:
Constructor constructor = mClass.getConstructor(String.class);
Object mObject = constructor.newInstance("argument-1");
Next post in the series is Java Reflection API: Calling Methods

Java Reflection API: Introduction

Reflection is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the Java virtual machine.  It enable applications to perform operations which would otherwise be impossible. An application may make use of external, user-defined classes by creating instances of extensibility objects using their fully-qualified names.
Thus Java Reflection makes it possible to inspect classes, interfaces, fields and methods at runtime, without knowing the names of the classes, methods etc. at compile time. It is also possible to instantiate new objects, invoke methods and get/set field values using reflection.

The Drawbacks of reflection are:

  • Performance overhead
  • Security restrictions
  • Exposure of internals
Creating a Class Object when you don't know the class name at runtime:
String className = ??? //get fully qualified classname at runtime
Class mClass = Class.forName(className);
The Class.forName() method may throw a ClassNotFoundException if the class cannot be found on the at runtime.

You can access the modifiers ("public", "private", "static" etc.) of a class via the Class object. 

int modi = mClass.getModifiers();
Now using java.lang.reflect.Modifier , you can check the modifier info, for example:
Modifier.isAbstract(modi);

You can access the constructors of a class like this: 
Constructor[] constructors = mClass.getConstructors();
You can access the methods of a class like this:
Method[] methods = mClass.getMethods();
You can access the fields of a class like this:
 Field[] fields = mClass.getFields();
Next post in the series is Java Reflection API: Constructing Objects

Tuesday, April 23, 2013

Liferay: using DynamicQuery in a velocity template.

Consider a scenario if you have 1000 records in a Dynamic Data List (DDL) record set. You need to show only 20 latest records. One ways is to bring all the records and use a loop to show the records and break when a counter is greater then 20, this will cause slowness in page as you are bringing the complete record set.

To overcome this consider if you bring only latest 20 records from database something like at most list screens in liferay where pagination is used. Below is the set of lines that will allow you to achieve this;



#set ($ddlRecordSet = $serviceLocator.findService('com.liferay.portlet.dynamicdatalists.service.DDLRecordSetLocalService'))
#set ($ddlLocalService = $serviceLocator.findService('com.liferay.portlet.dynamicdatalists.service.DDLRecordLocalService'))

#set ($recordSetId = $getterUtil.getLong($reserved_record_set_id.data, 0))
#set ($DDLrecordClass = $portal.getClass().forName("com.liferay.portlet.dynamicdatalists.model.DDLRecord"))
#set ($dqfu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil"))
#set ($ofu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.OrderFactoryUtil"))
#set ($rfu = $portal.getClass().forName("com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil"))
#set ($q = $dqfu.forClass($DDLrecordClass))
#set ($V = $q.add($rfu.eq("recordSetId", $getterUtil.getLong($recordSetId))))
#set ($V = $q.addOrder($ofu.desc("modifiedDate")))
#set ($records = $ddlLocalService.dynamicQuery($q,0,20))
#set ($recordTitle = $ddlRecordSet.getRecordSet($recordSetId))
#set ($title = $recordTitle.getName())

You can modify the dynamic query as per your needs to order data on different columns.

Thursday, December 06, 2012

Why Liferay ?


So why is Liferay Portal the best portal product in our opinion?
  1. Liferay has the lowest Total Cost of Ownership (TCO) compared to its competitors starting with its licensing and getting it up and running through development costs, operational costs, and training/support costs (from the perspective of infrastructure, developers, administrators, and end users).
  2. Second-to-none rich out-of-the-box (OOTB) functionality around core portal, content management, collaboration, social, mobile, security and more; check out http://www.liferay.com/products/liferay-portal/features/portal for more information.
  3. All portal products typically need extensions and/or additions to deliver requisite functionality – with Liferay you can simply do more within a specific budget.
  4. Product innovation – leader in introducing new capabilities whether it be AJAX or friendly URLs or mobile or social
  5. Improved business agility – it is lightweight in nature; you can quickly get it up and running, and it is easier to develop on/manage.
  6. A mature Enterprise Open Source (fully supported) product – 24x7x365 platinum support with 1 hour response time SLA; this includes access to all service packs, hot fixes, notifications of security alerts, phone and web based support.
  7. Liferay’s open architecture and its open source nature help you avoid lock-in to a single proprietary vendor.
  8. Liferay’s hook and extension plugin model allows you to tailor product behavior to your needs without rewriting from scratch and without creating upgrade hell.
  9. Liferay offers opportunities for product feature sponsorship to enable contributions back into the core product for key customizations – this allows you to offload responsibility of maintaining and enhancing your custom features back to Liferay.
  10. Liferay offers you a full choice of application servers, databases, and operating systems to run on, thereby allowing you to leverage your infrastructure and skills investment.
References:




Wednesday, December 05, 2012

Part 3: Custom Liferay Plugin JSON Web Services

Go to Previous post Part 2: Custom Liferay Plugin JSON Web Services
Below is the step by step setup to expose and consume a plugin portlet service as JSON web service.

Step 1: Create a liferay plugin portlet

Step 2: Create a custom service

Using Liferay Service builder create a service. For example

The service.xml will look like below:
<service-builder package-path="com.rdg.api">
 <author>rishidev.gupta</author>
 <namespace>ServiceAPI</namespace>

 <entity name="Bridge" remote-service = "true" local-service="true" human-name="Bridge">
  <reference package-path="com.liferay.counter" entity="Counter"></reference>
  <reference package-path="com.liferay.portal" entity="User"></reference>
  <reference package-path="com.liferay.portlet.journal" entity="JournalArticle"></reference>
 </entity>
</service-builder>

Step 3: Build the service using liferay service builder 

Step 4: Writing a custom method to be exposed

public class BridgeLocalServiceImpl extends BridgeLocalServiceBaseImpl {

 public String getBridge(String str) throws PortalException {
  System.out.println("You have successfully requested for: " + str);
  return "You have successfully requested for: " + str;

 }
}
public class BridgeServiceImpl extends BridgeServiceBaseImpl {
 public String getBridge(String str) throws PortalException {
  return bridgeLocalService.getBridge(str);
 }
}
Now rebuild the service.

Step 5: Configuring web.xml 

To make sure that your custom portlets can be scanned, and their service can become part of the JSON API. For this you must add the following in portlets web.xml:


     <servlet>
        <servlet-name>JSON Web Service Servlet</servlet-name>
        <servlet-class>com.liferay.portal.kernel.servlet.PortalClassLoaderServlet</servlet-class>
        <init-param>
            <param-name>servlet-class</param-name>
            <param-value>com.liferay.portal.jsonwebservice.JSONWebServiceServlet</param-value>
        </init-param>
        <load-on-startup>0</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>JSON Web Service Servlet</servlet-name>
        <url-pattern>/api/jsonws/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>JSON Web Service Servlet</servlet-name>
        <url-pattern>/api/secure/jsonws/*</url-pattern>
    </servlet-mapping>

This enables the servlet that is responsible for scanning JSON web services configuration. Now deploy the plugin portlet in a running tomcat server.

Step 6: Consuming JSON Web Service

 To list registered services on portlet, 
http://localhost:8080/<portlet-context>/api/jsonws
 
To access service using browser
http://localhost:8080//service-api-portlet/api/jsonws/bridge/get-bridge?&str=rishidev.gupta 

Saturday, November 10, 2012

Part 2: Accessing and Using Liferay JSON Web Services

In previous post, I have worked on introducing all basics about JSON Web Services.
In this post the focus is on accessing and consuming the the services and example

To Restrict a method from being exposed as service, just annotate the method with:
@JSONWebService(mode = JSONWebServiceMode.IGNORE)

To define custom HTTP method name instead of using the default, just annotate the method with:
@JSONWebService(value = "get-user", method = "GET")
public User getUserById( ...

Thus above service will be exposed and accessed as

http://localhost:8080/api/jsonws/user/get-user

instead of 

http://localhost:8080/api/jsonws/user/get-user-by-id

To further customize the URL and remove the serviceClassname, just annotate the method with:
@JSONWebService("/get-user")
public User getUserById(..

Thus above service will be exposed and accessed as

http://localhost:8080/api/jsonws/get-user

instead of 

http://localhost:8080/api/jsonws/user/get-user-by-id

Portal Configuration

JSON Web Services can be enabled or disabled by setting the below portal property:
json.web.service.enabled=true
by default the services are enabled and the property is set to true.

Enabling/Disabling particular HTTP methods
jsonws.web.service.invalid.http.methods=DELETE,POST,PUT
causes portal to accept only GET requests and ignore the HTTP methods specified above.

Below is the comma separated list of public service methods that can be accessed by unauthenticated user:
For all methods as unauthenticated use below
jsonws.web.service.public.methods=*  
For is methods as unauthenticated use below

jsonws.web.service.public.methods=is*

Accessing service via HTML form


<form action="http://localhost:8080/api/jsonws/user/get-user-by-id" method="GET">
        <input type="hidden" name="userId" value="10172"/>
        <input type="submit" value="submit"/>
</form>
When submitted will result in response consisting of User object as JSON string.

Accessing service via Java based Apache HttpClient API 

Below is the example to access the Liferay services using the Apache HTTPClient API
public static void get() throws Exception {
  HttpHost targetHost = new HttpHost("localhost", 8080, "http");
  DefaultHttpClient httpclient = new DefaultHttpClient();
  httpclient.getCredentialsProvider().setCredentials(
    new AuthScope(targetHost.getHostName(), targetHost.getPort()),
    new UsernamePasswordCredentials("test", "test"));

  // Create AuthCache instance
  AuthCache authCache = new BasicAuthCache();
  // Generate BASIC scheme object and add it to the local
  // auth cache
  BasicScheme basicAuth = new BasicScheme();
  authCache.put(targetHost, basicAuth);

  // Add AuthCache to the execution context
  BasicHttpContext ctx = new BasicHttpContext();
  ctx.setAttribute(ClientContext.AUTH_CACHE, authCache);

  HttpPost post = new HttpPost(
    "/api/jsonws/user/get-user-by-id"); 
  List<NameValuePair> params = new ArrayList<NameValuePair>();
  params.add(new BasicNameValuePair("userId", "10172"));
  
  UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
  post.setEntity(entity);
  HttpResponse resp = httpclient.execute(targetHost, post, ctx);
  System.out.println(resp.getStatusLine());
  resp.getEntity().writeTo(System.out);
  httpclient.getConnectionManager().shutdown();
 }


When submitted will result in response consisting of User object as JSON string.

Go to  Next post Part 3: Custom Liferay Plugin JSON Web Services

References:
The article is my summarized view while working on the topic and references have been taken from Liferay community and documentation

Part 1: Introduction Liferay JSON Web Services

JSON Web Services provide convenient way access to portal service layer methods by exposing them as JSON HTTP API. This makes services methods easily accessible using HTTP requests, not only from JavaScript within the portal, but also from any JSON-speaking client.

Registering JSON web services


While using Service Builder to build services via service.xml append each entity definition with remote-service="true" to create and enable web services for the entity.  By doing this All remote-enabled services (i.e. entities with remote-service="true" in service.xml) are exposed as JSON Web Services.

When Service Builder creates each -Service.java interface for a remote-enabled service, the @JSONWebService annotation is added on the class level of that interface. Therefore, all of the public methods of that interface become registered and available as JSON Web Services.

On server startup a restricted scanning is done on portal and service jar files for the classes that uses @JSONWebService annotation. Post this the annotation are loaded and service methods are exposed as JSON based API.

For example UserService looks as below:
@JSONWebService
public interface UserService{
...
}

 Accessing Services

Below is the convention used to access any service exposed by default Liferay bundle
http://[server]:[port]/api/jsonws/[service-class-name]/[service-method-name] 
service-class-name is the name generated from service class name, 
by removing the Service or ServiceImpl suffix and converting it to a 
lowercase name.
service-method-name is generated from the service method name, 
by converting the camel-case method name to a lowercase separated-by-dash name
For example UserService can be accessed as:
@JSONWebService
public interface UserService{

 public User getUserById(long userId) {...}
}


http://localhost:8080/api/jsonws/user-service/get-user-by-id

All methods prefixed with get, has, is are pre assumed to be readonly and thus are exposed as GET methods, leaving rest as POST methods.

Non-public service methods require the user to be registered before invoking the method and accessed as

http://[server]:[port]/api/secure/jsonws/[service-class-name]/[service-method-name]http://localhost:8080/api/jsonws/user-service/get-user-by-id

Viewing list of default liferay bundle service

You can view all the registered and available service listing ay accessing the below url
http://localhost:8080/api/jsonws
 
In my next post, I have further detailed about configuring and 
accessing the JSON Web services 
 
References:
The article is my summarized view while working on the topic and references have been taken from Liferay community and documentation

Wednesday, October 10, 2012

Java Concurrency / Multithreading: Part 3

In Previous post (Java Concurrency / Multithreading :Part 2) learn how to initialize and use ExecutorService.

There are numerous problem domains where while designing the application you will need to implement the thread pool and each thread after completing the task, based on inputs should return a value. Futures and Callables exist exactly to solve this area.

Till now we have implemented the thread pool (in previous post) using the Runnables which do not return any value. In case a thread should return a value based on computation or work done as part of task you can use java.util.concurremt.Callable. Callable return value after execution. Callable returns an object of java.util.concurrent.Future. Future is used to check the status of task and return some value. Below is the example to use Callable and return a value

public class MyRunnable implements Callable<Long> {  
     @Override  
     public Long call() throw Exception {  
       return 5L;  
     }  
   } 

Using the Executor Framework

public class Example {

    public static void main(String[] args) {



        ExecutorService executor = Executors.newFixedThreadPool(5);

        List<Future<Long>> fList = new ArrayList<Future<Long>>();

        for (int i = 0; i < 999; i++) {

            Callable<Long> worker = new MyRunnable();

            Future<Long> submit = executor.submit(worker);

            fList.add(submit);

        }

        long sum = 0;



        for (Future<Long> future : fList) {

            try {

            sum += future.get();

            } catch (InterruptedException e) {

            e.printStackTrace();

            } catch (ExecutionException e) {

            e.printStackTrace();

            }

        }

        System.out.println("Final Sum is : " + sum);

        executor.shutdown();

    }

} 

Java Concurrency / Multithreading: Part 2

See my earlier post (Java Concurrency / Multithreading :Part 1) related to basics about java threads and concurrency.

Executor Framework

ThreadPools is the way to manage the pool of working threads and limit the creation of thread as creating a thread have resource overhead associates with it. Thus thread pools contains a work queue waiting for their turn to get executed.

In thread pool, the thread are constantly running and checking the queue for new work. As soon as the pool have a idle thread the work is assigned to one of the threads.

With Java 5 came Executor Framework under java.util.concurrent package, so that you do not need to create and manage your own pool e.g java.util.concurrent.Executor can be initialized as Executors.newfixedThreadPool(n) to create n worker threads. 

Like wise Executors.newSingleThreadExecutor(); will create a single thread pool with only one worker thread.

Example:
Creating a Runnable class
public class MyRunnable implements Runnable {
    private final long count;
    MyRunnable(long count) {
        this.count = count;
    }
    @Override
    public void run() {
        long mySum = 0;
        for (long i = 1; i < count; i++) {
            mySum = mySum + i;
        }
        System.out.println(mySum);
    }
}

Using the Executor Framework
public class Example {

    public static void main(String[] args) {

        ExecutorService executor = Executors.newFixedThreadPool(5);

        for (int i = 0; i < 100; i++) {

            Runnable myworker = new MyRunnable(99999999L + i);

            executor.execute(myworker);

        }

        executor.shutdown();

        while (!executor.isTerminated()) {



        }

        System.out.println("Completed processing the work queue");

    }

} 


ExecutorService executor = Executors.newFixedThreadPool(5); creates a new pool of 5 worker threads.

executor.execute(myworker); adds new work in the queue for thread pool to complete.

executor.shutdown(); waits till all the work in the queue is completed. After calling this method the ExecutorService will not take any new task but once all the current tasks in the queue are complete the ExecutorService will shutdown.

To stop the ExecutorService immediately call shutdownNow() method.This will attempt to stop all executing tasks right away, and skips all submitted but non-processed tasks. There are no guarantees given about the executing tasks. Perhaps they stop, perhaps the execute until the end. It is a best effort attempt.

 executor.isTerminated() checks if the service is terminated or not.

Till now we have submitted the tasks to ExecutorService and never waited to get a return value after . Thus in case the threads should return some value then you should use java.util.concurrent.Callable. See my next post (Java Concurrency / Multithreading: Part 3) summarizing the above concept.

Tuesday, October 09, 2012

Java Concurrency / Multithreading :Part 1

Goal:

How to execute the tasks in background using Java concurrent programming. It also covers the concepts of threads, parallel programming, java.util.concurrent.Executor, java.util.concurrent.Future, java.util.concurrent.Callable framework.

Details:

What is Concurrency?

In computer world, concurrency means executing several programs simultaneously or in parallel and these programs may or may not interact with each other. Running several programs in parallel or asynchronously can add to over all performance of the task.

Process vs Threads

Both thread and process are methods of parallelizing the application. Below are the key points highlighting the differences between Process and Thread.

Process: are independent execution units. Applications are typically divided into various processes during the design phase. It cannot directly access shared data in other processes.However this is done by inter-process mechanism managed by operating system. A process might contain multiple threads.

Thread: are light weight processes and is the basic unit to which the operating system allocates processor time. A thread can execute any part of the process code, including parts currently being executed by another thread. . Every thread have its own memory cache.

Why Concurrency

  •  Efficient utilization of resources
  • Increased application throughput
  • High responsiveness
  •  Programs becomes simpler: as some of the problem domains are well suited to be represented as concurrent tasks

Disadvantages

  • With increased complexity the program design becomes more complex
  • Context Switching between threads, too many open threads will lead to context switching overheads causing the performance degrade

 Threads in Action

Threads are the core of all concurrent or parallel programing. There are 2 ways to implement thread in java.
The First one is extending java.lang.Thread class. Below is the way to create a thread:
Thread myThread =  new Thread();
Now after initialization , to start thread
myThread.start();

Create a subclass of Thread
public class CustomThread extends Thread{

 public void run(){
 System.out.println("Hello Thread");
}
}

Using the above class
CustomThread thread1 = new CustomThread();

thread1.start()
The second way is to implement the java.lang.Runnable interface.
public class MyRunnable implements Runnablee{
public void run (){

System.out.println("Hello Runnable"); 

} 

}
Using the above class
Thread thread1 =  new Thread(new MyRunnable);

thread1.start();
Next>>> Java Concurrency / Multithreading: Part 2