Friday, October 11, 2013

XMPP

What is XMPP?
- XMPP is communication protocol for message-oriented middleware based on XML.
Originally called Jabber, developed for instant messaging, presence info and contact list maintenance.
XMPP specs published in RFC 6120/21/22.

  • RFC 6120: XMPP Core
  • RFC 6121: XMPP IM
  • RFC 6122: XMPP Address Format

Strengths:

  • Mature, Open Standards based technology
  • Secure (SASL and TLS)
  • Extensible – Several extensions exist today (http://xmpp.org/xmpp-protocols/xmpp-extensions/) 

Weaknesses:

  • Binary data transfer (e.g. file transfer) is inefficient (as it requires converting to Base64 encoded form).

Core includes:
  • XML streaming layer
  • Security: SASL and TLS
  • Presence: Built-in information about network availability
  • Rosters: Presence-enabled contact lists
XMPP defines 2 fundamental terms with respect to messaging:
  • Stream – Open XML envelope sent before more XML elements are exchanged between two entities.
  • Stanza – XML elements exchanged between 2 entities. 3 types:
    • Presence
    • Message
    • IQ – information or query
Client sends:
xml version="1.0"?>
<stream:stream to="example.com" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0">
Server acknowledges by sending:
"?>
 <stream:stream from="example.com" id="someid" xmlns="jabber:client" xmlns:stream="http://etherx.jabber.org/streams" version="1.0">
... encryption, authentication, and resource binding ...
Client sends message:
xml:lang="en"> Art thou not Romeo, and a Montague?
Server forwards message to client:
xml:lang="en"> Neither, fair saint, if either thee dislike.
Client closes its stream/session:
</stream:stream>
Server closes its session:
</stream:stream>

Message – to/from = Jabber IDs. 
Wherefore art thou, Romeo?
IQ – Info/Query. 

  • Get/Set
  • Result
  • Error
  • Roster - Rosters are stored on the server so that the XMPP client may retrieve the same each time the user logs in. Rosters are a type of IQ Stanza. Example showing IQ message to request for roster.



Presence – the presence info of a user is broadcasted from server to all users in roster list of that user. This works using the PubSub messaging.

Bi-directional streams Over Synchronous HTTP (BOSH)


  • It is a long-lived 2 way communication over HTTP.
    • Significantly more bandwidth efficient over http (compared to other technologies – such as AJAX)
    • Applications requiring both “push” and “pull” communications
    • http://xmpp.org/extensions/xep-0124.html
  • Avoids http polling for more efficiency and low latency


PubSub

  • Each user is assigned a unique Jabber ID. 
  • XMPP server manages the messages published to a certain node (topic) and delivers the messages to all subscribers for that node.
  • Messages may contain payload.
  • Messages may be persistent.

XMPP Libraries for Application Programming

  • Smack API – Java API for XMPP clients.
  • Can be used to:
    • Connect to the XMPP server with user’s JID
    • Get the user’s roster from XMPP server
    • Sending and receiving different type of Stanzas (IQ, Message and Presence).
    • Publish messages to nodes 
    • Subscribe to nodes of interest.
    • File transfer/Group chat support also available.
  • http://www.igniterealtime.org/projects/smack/index.jsp 

Network Management over XMPP
  • Arista’s CloudVision framework Multi-Switch CLI extension uses XMPP to provide a shared message bus for managing and configuring switches. This is based on the idea from Internet of Things extension for XMPP (http://xmpp.org/extensions/xep-0324.html). 
  • Arista Switches run an XMPP client and respond to CLI commands. 
  • User can use any XMPP client (like iChat) on phone or PC to execute CLI on switches.
  • A single login to XMPP server gives secure access to all switches.
  • Switches can participate in group chats – meaning CLI can be executed on all participating switches in batch.
  • A Switch can be in more than one chat room at the same time. Command executed in a given chat room, is executed on all participating switches in that chat room.
  • Arista uses ejabberd XMPP server (included with fedora distro).
  • Arista uses SleekXMPP client.
  • If 2 switches are connected via XMPP, you can run CLI commands on switch A directly from switch B using xmpp send CLI command.
XMPP with Primefaces

  • Primefaces uses Atmosphere framework for implementing server push (PrimePush) - http://blog.primefaces.org/?p=2053.
  • Atmosphere comes with a plug-in for BOSH/XMPP (https://github.com/Atmosphere/atmosphere/wiki/Atmosphere-PlugIns-and-Extensions#xmpp)
References

  • Fun with XMPP and Google Talk - http://www.adarshr.com/papers/xmpp
  • Smack API - http://www.igniterealtime.org/projects/smack/index.jsp
  • XMPP Technology overview - http://xmpp.org/about-xmpp/technology-overview/
  • Arista’s Network Management over XMPP - https://eos.aristanetworks.com/2011/08/management-over-xmpp/

Friday, October 04, 2013

Ant build script for a simple Java Web App

<?xml version="1.0"?> 
<project name="MyWebApp" default="dist" basedir=".">
 <property name="build" location="bin" />
 <property name="src" location="src" />
 <property name="dist" location="dist" />
 <property name="web" location="web" />
 <!-- Set up the 'env' prefix for environment variables -->
 <property environment="env" />
 <property name="lib" location="lib" />
 <property name="version.num" value="1.0" />
 <path id="classpath">
  <fileset dir="${lib}">
   <include name="**/*.jar" />
  </fileset>
  <fileset dir="${env.TOMCAT_HOME}/lib">
   <include name="**/*.jar" />
  </fileset>
 </path>
 
 <!-- get the source compile classpath in a printable forms -->
 <pathconvert pathsep="${line.separator}|   |-- " property="echo.path.compile" refid="classpath">
 </pathconvert>
 
 <!-- 0. Abort the build if TOMCAT_HOME is not set -->
 <target name="checkTomcatHome" unless="env.TOMCAT_HOME">
  <fail message="TOMCAT_HOME must be set!" />
 </target>
 
 <!-- 0. PRINT DEFAULTS. -->
 <target name="print_default_properties">
  <echo message="os.name:          ${os.name}" />
  <echo message="basdir:           ${basedir}" />
  <echo message="ant.file:         ${ant.file}" />
  <echo message="ant.project.name: ${ant.project.name}" />
  <echo message="ant.java.version: ${ant.java.version}" />
  <echo message="tomcat_base:      ${env.TOMCAT_HOME}" />
  <echo message="|-- compile classpath" />
  <echo message="|   |" />
  <echo message="|   |-- ${echo.path.compile}" />
 </target>
 
 <!-- 1. CLEAN the build generated artifacts. -->
 <target name="clean">
  <delete dir="${build}" />
  <delete dir="${dist}" />
 </target>
 <!-- 2. INITIALIZE the build. -->
 <target name="init" depends="print_default_properties, checkTomcatHome">
  <mkdir dir="${build}" />
 </target>
 <!-- 3. COMPILE the source files. -->
 <target name="compile" depends="init">
  <!-- Compile the java code -->
  <javac srcdir="${src}" destdir="${build}" classpathref="classpath" debug="on" />
 </target>
 <!-- 4. Create the DISTRIBUTION. -->
 <target name="dist" depends="compile">
  <mkdir dir="${dist}" />
 
  <copy todir="${build}">
   <fileset dir="${basedir}">
    <include name="*.properties" />
    <include name="*.xml" />
    <include name="*.xsd" />
   </fileset>
  </copy>
 
  <war destfile="${dist}/${ant.project.name}.war" webxml="${web}/WEB-INF/web.xml">
   <manifest>
    <attribute name="Built-By" value="${user.name}" />
    <attribute name="Implementation-Version" value="${version.num}" />
    <attribute name="Built-Date" value="${TODAY}" />
   </manifest>
   <fileset dir="${web}" />
   <lib dir="${lib}">
    <include name="**/*.jar"/>
   </lib>
   <classes dir="${build}" />
  </war>
 </target>
 
 <!-- 5. DEPLOY the generated WAR to tomcat. -->
 <target name="deploy" depends="dist">
  <echo>Deploying to ${env.TOMCAT_HOME}</echo>
  <copy todir="${env.TOMCAT_HOME}/webapps">
   <fileset dir="${dist}">
    <include name="${ant.project.name}.war" />
   </fileset>
  </copy>
 </target>
 
 <!-- HELP -->
 <target name="help">
  <echo message="help         - Displays help menu">
  </echo>
  
  <echo message="compile      - (default) Builds Java classes">
  </echo>
  <echo message="dist         - Creates web applicaiton .war ">
  </echo>
  <echo message="clean        - Delete built .class and .war files, leave directories">
  </echo>
  <echo message="deploy       - Deploy to local tomcat installation">
  </echo>
 </target>
</project>
</pre>

Wednesday, October 02, 2013

jQuery treetable

jQuery treetable: A nice tree table component that can be customized to support line highlighting and drag and drop. Unfortunately it does not support column sorting.

'via Blog this'

Visualization: Bar Chart - Google Charts — Google Developers

Visualization: Pie Chart - Google Charts — Google Developers:

Google Charts are very easy to use charting components for your web application.

'via Blog this'

Clearcase error when trying to add jquery-x.x.x.min.js to source control

When you add the jquery-x.x.x.min.js to clearcase you have to specify 
the file type like this: 

cleartool mkelem -eltype compressed_file jquery-x.x.x.min.js 
cleartool ci -nc jquery-x.x.x.min.js 

A minified javascript file has all the whitespace characters removed to make it more efficient to load the javascript on the client browser. So the entire contents of the javascript source file is compressed into a single line (removing all whitespace). Clearcase still treats it as text file but it needs to be told explicitly if its a compressed text file. I figured there is no way on the UI (clearcase explorer) that lets us do so. So we need to go to command line cleartool and run the above command to make it work.

Wednesday, July 24, 2013

Google Trends - Web Search interest: "java certification", ocmjea - Worldwide, 2004 - present

Decline in interest shown in Google trends report for OCMJEA certification and its primarily due to Oracle mandating that people attend their course (which are very expensive - the cheapest one was $1950 for 3 days of Java EE 6 training conducted from India over the live web session). I wish Oracle pays heed to the developer communities and does not force them into paying for Java training but may consider upping the price for the certification by a bit.


Wednesday, July 17, 2013

Book Review: The Eleventh Commandment by Jeffery Archer



Jeffery Archer excels as usual in this book by keeping it a fast paced thriller with some good dose of suspense. The story is about a CIA director trying to save her reputation at stake for ordering an assassination in Columbia, and in order to do so, she must get rid of the CIA agent who carried out her order for the assassination in Columbia, and how that agent, who was an american hero, saves himself and his family eventually.

Thursday, June 27, 2013

Essential CPU BIOS settings for virtualization

The following three CPU BIOS options are important to install 64-bit guest OS on VMWare virtual machine.
  • 64-bit “Yes” – This is set by default.
  • Virtualization Technology “Enabled” – This is disabled by default. You should change this.
  • Execute Disable “Enabled” – This is set by default.

Tuesday, May 14, 2013

Toastmaster Speech #2 – An Introduction to Jenkins Continuous Integration Server

Time Limits: 6/7/8 mins

Actual Time Taken: 10 min 02 secs.

Following is the content of the speech:

Jenkins

1. What is Jenkins?

a. It’s a continuous integration server.

b. It is a fork of another CI server project Hudson (started by Koshiko Kawaguchi of erstwhile Sun Microsystems).

c. It is free and open source.

2. Hallmarks of Jenkins CI Server:

1. Automates builds via build triggers.

2. Automates running test suites. Fails the build if test fails. Trending of test failures by builds.

3. Encourages regular commits to the version control

4. Builds on each commit

5. Fast builds – build the module and run unit tests per module. Jenkins even supports clustering and can send the builds for different modules to different nodes in the cluster thus enabling “parallel” builds.

6. Dashboard – web based dashboard for viewing results and other notification methods like sending emails etc.

3. Why Jenkins?

a. All CI servers can poll a version control repo and execute compile and test.

b. Jenkins stands-out due to its easy-to-use web UI (with context sensitive help at each UI control level) and its extensive plugin ecosystem.

c. Due to its plug-in based ecosystem, it integrates with most of the popular version control repos, run builds for multiple languages, and view a host of valuable reports about your code.

4. How it works?

a. Jenkins supports both Ant and Maven build tools.

b. Out of the box Jenkins supports 2 version control repos: CVS and SVN.

c. Jenkin Job – You need to define a job to build a certain project. The important items you need to define are:

i. Source code management

1. Which version control branch, tag or label you are building the source code from. This is the “integration” in the CI as your team will be constantly adding new code to version control.

ii. Build triggers – when should the source code be built? This is the “continuous” of the CI.

1. Periodically – say once a day.

2. Poll SCM – set a duration say every 15 mins (specified as cron-like expresssion). If there is a commit that happened since the last poll the build will be executed.

iii. Build – what build goals/targets of the build script to execute.

d. We can have multiple jobs for the same project executing different parts of the build lifecycle. For example, we can have another job that executes once a day and executes the complete integration test suite on the build.

5. Jenkins Dashboard

a. Last Success(S) – status of the latest build

b. Weather (W) – overall health of the job – how many times build failed, whether the tests passed, and other scenarios depending on configured plugins.

6. Execute a build – can be either done manually or automatically (if polling SCM option selected).

7. Report – We can view the test reports for tests executed (triggered via Jenkins)

8. Plugin Manager – Plugins for code metrics tooling are available:

a. Checkstyle – enforces good coding guidelines.

b. FindBugs

9. Conclusion

•Jenkins an extensible CI server tool with easy to use UI and very easy to deploy.

•Use of CI server like Jenkins will go a long way in improving the quality of the software in an organization.

Saturday, May 11, 2013

Dell XPS 14 Ultrabook Review

Recently I got myself another notebook and for the first time I am trying an ultrabook – the dell xps 14 ultrabook base model which comes with i5 dual core 1.7 GHz processor, 4 GB RAM and 32GB SSD + 500 GB (5400 RPM) HDD.

The configuration is pretty decent for programming and everyday computing purposes but what is most attractive is the build quality – its aluminum body and slim overalls with the 1600x900 resolution screen for a 14” size is a pretty attractive aspect of this ultrabook. From the specs I was expecting this computer to be slow but I am plesantly surprised that over and above the processor the build of the system does make a BIG difference in the overall performance of your system. It is pretty close in look to a macbook pro and though it is not that light weight the feel of using this system is so good that I think this is the best laptop I have ever owned or even had (it surpasses my work laptop which is a dell latitude e6430).

I could not be more happy. It’s a great laptop/ultrabook to have. Especially I got this in a great deal (a refurbished one at $470 when the new ones with same config are from $800-$1000).

Tuesday, March 26, 2013

Toastmaster’s Table Topics – Life as an Object

Introduction to the theme – Life as an Object:

Spring is around the corner. Most of us will have some plans for doing stuff like cleaning their homes, to go on some vacation, to throw parties, to do other outdoor activities and get healthy.

Consider for a moment if we were not living beings - consider if we were lifeless objects like a Pen for instance. Now consider if the Pen had a mind of its own with which it can think just as we humans do.

In the table topics today, each of the respondents to the table topics will lend their voice to an object which they pick from the grab bag of objects i have. They can then tell us about their life as that Object in general or what they think (as that object) about spring time.

So let the fun begin... may i have volunteers please.

Objects options:
Pen
PC Mouse
Keyboard
Laptop
Chair
Door

etc..

Tuesday, March 19, 2013

Toastmaster’s speech 1 – Virtual Networks

Speech contents are below:

 

Speech – Virtual Networks

1. What is Virtualization?

a. Benefits: Run multiple OS on single server (hardware consolidation – 80% greater utilization), power savings, rack space saving, efficiency in maintenance and deploying patches, HA

b. Savings - > $1500 per server virtualized.

c. Types – Server, Storage (VMFS datastore), Network

2. Software Defined Datacenters – caters to capacity elasticity, on-demand application provisioning, policy based provisioning and automated operations management.

3. Types of Hypervisors

a. Type 1- Bare metal (ESXi, Hyper-v, XenServer)

b. Type 2 – Hypervisor within OS (VMware Workstation, MS VirtualServer)

c. ESXi – 32 MB footprint.

4. Virtual Network Components:

a. vSS

b. vDS

c. Port/Port group – VM Kernel, VM Port group

d. VLAN

e. Trunk port

f. Access port

g. Network Interface card team

h. Virtual network adapters – vmxnet adapters 1Gbps – inside guest OS.

5. Virtual Switch functions –

a. VM to VM on same host

b. Vmknic for vMotion, iSCSI/NFS storage access etc

c. VM to VM on different hosts

d. VM to physical host

6. Similarities to a physical switch –

a. L2 switch

b. MAC table

c. Supports VLAN

d. Supports trunking

e. Fixed number of ports (as specified) - 8, 24 … 4088

7. Dissimilarities to a physical switch –

a. vSwitch cannot be connected to vSwitch – so no looping – so no need for STP

b. vSwitch knows the MACs of VMs connected – so no need to learn MACs.

c. vSwitch cannot route traffic from one NIC to another NIC.

d. No telnet service.

8. Port groups –

a. VM Kernel port – traffic from vmknics on host

b. VM Port groups – traffic of VMs

9. Uplinks –

a. Required to connect to physical switch.

b. vSwitch can have multiple uplinks.

c. No uplink can be shared by 2 vSwitches.

d. Max 32 uplinks on host

e. vSwitch without uplink – internal-only vSwitch

10. NIC Team – 2 or more uplinks on a vSwitch. Provides load balancing and failover (Active/passive)

11. VM Port group – multiple vNICs, does not have IP addresses.

12. VLAN – can reduce number of vSwitches and uplinks required. ID 0 – 4094.

13. Switch port connected to uplink using multiple VLANs must be trunk port.

14. Distributed vSwitches – spans hosts, config change on dvPort group will be pushed to all member hosts by vCenter.

15. Conclusion – Virtual networking aids server virtualization initiatives and thus contributes to the benefits incurred from adopting virtualization.

 

I was only able to cover up to 4.a and then 15 and that itself put me in red @ 6 min+.

Friday, March 15, 2013

Java EE 6 - Part 8 - Transactions

Project: EJB31-ejb


package helloworld.beans;

import helloworld.interceptors.PMInterceptor;
import helloworld.vo.GreetingRequest;
import javax.ejb.EJB;
import javax.ejb.Singleton;
import javax.ejb.LocalBean;
import javax.ejb.Schedule;
import javax.ejb.Startup;
import javax.ejb.Timer;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.interceptor.Interceptors;

/**
 * This is a stateless bean using EJB timer service.
 *
 * @author rwatsh
 */
@Singleton
@LocalBean
@Startup
public class AutomaticSayHelloBean {

    @EJB
    private SingletonHelloWorldBean singletonHelloWorldBean;
    private int timerNotifications;
    private boolean cancelTimer = false;

    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")
    /**
     * Using schedule will cause a timer notification to occur every 5 seconds.
     */
    @Interceptors(PMInterceptor.class)
    @Schedule(second = "*/5", minute = "*", hour = "*")
    public void sayHello(Timer timer) {
        if (!cancelTimer) {
            GreetingRequest request = singletonHelloWorldBean.sayHello();
            System.out.println("AutomaticSayHelloBean.sayHello:- " + request);
            timerNotifications++;
        } else {
            timer.cancel();
            System.out.println("AutomaticSayHelloBean.sayHello: canceled timer");
        }
    }

    public int getNotificationCount() {
        return timerNotifications;
    }

    @TransactionAttribute(TransactionAttributeType.MANDATORY)
    public void cancelTimer() {
        this.cancelTimer = true;
    }
}

---------------------

package helloworld.beans;

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.transaction.UserTransaction;

/**
 * Bean implementation for controlling the timer service EJB.
 *
 * @author rwatsh
 */
@TransactionManagement(TransactionManagementType.BEAN)
@Stateless
public class AutomaticManagerBean implements AutomaticManagerBeanRemote {
    @EJB
    private AutomaticSayHelloBean automaticSayHelloBean;
    @Resource
    private TimerService timerService;
    private int threshold;
    @Resource SessionContext context;
   
    @Override
    public void manageTimer(int interval, int threshold) {
        this.threshold= threshold;
        int currentCount = automaticSayHelloBean.getNotificationCount();
        if (currentCount >= threshold){
            try {
                //automaticSayHelloBean.cancelTimer();
                cancelSayHelloTimer();
            } catch (Exception ex) {
                Logger.getLogger(AutomaticManagerBean.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            timerService.createIntervalTimer(interval, interval, null);
        }
    }

    @Override
    @Timeout
    public void monitorAutomaticTimer(Timer timer) {      
        int currentCount = automaticSayHelloBean.getNotificationCount();
        if (currentCount >= threshold) {
            try {
                //automaticSayHelloBean.cancelTimer();
                cancelSayHelloTimer();
            } catch (Exception ex) {
                Logger.getLogger(AutomaticManagerBean.class.getName()).log(Level.SEVERE, null, ex);
            }
            timer.cancel();
        }
    }
   
    private void cancelSayHelloTimer() throws Exception {
        UserTransaction ut = context.getUserTransaction();
        ut.begin();
        automaticSayHelloBean.cancelTimer();
        ut.commit();
    }

}

Project: EJB31-app-client
package ejb31;

import helloworld.beans.AutomaticManagerBeanRemote;
import javax.ejb.EJB;

/**
 * Test the automatic timer bean through its session facade
 * AutomaticManagerBean.
 *
 * @author rwatsh
 */
public class MaMApp {

    @EJB
    private static AutomaticManagerBeanRemote automaticManagerBean;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        automaticManagerBean.manageTimer(1000 * 60, 50);
        System.out.println("MaMApp.main: started management process");
    }
}

Java EE 6 - Part 7 - Writing Asynchronous Session Beans

This is a very useful enhancement in EJB 3.1 that lets the client make a server method call asynchronously.

In the past we needed to write a lot of code to achieve the same result. The client used to create a temporary JMS queue destination and pass it to the server in the remote method call and the server did its task asynchronously and used the temporary queue to send its response back to client. This has now been taken care of by Java EE 6 framework with the introduction of the @Asynchronous annotations for session beans.

Project: EJB31-Common


package helloworld.beans;

import java.util.concurrent.Future;
import javax.ejb.Remote;

/**
 * Interface for the asynch session bean.
 *
 * @author rwatsh
 */
@Remote
public interface HelloEjbAsynchronousRemote {

    Future ejbAsynchronousSayHello(String name);
   
}

Project: EJB31-ejb

package helloworld.beans;

import java.util.Date;
import java.util.concurrent.Future;
import javax.ejb.AsyncResult;
import javax.ejb.Asynchronous;
import javax.ejb.Stateless;

/**
 * Stateless session bean with a long running task executed asynchronously.
 *
 * @author rwatsh
 */
@Stateless
public class HelloEjbAsynchronous implements HelloEjbAsynchronousRemote {

    @Asynchronous
    @Override
    public Future ejbAsynchronousSayHello(String name) {
        System.out.println(new Date().toString() + " - Begin - HelloEjbAsynchronous.ejbAsynchronousSayHello: " + name);

        // simulate some delay
        try {
            Thread.sleep(50000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(new Date().toString() + " - End - HelloEjbAsynchronous.ejbAsynchronousSayHello: " + name);

        return new AsyncResult("Hello " + name);
    }
 }


Project: StandAloneApp

package standaloneapp;

import helloworld.beans.HelloEjbAsynchronousRemote;
import java.util.concurrent.Future;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 * This client can be a SwingWorker waiting for server task to complete and
 * respond asynchronously while the client carries on with other UI tasks.
 *
 * @author rwatsh
 */
public class AsyncClient {

    private static HelloEjbAsynchronousRemote helloWorldBean;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Exception {
        System.err.println("standaloneapp.Main.main: Stand-alone App started");
        String jndiPath = "java:global/EJB31/EJB31-ejb/HelloEjbAsynchronous";
        try {
            Context ctx = new InitialContext();
            System.out.println("standaloneapp.Main.main: looking up bean at: "
                    + jndiPath);
            helloWorldBean = (HelloEjbAsynchronousRemote) ctx.lookup(jndiPath);
            System.out.println("standaloneapp.Main.main: found HelloWorldBean: "
                    + helloWorldBean);
            System.out.println("standaloneapp.Main.main: calling sayHello");

            Future future = helloWorldBean.ejbAsynchronousSayHello("Watsh");

            while (!future.isDone()) {
                Thread.sleep(10000);
                System.out.println("Doing some other client tasks and waiting for server to respond");
            }

            String greeting = (String) future.get();

            System.out.println("standaloneapp.Main.main: HelloWorldBean said: "
                    + greeting);
        } catch (NamingException ex) {
            System.err.println(
                    "standaloneapp.Main.main: Could not find HelloWorldBeanRemote");
            System.err.println("standaloneapp.Main.main: JNDI path used for lookup: " + jndiPath);
            ex.printStackTrace();
        }
    }
}



Java EE 6 - Part 6 - Writing EJB TimerService and Interceptors

Project: EJB31-Common


package helloworld.beans;

import javax.ejb.Remote;
import javax.ejb.Timer;

/**
 * Interface to manage the EJB timer service.
 *
 * @author rwatsh
 */
@Remote
public interface AutomaticManagerBeanRemote {
    public void manageTimer(int interval, int threshold);

    void monitorAutomaticTimer(Timer timer);
}

Project:EJB31-ejb


package helloworld.beans;

import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;

/**
 * Bean implementation for controlling the timer service EJB.
 *
 * @author rwatsh
 */
@Stateless
public class AutomaticManagerBean implements AutomaticManagerBeanRemote {
    @EJB
    private AutomaticSayHelloBean automaticSayHelloBean;
    @Resource
    private TimerService timerService;
    private int threshold;
 
    @Override
    public void manageTimer(int interval, int threshold) {
        this.threshold= threshold;
        int currentCount = automaticSayHelloBean.getNotificationCount();
        if (currentCount >= threshold){
            automaticSayHelloBean.cancelTimer();
        } else {
            timerService.createIntervalTimer(interval, interval, null);
        }
    }
 
 

    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")

    @Override
    @Timeout
    public void monitorAutomaticTimer(Timer timer) {      
        int currentCount = automaticSayHelloBean.getNotificationCount();
        if (currentCount >= threshold) {
            automaticSayHelloBean.cancelTimer();
            timer.cancel();
        }
    }

}
-------------------------
package helloworld.beans;

import helloworld.interceptors.PMInterceptor;
import helloworld.vo.GreetingRequest;
import javax.ejb.EJB;
import javax.ejb.Singleton;
import javax.ejb.LocalBean;
import javax.ejb.Schedule;
import javax.ejb.Startup;
import javax.ejb.Timer;
import javax.interceptor.Interceptors;

/**
 * This is a stateless bean using EJB timer service.
 *
 * @author rwatsh
 */
@Singleton
@LocalBean
@Startup
public class AutomaticSayHelloBean {

    @EJB
    private SingletonHelloWorldBean singletonHelloWorldBean;
    private int timerNotifications;
    private boolean cancelTimer = false;

    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")
    /**
     * Using schedule will cause a timer notification to occur every 5 seconds.
     */
    @Interceptors(PMInterceptor.class)
    @Schedule(second = "*/5", minute = "*", hour = "*")
    public void sayHello(Timer timer) {
        if (!cancelTimer) {
            GreetingRequest request = singletonHelloWorldBean.sayHello();
            System.out.println("AutomaticSayHelloBean.sayHello:- " + request);
            timerNotifications++;
        } else {
            timer.cancel();
            System.out.println("AutomaticSayHelloBean.sayHello: canceled timer");
        }
    }

    public int getNotificationCount() {
        return timerNotifications;
    }

    public void cancelTimer() {
        this.cancelTimer = true;
    }
}

---------------------
package helloworld.interceptors;

import javax.interceptor.AroundTimeout;
import javax.interceptor.InvocationContext;

/**
 * Interceptor to monitor invocations of a method.
 *
 * @author rwatsh
 */
public class PMInterceptor {

    private long numberOfInvocations;

    @AroundTimeout
    public Object monitorInvocations(InvocationContext ic) throws Exception {
        try {
            Object returnValue = ic.proceed();
            numberOfInvocations++;
            System.out.println("PMInterceptor.monitorInvocations: invocation count -" + numberOfInvocations);
            return returnValue;
        } catch (Exception ex) {
            System.err.println("PMInterceptor.monitorInvocations: error occurred -" + ex);
        }
        return null;
    }
}
------------------------
Project: EJB31-app-client

package ejb31;

import helloworld.beans.AutomaticManagerBeanRemote;
import javax.ejb.EJB;

/**
 * Test the automatic timer bean through its session facade
 * AutomaticManagerBean.
 *
 * @author rwatsh
 */
public class MaMApp {

    @EJB
    private static AutomaticManagerBeanRemote automaticManagerBean;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        automaticManagerBean.manageTimer(1000 * 60, 50);
        System.out.println("MaMApp.main: started management process");
    }
}

Output:
INFO: TimeBasedHelloWorldBean.postConstruct
INFO: SingletonHelloWorldBean.postConstruct
INFO: AutomaticSayHelloBean.sayHello:- helloworld.vo.GreetingRequest [requestTime=3/15/13 10:49 AM, greeting=Good Morning]
INFO: PMInterceptor.monitorInvocations: invocation count -1
INFO: AutomaticSayHelloBean.sayHello:- helloworld.vo.GreetingRequest [requestTime=3/15/13 10:49 AM, greeting=Good Morning]
INFO: PMInterceptor.monitorInvocations: invocation count -2
INFO: AutomaticSayHelloBean.sayHello:- helloworld.vo.GreetingRequest [requestTime=3/15/13 10:49 AM, greeting=Good Morning]
INFO: PMInterceptor.monitorInvocations: invocation count -3
.....
INFO: helloworld.beans.SingletonHelloWorldBean: @PreDestroy

Java EE 6 - Part 5 - Writing Message Driven Beans

Project: EJB31-Common

package helloworld.beans;

import helloworld.vo.GreetingRequest;
import javax.ejb.Remote;

/**
 *
 * @author rwatsh
 */
@Remote
public interface MessageFacadeRemote {

    GreetingRequest sayHello();
   
}


Project: EJB31-ejb

package helloworld.beans;

import helloworld.vo.GreetingRequest;
import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.Session;

/**
 * Message Facade bean that produces message.
 * @author rwatsh
 */
@Stateless
public class MessageFacade implements MessageFacadeRemote {

    @Resource(mappedName = "jms/HelloWorldQueue")
    private Queue helloWorldQueue;
    @Resource(mappedName = "jms/HelloWorldQueueFactory")
    private ConnectionFactory helloWorldQueueFactory;
    @EJB
    private SingletonHelloWorldBean singletonHelloWorldBean;

    private ObjectMessage createJMSMessageForjmsHelloWorldQueue(Session session, Serializable messageData) throws JMSException {
        // TODO create and populate message to send
        ObjectMessage om = session.createObjectMessage(messageData);
        return om;
    }

    private void sendJMSMessageToHelloWorldQueue(Serializable messageData) throws JMSException {
        Connection connection = null;
        Session session = null;
        try {
            connection = helloWorldQueueFactory.createConnection();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer messageProducer = session.createProducer(helloWorldQueue);
            messageProducer.send(createJMSMessageForjmsHelloWorldQueue(session, messageData));
        } finally {
            if (session != null) {
                try {
                    session.close();
                } catch (JMSException e) {
                    Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Cannot close session", e);
                }
            }
            if (connection != null) {
                connection.close();
            }
        }
    }

    @Override
    public GreetingRequest sayHello() {
        GreetingRequest result = singletonHelloWorldBean.sayHello();
        try {
            sendJMSMessageToHelloWorldQueue(result);
            System.out.println("MessageFacade.sayHello: sent message - " + result);
        } catch (JMSException ex) {
            System.err.println("MessageFacade.sayHello: error sending message - "
                    + ex);
        }
        return result;
    }
}



package helloworld.beans;

import helloworld.vo.GreetingRequest;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.TextMessage;

/**
 * MDB that consumes the message.
 * @author rwatsh
 */
@MessageDriven(mappedName = "jms/HelloWorldQueue", activationConfig = {
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class HelloWorldMDB implements MessageListener {

    public HelloWorldMDB() {
    }

    @PostConstruct
    private void postConstruct() {
        System.out.println("HelloWorldMDB: @PostConstruct");
    }

    @Override
    public void onMessage(Message message) {
        if (message instanceof TextMessage) {
            try {
                TextMessage textMessage = (TextMessage) message;
                String messageValue = textMessage.getText();
                System.out.println("HelloWorldMDB.onMessage: received text message - " + messageValue);
            } catch (JMSException ex) {
                Logger.getLogger(HelloWorldMDB.class.getName()).log(Level.SEVERE, null, ex);
            }

        } else if (message instanceof ObjectMessage) {
            try {
                ObjectMessage objMessage = (ObjectMessage) message;
                Object contents = objMessage.getObject();
                if (contents instanceof GreetingRequest) {
                    String messageValue = contents.toString();
                    System.out.println("HelloWorldMDB.onMessage: received object message - " + messageValue);
                }
            } catch (JMSException ex) {
            }

        } else {
//do nothing
        }
    }

    @PreDestroy
    private void destroy() {
        System.out.println("HelloWorldMDB: @PreDestroy");
    }
}

Project: EJB31-app-client

package ejb31;

import helloworld.beans.MessageFacadeRemote;
import helloworld.vo.GreetingRequest;
import javax.ejb.EJB;

/**
 * Message facade tester which triggers the facade to send message to MDB.
 *
 * @author rwatsh
 */
public class MessageFacadeTest {

    @EJB
    private static MessageFacadeRemote messageFacade;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        GreetingRequest request = messageFacade.sayHello();
        System.out.println("MessageFacadeTest.main: facade said - "
                + request);
    }
}



Java EE 6 - Part 4 - Writing JMS Message Producers

1. Create JMS resources - QueueConnectionFactory and Queue. 

For glassfish, it is done in the glassfish-resources.xml file. Netbeans puts in /setup folder (Right click App and select New > Other > Glassfish > JMS Resource. Do it twice, once to add Admin Object Resource and then to add Connector Object Resource.



2. Create MessageProducerApp client.
Project: EJB31-app-client


package ejb31;

import helloworld.beans.SingletonHelloWorldBeanRemote;
import helloworld.vo.GreetingRequest;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 * The message producer.
 * @author rwatsh
 */
public class MessageProducerApp {

    private static Message createJMSMessageForjmsHelloWorldQueue(Session session, Object messageData) throws JMSException {
        // TODO create and populate message to send
        TextMessage tm = session.createTextMessage();
        tm.setText(messageData.toString());
        return tm;
    }

    private static void sendJMSMessageToHelloWorldQueue(Object messageData) throws NamingException, JMSException {
        Context c = new InitialContext();
        ConnectionFactory cf = (ConnectionFactory) c.lookup("jms/HelloWorldQueueFactory");
        Connection conn = null;
        Session s = null;
        try {
            conn = cf.createConnection();
            s = conn.createSession(false, s.AUTO_ACKNOWLEDGE);
            Destination destination = (Destination) c.lookup("jms/HelloWorldQueue");
            MessageProducer mp = s.createProducer(destination);
            mp.send(createJMSMessageForjmsHelloWorldQueue(s, messageData));
        } finally {
            if (s != null) {
                try {
                    s.close();
                } catch (JMSException e) {
                    System.err.println("Cannot close session - " + e);
                }
            }
            if (conn != null) {
                conn.close();
            }
        }
    }

    private static SingletonHelloWorldBeanRemote lookupSingletonHelloWorldBeanRemote() {
        try {
            Context c = new InitialContext();
            return (SingletonHelloWorldBeanRemote) c.lookup("java:global/EJB31/EJB31-ejb/SingletonHelloWorldBean");
        } catch (NamingException ne) {
            ne.printStackTrace();
            throw new RuntimeException(ne);
        }
    }

    public static void main(String[] args) {
        SingletonHelloWorldBeanRemote hwr = lookupSingletonHelloWorldBeanRemote();
        GreetingRequest result = hwr.sayHello();
        String resultStr = result.toString();
        try {
            sendJMSMessageToHelloWorldQueue(resultStr);
            System.out.println("MessageProducerApp.main: sent message - " + resultStr);
        } catch (Exception ex) {
            System.err.println("MessageProducerApp.main: failed to send message - " + ex);
        }

    }
}


Java EE 6 - Part 3 - Writing Singleton Session Beans

Project: EJB31-Common

package helloworld.beans;

import helloworld.vo.GreetingRequest;
import javax.ejb.Remote;

/**
 * Remote interface for singleton bean.
 * @author rwatsh
 */
@Remote
public interface SingletonHelloWorldBeanRemote {

    GreetingRequest sayHello();

    GreetingRequest[] auditRequests();
 
}

Project: EJB31-ejb

package helloworld.beans;

import helloworld.vo.GreetingRequest;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PreDestroy;
import javax.ejb.EJB;
import javax.ejb.Singleton;

/**
 * Singleton bean implementation.
 * Note: It depends on the TimeBasedHelloWorldBean (not shown in this post) which is
 * another singleton bean. The TimeBasedHelloWorldBean will be initialized before this bean.
 * @author rwatsh
 */
@Singleton
@DependsOn("TimeBasedHelloWorldBean")
public class SingletonHelloWorldBean implements SingletonHelloWorldBeanRemote {

    @EJB
    private TimeBasedHelloWorldBean timeBasedHelloWorldBean;
    private List greetingRequests;

    public SingletonHelloWorldBean() {
        greetingRequests = new ArrayList();
    }
    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method")

    @Override
    public GreetingRequest sayHello() {
        String greeting = timeBasedHelloWorldBean.sayHello();
        GreetingRequest request = new GreetingRequest(greeting);
        greetingRequests.add(request);
        return request;
    }

    @Override
    public GreetingRequest[] auditRequests() {
        return greetingRequests.toArray(new GreetingRequest[]{});
    }

    @PreDestroy
    private void destroy() {
        System.out.println("helloworld.beans.SingletonHelloWorldBean: @PreDestroy");
        for (GreetingRequest gr : greetingRequests) {
            System.out.println(gr);
        }
        greetingRequests = null;
    }
}

Project: StandAloneApp

package standaloneapp;

import helloworld.beans.SingletonHelloWorldBeanRemote;
import helloworld.vo.GreetingRequest;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 * Singleton bean test client.
 * @author rwatsh
 */
public class SingletonHelloWorldBeanTest {

    private static SingletonHelloWorldBeanRemote helloWorldBean;

    public static void main(String[] args) {
        System.err.println("standaloneapp.Main.main: Stand-alone App started");
        String jndiPath = "java:global/EJB31/EJB31-ejb/SingletonHelloWorldBean";
        try {
            Context ctx = new InitialContext();
            System.out.println("standaloneapp.Main.main: looking up bean at: "
                    + jndiPath);
            helloWorldBean = (SingletonHelloWorldBeanRemote) ctx.lookup(jndiPath);
            System.out.println("standaloneapp.Main.main: found HelloWorldBean: "
                    + helloWorldBean);
            System.out.println("standaloneapp.Main.main: calling sayHello");
            GreetingRequest greeting = helloWorldBean.sayHello();
            System.out.println("standaloneapp.Main.main: HelloWorldBean said: "
                    + greeting);

            GreetingRequest[] audit = helloWorldBean.auditRequests();
            System.out.println("SingletonHelloWorldBeanTest.main: number of sayHello requests made on Singleton: " + audit.length);
        } catch (NamingException ex) {
            System.err.println(
                    "standaloneapp.Main.main: Could not find HelloWorldBeanRemote");
            System.err.println("standaloneapp.Main.main: JNDI path used for lookup: " + jndiPath);
            ex.printStackTrace();
        }
    }
}


Popular micro services patterns

Here are some popular Microservice design patterns that a programmer should know: Service Registry  pattern provides a  central location  fo...