Tuesday, 7 April 2015

Exception in hibernate-spring-data

Caused by: org.hibernate.HibernateException: Connection cannot be null when 'hibernate.dialect' not set

Set the below property in the persistence.xml file

      <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>

Wednesday, 28 January 2015

Nuke python console output

When you start a python/cherrypy web server, by default, will log onto the console. One can disable this by using property "log.screen" in global properties

log.screen = False

or cherrypy configuration in the code

cherrypy.config.update({..., 'log.screen':False,})

Read properties from configuration file in Python

It's always recommended to keep properties such as username, password, .. etc in .cfg files, instead of code. (Debate of appropriate/correct approach is out of context :) )

Let's say we have application configurations in a file "app.cfg". Contents of the "app.cfg" file:

[default]
host=abc.xyz.com
...
...

[mysql]
username=root
password=root
...

Let's look at the python code snippet to read the above application properties.

import ConfigParser

# class definition
class <class_name>:
    def __init__(self):
        ##### read properties
        config = ConfigParser.RawConfigParser()
        config.read(self.__file_path('app.cfg'))
        user = config.get('mysql', 'user')
        password = config.get('mysql', 'password')

# some other code funtionality
....


Default thread pool for Cherrypy web server

In the previous post, we have seen creating a web service using cherrypy. Cherrypy has thread default pool size as 10. One should modify/change the configuration by giving property "server.thread_pool".

Code snippet for configuration of thread pool is:

cherrypy.config.update({'server.socket_host': '0.0.0.0','server.socket_port': 8090,'server.thread_pool': 50,})

Note: For other attributes of cherrypy.quickstart(), please refer here

Tuesday, 27 January 2015

Python web server using Cherrypy

Recently, I came across a situation where I was supposed to use python to build a web service. At that time, I didn't even know the syntax of python language. Thanks to Cherrypy module, it's very easy and robust.

I will be showing here the code snippet to create a web service (restful api end point)

(I am not giving steps to install python or cherrypy module installation)

Create a file, say, helloworld.py and add below content.

# import cherrypy module
import cherrypy

# class definition
class HelloWorldService(object):
     # this annotation exposes the behavior
    @cherrypy.expose
    # status behavior definition
    def status(self):
        return"OK"

    @cherrypy.expose
    # sayhello behavior with path params

    def sayhello(selfi, *args):
        pathParam = args[0]
        msg = "Hello %s" %(pathParam)
        return msg

# define configuration
if __name__ == '__main__':
    conf = {
          '/' : {
                        'tools.response_headers.on': True,
                        'tools.response_headers.headers': [('Content-Type', 'application/json'), ('Server', '')]
           }
    }

webapp = HelloWorldService()
# starting the server, by default it run on port 8080, we can change this un-comment below line

# cherrypy.config.update({'server.socket_host': '0.0.0.0','server.socket_port': 8090,})
cherrypy.quickstart(webapp, '/', conf)

After this, start the server.
$ python helloworld.py

Once it starts, try accessing below url.
http://localhost:8080/status/
http://localhost:8080/sayhello/sateesh/




Tuesday, 18 November 2014

How to push maven artifacts to s3 bucket

I have written here about pushing third party artifacts to remote repository . Now, I will share here details about pushing artifacts to s3.

If we use default maven wagon connector to push artifacts to s3 buckett, we would come across below issue.

No connector available to access repository  <repository_name> (<repository_url>) of type default using the available factories WagonRepositoryConnectorFactory -> [Help 1]


To overcome this, we should use below code-snippet within <build> tags.

        <extensions>
            <extension>
                <groupId>org.springframework.build</groupId>
                <artifactId>aws-maven</artifactId>
                <version>${aws-maven.version}</version>
            </extension>
        </extensions>


Now, what does this code snippet do?

This means, adding the artifact "aws-maven" in the class path of maven build, so that aws-maven wagon connector will push artifacts to s3 bucket.

Wednesday, 15 October 2014

Implementation of ThreadPoolExecutor

I will explain implementation of ThreadPoolExecutor.class here!


 ThreadPoolExecutor class has four constructors, using which one can obtain ThreadPoolExecutor instance.

(1)
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }


(2)
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             threadFactory, defaultHandler);
    }


(3)
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              RejectedExecutionHandler handler) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), handler);
    }


(4)
public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }



Out of 4 constructors mentioned above, if you observer,  both 1 & 2, variable defaultHandler is passed to create the instance. So, what is defaultHandler?

private static final RejectedExecutionHandler defaultHandler =
        new AbortPolicy();



public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            throw new RejectedExecutionException("Task " + r.toString() +" rejected from " +  e.toString());
        }



defaultHandler throws RejecctedExecutionException whenever there is no thread available to execute the job.

If you want to have metric logs for thread rejection execution exception, it is recommended to create a separate implementation for RejectedExecutionHandler.

This can be done as mentioned below.

(a) Create RejectedExecutionHandlerImpl class

public class RejectedExecutionHandlerImpl implements RejectedExecutionHandler {

    @Override
    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
        // log rejection metrics here
    }
}


(b) Create ThreadPoolExecutor

RejectedExecutionHandlerImpl rejectionHandler = new RejectedExecutionHandlerImpl();

ThreadFactory threadFactory = Executors.defaultThreadFactory();

ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(minThreadCount, maxThreadCount, threadAliveTime, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(poolQueueSize), threadFactory, rejectionHandler);





Sunday, 31 August 2014

Aws Kinesis Integration (sending messages to kinesis)

I will be sharing here details about integration of Aws Kinesis here. If you have bit time, I would recommend you to visit here


1. Create a properties file for Kinesis.

@Component
public class KinesisProp {

    @Value("${kinesis.access.key}")
    private String  awsAccessKey;
    @Value("${kinesis.secret.key}")
    private String  awsSecretKey;
    @Value("${kinesis.streamName}")
    private String streamName;
    @Value("${kinesis.receive.limit}")
    private Integer receiveLimit;
    @Value("${kinesis.shradCount}")
    private Integer shardCount;
    @Value("${kinesis.region}")
    private String region;
    @Value("${kinesis.steam.initialPosition}")
    private String streamInitialPosition;
    @Value("${kinesis.endPoint}")
    private String endPoint; 


    // getters and setters here

}

2. Create a service call, which will be responsible for sending messages to Kinesis.

@Component
public class KinesisService {
    private static final Logger logger = LoggerFactory.getLogger(KinesisService.class);
    @Autowired
    private KinesisProp kinesisProp;
    private AmazonKinesisClient kinesisClient;
 

    @PostConstruct
    private void init() {
        try {
            instantiateKinesisClient();
        } catch (Exception e) {
            logger.error("Exception occurred while instantiating the Kinesis Client", e);
        }
    }

    private void instantiateKinesisClient() throws IOException {
        BasicAWSCredentials  credentials = new BasicAWSCredentials(this.kinesisProp.getAwsAccessKey(), this.kinesisProp.getAwsSecretKey());
        kinesisClient = new AmazonKinesisClient(credentials);
        final Region apac_east = Region.getRegion(Regions.valueOf(kinesisProp.getRegion()));
        kinesisClient.setRegion(apac_east);
        createStream();
    }

    private void createStream() {
        final ListStreamsRequest listStreamsRequest = new ListStreamsRequest();
        ListStreamsResult listStreamsResult = kinesisClient.listStreams(listStreamsRequest);
        if (listStreamsResult == null || listStreamsResult.getStreamNames().isEmpty() ||
                (!listStreamsResult.getStreamNames().contains(kinesisProp.getStreamName()))) {

            CreateStreamRequest createStreamRequest = new CreateStreamRequest();
            createStreamRequest.setStreamName(kinesisProp.getStreamName());
            createStreamRequest.setShardCount(kinesisProp.getShardCount());

            try {
                kinesisClient.createStream(createStreamRequest);
            } catch (Exception e) {
                logger.error("Error occurred while creating the stream!", e);
            }
        }
    }

    public void sendMessage(final String message) throws AmazonServiceException {
       PutRecordRequest putRecordRequest = new PutRecordRequest();
 putRecordRequest.setStreamName(kinesisProp.getStreamName());
 putRecordRequest.setData(ByteBuffer.wrap(message.getBytes()));                                                                      putRecordRequest.setPartitionKey(Constants.AWS_KINESIS_PARTITION_KEY);
          kinesisClient.putRecord(putRecordRequest);
    }
 

}


3. Fetching the messages can be done in two ways.

(a) Using Aws Kinesis API
(b) Using Aws Kinesis Client Library.

I will update on this in my next blog.

Note:
(a) Spring is used for DI.
(b) When you are creating the access key and secret key, make sure to create for the kinesis app.

Monday, 11 August 2014

Embedded jetty server with web app

Recently, I come across a situation where both maven-jetty plugin & embedded jetty server need to packed along with web-application. I have already written a blog on incorporating maven-jetty plugin in the web app here, hence will not be discussing here again. I will describe here about package of embedded jetty server with in web application below.

Firstly, why do we require to include embedded jetty?
1. Easy deployment, java -jar <web-app>.jar, once you build the artifact, it's ready for deployment without any hassle configurations/deployment procedures, etc
2. No requirement of application server.


Let's go through the following steps to include jetty server within web app.

1. Create a JettyServer class


package com.sateesh.application.server;

import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.webapp.WebAppContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.DispatcherServlet;

import java.io.IOException;


public class JettyServer {

    private static final Logger logger = LoggerFactory.getLogger(JettyServer.class);
    private final String WEB_APP_DIR = "src/main/webapp";
    private final String WEB_XML_PATH = "src/main/webapp/WEB-INF/web.xml";
    private static final String MVC_SERVLET_NAME = "dispatcher";
    private static final String JSP_SERVLET_NAME = "jspServlet";
    private static final String DEFAULT_PORT = "8080";
    private static final String DEFAULT_CONTEXT_PATH = "/";



    public static void main(String[] args) throws Exception{
        JettyServer jettyServer = new JettyServer();
        jettyServer.start();
    }

    private JettyServer() {

      // none can instantiate this class
    }

    private void start() throws Exception{
        try {
            QueuedThreadPool threadPool = new QueuedThreadPool(512);

            final Server server = new Server(threadPool);
            server.setStopAtShutdown(true);
            server.setStopTimeout(5000);

            ServerConnector connector = new ServerConnector(server);
            connector.setPort(getPort());
            connector.setIdleTimeout(30000);
            server.setConnectors(new Connector[]{connector});
            server.setHandler(getServletContextHandler());

            server.start();
            server.join();
            logger.info("Embedded Jetty Server is started!");
        } catch (Exception e) {
            logger.error("Exception occurred while starting the jetty server ", e);
        }
    }

    private WebAppContext getServletContextHandler() throws IOException {
        final WebAppContext contextHandler = new WebAppContext();
        contextHandler.setContextPath(getContextPath());
        contextHandler.setWar(WEB_APP_DIR);
        contextHandler.setDefaultsDescriptor(WEB_XML_PATH);
        ServletHolder jspServletHolder = new ServletHolder("jspServlet", new org.apache.jasper.servlet.JspServlet());

        // jsp servelet is required to parse the jsp passed by the spring-mvc  
        contextHandler.addServlet(jspServletHolder, "*.jsp");
        return contextHandler;
    }

 

  /**
  * Consider default port as "8080" until unless not passed using java args
  **/  private int getPort() {
        Integer port = Integer.parseInt(System.getProperty("jetty.port"));

        if (port == null || port == 0) {
            port = Integer.parseInt(DEFAULT_PORT);
        }

        return port;
    }

    

  /**
  * Consider default context path as "/" until unless not passed using java args
  **/
  private String getContextPath() {
        String contextPath = System.getProperty("jetty.contextPath");

        if (contextPath == null ||  contextPath.equals("")) {
            contextPath = DEFAULT_CONTEXT_PATH;
        }

        return contextPath;
    }

}



2. Contents of web.xml (default descriptor executed by JettyServer).

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        id="YourWebAppID"
        version="2.5">

    <display-name>Web App Server</display-name>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:META-INF/spring/application-context.xml
        </param-value>
    </context-param>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>

</web-app>



3. Contents of application-context.xml & dispatcher-servlet.xml files

application-context.xml --- is spring descriptor file. 
dispatcher-servlet.xml --- is servlet dispatcher file, which will scan @Controller annotated packages.


4. Package structure of the project

   --- src
       --- main
           --- java 
               --- com.sateesh.application.server
           --- resources
               --- META-INF
                   --- spring
                       --- application-context.xml
               --- dispatcher-servlet.xml
               --- logback.xml
           --- webapp
               --- views
                   ---  ***.jsp
               --- web.xml


5. below plugin needs to be added in pom.xml

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>META-INF/*.SF</exclude>
                                        <exclude>META-INF/*.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                            <createDependencyReducedPom>true</createDependencyReducedPom>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.sateesh.application.server.JettyServer</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>


6. add below dependencies in pom.xml

    <properties>
        <jetty.server.scope>compile</jetty.server.scope>
        <jetty.version>9.1.2.v20140210</jetty.version>
    </properties>


        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>${jetty.version}</version>
            <scope>${jetty.server.scope}</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-webapp</artifactId>
            <version>${jetty.version}</version>
            <scope>${jetty.server.scope}</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>${jetty.version}</version>
            <scope>${jetty.server.scope}</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-jsp</artifactId>
            <version>${jetty.version}</version>
            <scope>${jetty.server.scope}</scope>
        </dependency>


7. You are almost there.. now run the web application now.

build the project (default package is jar in maven):
mvn clean package

run the webapp:
java -jar target/webapp.jar


PS: we can also create embedded jetty server with in web-app without web.xml file also.

Thursday, 31 October 2013

Performance improvement in JSF2

Recently, I come across performance issues with JSF2. The challenge was to improve the time response for rendering the page. I am here with configuration of jsf2 parameters, which helped us to reduce the time response to render the page contents,

Set the state method as server.

        <context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>

Limit the number of views in session to small number.

    <context-param>
            <param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name>
            <param-value>15</param-value>
    </context-param>

Don't serialize the state, set the compress state as false
    <context-param>
        <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
        <param-value>false</param-value>
    </context-param>


    <context-param>
        <param-name>org.apache.myfaces.COMPRESS_STATE_IN_SESSION</param-name>
        <param-value>false</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.PRETTY_HTML</param-name>
        <param-value>false</param-value>
    </context-param>


cache the el-expressions
    <context-param>
        <param-name>org.apache.myfaces.CACHE_EL_EXPRESSIONS</param-name>
        <param-value>always</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.CHECK_ID_PRODUCTION_MODE</param-name>
        <param-value>false</param-value>
    </context-param>



below parameters are added to not refresh facelets for static pages
    <context-param>
        <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
        <param-value>-1</param-value>
    </context-param>
    <context-param>
        <param-name>facelets.REFRESH_PERIOD</param-name>
        <param-value>-1</param-value>
    </context-param>
    <context-param>
        <param-name>facelets.DEVELOPMENT</param-name>
        <param-value>false</param-value>
    </context-param>



Sunday, 7 July 2013

Dynamically displaying the modification of .xhtml files in JSF/MyFaces apps

To see any changes in the static files of jsf/myfaces application at run time, we need to add following context-params in the web.xml file.


<!-- below parameters are added to refresh facelets for static pages -->
    <context-param>
        <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
        <param-value>1</param-value>
    </context-param>
    <context-param>
        <param-name>facelets.REFRESH_PERIOD</param-name>
        <param-value>1</param-value>
    </context-param>
    <context-param>
        <param-name>facelets.DEVELOPMENT</param-name>
        <param-value>true</param-value>
    </context-param>


Thursday, 4 July 2013

Tiles framework for Jsps

I am here with the introduction of tiles framework for Java Servlet Page (JSP)s. I am not giving the information on integration of tiles with sturts/spring here. It is simple tiles usage with jsps.

Following the steps. Considering web app is build by maven tool, tiles version is 2.1.2.

1. Maven dependencies required to include in the project object model file pom.xml


       <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-extras</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-core</artifactId>
            <version>2.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-servlet</artifactId>
            <version>2.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-jsp</artifactId>
            <version>2.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-api</artifactId>
            <version>2.1.2</version>
        </dependency>


2. Modifications in web descriptor file web.xml


    <!-- listener needs to be added for tiles -->

    <listener>
        <listener-class>org.apache.tiles.web.startup.TilesListener</listener-class>
    </listener>


    <!-- servlet needs to be added for tiles -->


    <servlet>
        <servlet-name>tiles</servlet-name>
        <servlet-class>org.apache.tiles.web.startup.TilesServlet</servlet-class>
        <init-param>
            <param-name>
                org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG
            </param-name>
            <param-value>
                /WEB-INF/tiles-defs.xml
            </param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet>


3. Add a tiles descriptor file tiles-defs.xml file


<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
        "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
<tiles-definitions>

    <definition name="unauthorized_default" template="/appName/templates/layout.jsp">
        <put-attribute name="header" value="/appName/templates/nonAuthenticatedHeader.jsp" />
        <put-attribute name="menu" value="/appName/templates/menu.jsp" />
        <put-attribute name="body" value="/appName/templates/body.jsp" />
        <put-attribute name="footer" value="/appName/templates/footer.jsp" />
    </definition>

    <definition name="authorized_default" template="/appName/templates/layout.jsp">
        <put-attribute name="header" value="/appName/templates/header.jsp" />
        <put-attribute name="menu" value="/appName/templates/menu.jsp" />
        <put-attribute name="body" value="/appName/templates/body.jsp" />
        <put-attribute name="footer" value="/appName/templates/footer.jsp" />
    </definition>

    <definition name="authorized_home" template="/appName/templates/layout_leftmenu.jsp">
        <put-attribute name="header" value="/appName/templates/header.jsp" />
        <put-attribute name="menu" value="/appName/templates/menu.jsp" />
        <put-attribute name="leftMenu" value="/appName/templates/leftMenu.jsp" />
        <put-attribute name="body" value="/appName/templates/body.jsp" />
        <put-attribute name="footer" value="/appName/templates/footer.jsp" />
    </definition>

</tiles-definitions>




4. Template files required to add:

(a) layout.jsp

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>



      <table width="100%">
      <tr>
        <td>
          <tiles:insertAttribute name="header" />
        </td>
      </tr>
      <tr>
        <td>
          <tiles:insertAttribute name="menu" />
        </td>
      </tr>
      <tr>
        <td>
          <tiles:insertAttribute name="body" />
        </td>
      </tr>
      <tr>
        <td>
          <tiles:insertAttribute name="footer" />
        </td>
      </tr>
    </table>

(b) layout_leftmenu.jsp

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>



      <table width="100%">
      <tr>
        <td colspan="2">
          <tiles:insertAttribute name="header" />
        </td>
      </tr>
      <tr>
        <td colspan="2">
          <tiles:insertAttribute name="menu" />
        </td>
      </tr>
      <tr>
        <td width="25%">
          <tiles:insertAttribute name="leftMenu" />
        </td>
        <td>
          <tiles:insertAttribute name="body" />
        </td>
      </tr>
      <tr>
        <td align="center">
          <tiles:insertAttribute name="footer" />
        </td>
      </tr>
    </table>




5. Calling the tiles definitions on any jsp


<html>
<body>
    <div align="center" width="100%">
        <tiles:insertDefinition name="unauthorized_default">
            <tiles:putAttribute name="menu" value="/callCenter/templates/blank.jsp" />
            <tiles:putAttribute name="body" value="/callCenter/loginPage.jsp" />
        </tiles:insertDefinition>
    </div>
</body>
</html>





Wednesday, 3 July 2013

URL change while redirecting the page in JSF application

In JSF applications, url will not be changing while redirecting the page using navigation rules. However, sometimes, it might be a damn need to change the url while redirecting from one page to another page. This request can be fulfilled by following way.

In general navigation rule is defined as:

<navigation-rule>
       <from-view-id>/callCenter/crmLogin.jsp</from-view-id>
       <navigation-case>
<from-outcome>gotoMainPanel</from-outcome>
<to-view-id>/callCenter/crmMainPanel.jsp</to-view-id>
       </navigation-case>
</navigation-rule>

However, you need to add <redirect /> tag to do the url change as mentioned below.


<navigation-rule>
       <from-view-id>/callCenter/crmLogin.jsp</from-view-id>
       <navigation-case>
<from-outcome>gotoMainPanel</from-outcome>
<to-view-id>/callCenter/crmMainPanel.jsp</to-view-id>
                <redirect />
</navigation-case>
</navigation-rule>

PS: Navigation rules are mentioned in the faces-config.xml file ( inside WEB-INF directory)

Monday, 17 June 2013

Clustering of tomcat servers

I am here with brief notes on how to form a clustering on tomcat servers.

1. Set up two tomcat servers (tomcat-pri & tomcat-sec)
2. In the setup of tomcat-pri, go the conf directory, and add following content in the server.xml file in the <Host> tag.

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
                 channelSendOptions="6">

          <Manager className="org.apache.catalina.ha.session.BackupManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"
                   mapSendOptions="6"/>

          <Channel className="org.apache.catalina.tribes.group.GroupChannel">
            <Membership className="org.apache.catalina.tribes.membership.McastService"
                        address="228.0.0.4"
                        port="45564"
                        frequency="500"
                        dropTime="3000"/>
            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                      address="auto"
                      port="5000"
                      selectorTimeout="100"
                      maxThreads="6"/>

            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
              <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
            </Sender>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
          </Channel>

          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                 filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/>

          <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                    tempDir="/tmp/war-temp/"
                    deployDir="/host/Work/servers/tomcat-pri/webapps"
                    watchDir="/tmp/war-listen/"
                    watchEnabled="true"/>

          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
        </Cluster>

NOTE: If you observe carefully, the server.xml will have <Cluster> tag is commented out with in the <Engine> tag. However, we need to keep the <Cluster> tag with in the <Host> tag.


3. In the setup of tomcat-pri, go the conf directory, and edit the server.xml file.
Change the port information so that, you wouldn't see port already used messages in the logs.
(i) Server Port
(ii) Connector Port (two places)


4. Also add following content in the server.xml file of tomcat-sec setup.

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
                 channelSendOptions="6">

          <Manager className="org.apache.catalina.ha.session.BackupManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"
                   mapSendOptions="6"/>
          <!--
          <Manager className="org.apache.catalina.ha.session.DeltaManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"/>
          -->
          <Channel className="org.apache.catalina.tribes.group.GroupChannel">
            <Membership className="org.apache.catalina.tribes.membership.McastService"
                        address="228.0.0.4"
                        port="45564"
                        frequency="500"
                        dropTime="3000"/>
            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                      address="auto"
                      port="5020"
                      selectorTimeout="100"
                      maxThreads="6"/>

            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
              <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
            </Sender>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
          </Channel>

          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                 filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/>

          <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                    tempDir="/tmp/war-temp/"
                    deployDir="/host/Work/servers/apache-tomcat-7.0.41-sec/webapps"
                    watchDir="/tmp/war-listen/"
                    watchEnabled="true"/>

          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
        </Cluster>

5. Now, deploy the web-application artifact in the directory "/tmp/war-listen"

6. Start the tomcat-pri server

7. Start the tomcat-sec server (once tomcat-pri server is started)

8. You would observer following in logs.

Jun 17, 2013 1:53:11 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
Jun 17, 2013 1:53:11 PM org.apachecatalina.startup.Catalina load
INFO: Initialization processed in 524 ms
Jun 17, 2013 1:53:11 PM org.apache..coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-bio-8009"]
Jun 17, 2013 1:53:11 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Jun 17, 2013 1:53:11 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.41
Jun 17, 2013 1:53:11 PM org.apache.catalina.ha.tcp.SimpleTcpCluster startInternal
INFO: Cluster is about to start
Jun 17, 2013 1:53:11 PM org.apache.catalina.tribes.transport.ReceiverBase bind
INFO: Receiver Server Socket bound to:/127.0.1.1:5000
Jun 17, 2013 1:53:11 PM org.apache.catalina.tribes.membership.McastServiceImpl setupSocket
INFO: Setting cluster mcast soTimeout to 500
Jun 17, 2013 1:53:11 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Sleeping for 1000 milliseconds to establish cluster membership, start level:4
Jun 17, 2013 1:53:12 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Done sleeping, membership established, start level:4
Jun 17, 2013 1:53:12 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Sleeping for 1000 milliseconds to establish cluster membership, start level:8
Jun 17, 2013 1:53:13 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Done sleeping, membership established, start level:8
Jun 17, 2013 1:53:13 PM org.apache.catalina.ha.deploy.FarmWarDeployer start
INFO: Cluster deployment is watching [/tmp/war-listen/] for changes.
Jun 17, 2013 1:53:13 PM org.apache.catalina.ha.deploy.FarmWarDeployer start
INFO: Cluster FarmWarDeployer started.

Thursday, 13 June 2013

Configuration of Jetty-Maven plugin to a web app

In present era development process, everybody is primarily concerned about faster development process, because of which development environment has become vital in the project implementation plan.

Jetty is the one of the light weight application server, which can be run on stand-alone or using maven plugin. I am here giving the configuration details of later one.

(One assumption here is, reader has the knowledge of Maven)

1. Add jetty-maven plugin in the plugins section of pom.xml


           <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>8.1.9.v20130131</version>
                <configuration>
                    <connectors>
                        <connector  implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
                            <port>8080</port>
                        </connector>
                    </connectors>
                    <stopPort>18080</stopPort>
    <scanIntervalSeconds>0</scanIntervalSeconds>
    <webXml>target/classes/web.xml</webXml>
    <webApp>
           <contextPath>/</contextPath>
    </webApp>
                </configuration>
                <dependencies>
                    // any dependencies required can be added here
                    // if you project has dependency on jsf, add jsf dependencies here too.
                </dependencies>
            </plugin>


2. Go to the terminal and change directory to base directory of project and run the server using below command.

mvn jetty:run

PS: Maven Options might need to be mentioned

(i) Perm Genspace attributes:
MAVEN_OPTS="-Xmx1024m -XX:MaxPermSize=256m"

(ii) Starting jetty server in debug mode with Perm Genspace attributes:
MAVEN_OPTS="-Xmx1024m -XX:MaxPermSize=256m -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=4000,server=y,suspend=y"

Thursday, 16 May 2013

Dynamically changing the enum type ids

Have you ever felt, modelling a "STATUS" column as a enum type in any of your ticketing system?? Obviously, most of the people opt for it. I am here with one of example here...

eg:

public enum Status {
      
     OPEN("Open" , 1),
     IN_PROGRESS("In_Progress", 2),
     RESOLVED("Resolved", 3),
     CLOSE("Close", 4);

     private String name;
     private Integer id;

     private Status(String name, Integer id) {
           this.name = name;
           this.id = id;
     }

     public String getName() {
             return this.name;
     }

     public Integer getId() {
            return this.id;
     }
}

In the above mentioned enum class, whenever we change the id of the statuses due to environmental specific reasons, developers need to modify this enum class to keep the mapping between state names and the state ids.

How can we capture only state names in the enums, and ids need to be captured during the start of application dynamically??



public enum Status {

    OPEN ("Open"),

 IN_PROGRESS("In_Progress"),
     RESOLVED("Resolved"),

    CLOSE("Close");


    private String name;
    private Integer id;

    private CaseStatus(final String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String toString() {
        return this.name;
    }
}

Now, how do we map the ids with the states? Now, we will have a configuration class, which helps this. Of course, I have used the spring abilities here, you may use which is relevant for your scenarios.



import Status;
import models.Status;
import repositories.StatusRepository;
import org.springframework.stereotype.Service;
import play.Logger;
import sun.reflect.ReflectionFactory;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Service
public class StatusConfiguration {

    private static ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();

    @Resource
    private StatusRepository statusRepository;


    @PostConstruct
    private void initialize() {
        Map<String, Integer> statuses = this.fetchStatuses();

        if (null != statuses && !statuses.isEmpty()) {
            this.updateStatusEnum(statuses);
        }
    }

    public Map<String, Integer> fetchStatuses() {
        Map<String, Integer> statuses = null;
        try {
            List<Status> statusList = this.statusRepository.findAll();
            if (null != statusList && !statusList.isEmpty()) {
                statuses = new HashMap<String, Integer>(statusList.size());
                for (Status status : statusList) {
                    statuses.put(status.getName(), status.getId());
                }
            }
        } catch (Exception ex) {
            Logger.error("Error while fetching statuses information!", ex);
        }
        return statuses;
    }

    private void updateStatusEnum(Map<String, Integer> statuses) {
        Iterator<Map.Entry<String, Integer>> iterator = statuses.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Integer> status = iterator.next();
            this.updateStatusEnumIds(statuses);
        }
    }

    private void updateStatusEnumIds(Map<String, Integer> statuses) {
        for (Status status : Status.values()) {
            Integer statusId = statuses.get(status.toString());
            if (null != statusId) {
                status.setId(statusId);
            }
        }
    }

}