Sparkles

that were shone when I got tempered!

CouchDB – Updates and Deletes

leave a comment »

You can delete document using the _id and rev as mentioned below

curl -X DELETE http://localhost:5984/couch_dev/document_id_100?rev=1-f87d6fa9b847b8ac0f92f3210cc02db5

But this will only make it invisible (anyway it IS-A delete according to the CouchDB Lingo). Space will still not be released. If you want to permanently delete it and release the space, you must purge it like mentioned below.

curl -X POST -d '{"document_id_100":["1-f87d6fa9b847b8ac0f92f3210cc02db5"]}'http://localhost:5984/couch_dev/_purge -H "Content-Type:application/json"

But if we want to use this to delete temporary/expired data according to the experts, this is inappropriate use of couchdb. In this case we can delete whole db periodically.

Written by Namal Fernando

August 17, 2017 at 5:31 am

CouchDB – Retreiving Data

leave a comment »

Once Documets are available in the couchdb, they can be directly accissible using the _id value as below.

 http://localhost:5984/couch_dev/search-CMB-001 

You can use simple GET request to retrieve this data.

 curl -X GET http://localhost:5984/couch_dev/search-CMB-001 

 

Querying Documents

Documents can be queried also by creating views.

These views can be created using the JavaScript or CofeeScripts. They can be used to query multiple documents.

In this case first you need to create views. This can be easily created using the UI as mentioned below

Then you can add a view. Here create a design document also. If you already have a designdocument, create a view on that one.

Once you click on that view it will be selected.

 

After this documents can be retreived through these views using below like get query.

http://{couchDB-host}:{couchDB-port}/{couchDB-dbName}/_design/{couchDB-design document name}/_view/{couchDB-view name}?key=”{couchDB-document key}”

Note : couchDB-document key must be the key that was mentioned in the emit function.

 

Sample Functions

01. doc

function(doc) {
emit(doc._id, doc);
}

This will provide whole json providing the _id as the key.
So, You can retreive a particular doc using id as mentioned below.

curl -X GET 'http://localhost:5984/couch_dev/_design/hotels/_view/doc?key="search-CMB-001"'

02.rev

function(doc) {function(doc) {
emit(doc._id, doc._rev);
}

This will provide _rev id providing the _id as the key.
So, you can retreive the particular rev using the id as mentioned below

curl -X GET 'http://localhost:5984/couch_dev/_design/hotels/_view/rev?key="search-CMB-001"'

 

03.rooms

function(doc) {function (doc) {
for (var x = 0, htlLen = doc.hos.length; x < htlLen; x++) {
emit(doc._id+'-'+doc.hos[x].hotelcode, doc.hos[x].rms);
}
}

This will provide all rooms as a list for each hotel, providing the “id-hotelcode” as the key.
So, you can retreive all rooms for a particular hotel as mentioned below

curl -X GET 'http://localhost:5984/couch_dev/_design/hotels/_view/rooms?key="search-CMB-001-GLD"'

 

04.room

function(doc) {function (doc) {
for (var x = 0, htlLen = doc.hos.length; x < htlLen; x++) {
for (var y = 0, rmLen = doc.hos[x].rms.length; y < rmLen; y++) {
emit(doc._id+'-'+doc.hos[x].hotelcode+'-'+doc.hos[x].rms[y].roomcode, doc.hos[x].rms[y]);
}
}
}

This will provide all room objects one by one for each hotel, providing the “id-hotelcode-roomcode” as the key.
So, you can retreive a particular room object providing the room code as below.

curl -X GET 'http://localhost:5984/couch_dev/_design/hotels/_view/room?key="search-CMB-001-GLD-SGL-2-A"'

 

Written by Namal Fernando

August 17, 2017 at 4:57 am

Posted in CouchDB, Retreive Data

CouchDB – Insert Data

leave a comment »

Data can be updated to the CouchDB as json using a HTTP POST call. In this case, content-type must be used as “application/json“. This also can be done using any http client such as Postman, SoapUI, java.net.HttpURLConnection or even simple curl command.

In this case first you must create a Database in the CouchDB. You can do this using the fotonUI as meentioned below or via curl command.

Then you can POST the JSON you want to insert as mentioned below.

curl -X POST -d '{"_id":"document_id_01", "Name":"Namal Fernando", "Age":28}' http://localhost:5984/couch_dev -H "Content-Type:application/json"

In this case, this _id filed (eg : document_id_01)  is very important. Because, document will be identified using this id. Once the document is updated, it will be displayed in Futon UI as mentioned below.

We can write json documents to couchdb in java as mentioned below.

URL mUrl = new URL("http://localhost:5984/couch_dev");
HttpURLConnection con = (HttpURLConnection) mUrl.openConnection(); 
con.setRequestMethod("POST"); con.setDoOutput(true); con.setUseCaches(false); 
con.setDoInput(true); con.setRequestProperty("user-agent","Mozilla(MSIE)"); 
con.setRequestProperty("Accept-Encoding","gzip,deflate"); 
con.setRequestProperty("Content-Type", "application/json"); 
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 
byteArrayOutputStream.write(payLoad.getBytes()); 
byteArrayOutputStream.writeTo(con.getOutputStream()); 
System.out.println("writeToCouchDB().con.getHeaderFields() : [Response Code : " + con.getResponseCode() + "], [Headers : " + con.getHeaderFields()+"]");

Bulk insert.

When it is needed to insert large number of json documents, you can insert them as bulk insert.Here, there are two main changes will happen.

  1. URL changes :    URL must be changed from

http://localhost:5984/couch_dev to http://localhost:5984/couch_dev/_bulk_docs.

2. Payload : Payloads must be mentioned as a JSONArray as mentioned below.

{"docs":[{"_id":"document_id_02", "Name":"Lakmini Weerasekara", "Age":30},{"_id":"document_id_03", "Name":"Ahas Rehan", "Age":3},{"_id":"document_id_100", "Name":"Ranjith Fernando", "Age":66}]}

eg :

curl -X POST -d '{"docs":[{"_id":"search-KLT-003","hos": [{"hotelcode": "CTS","hotelname": "Citrus Hotel","rms": [{"roomcode": "SGL-1-G","roomname": "Single Room1G"},{"roomcode": "DBL-1-H","roomname": "Double Room1H"},{"roomcode": "TRP-1-I","roomname": "Triple Room1I"}]},{"hotelcode": "AVN","hotelname": "Avani Hotel","rms": [{"roomcode": "SGL-2-G","roomname": "Single Room2G"},{"roomcode": "DBL-2-H","roomname": "Double Room2H"},{"roomcode": "TRP-2-I","roomname": "Triple Room2I"}]},{"hotelcode": "RYP","hotelname": "Royal Palms Hotel","rms": [{"roomcode": "SGL-3-G","roomname": "Single Room3G"},{"roomcode": "DBL-3-H","roomname": "Double Room3H"},{"roomcode": "TRP-3-I","roomname": "Triple Room3I"}]}]},{"_id":"search-PLN-002","hos": [{"hotelcode": "SDA","hotelname": "Sudu Araliya Hotel","rms": [{"roomcode": "SGL-1-D","roomname": "Single Room1D"},{"roomcode": "DBL-1-E","roomname": "Double Room1E"},{"roomcode": "TRP-1-F","roomname": "Triple Room1F"}]},{"hotelcode": "MHN","hotelname": "Maha Nuge Hotel","rms": [{"roomcode": "SGL-2-D","roomname": "Single Room2D"},{"roomcode": "DBL-2-E","roomname": "Double Room2E"},{"roomcode": "TRP-2-F","roomname": "Triple Room2F"}]},{"hotelcode": "RNK","hotelname": "Ranketha Hotel","rms": [{"roomcode": "SGL-3-D","roomname": "Single Room3D"},{"roomcode": "DBL-3-E","roomname": "Double Room3E"},{"roomcode": "TRP-3-F","roomname": "Triple Room3F"}]}]},{"_id":"search-CMB-001","hos": [{"hotelcode": "HIL","hotelname": "Hilton Hotel","rms": [{"roomcode": "SGL-1-A","roomname": "Single Room1A"},{"roomcode": "DBL-1-B","roomname": "Double Room1B"},{"roomcode": "TRP-1-C","roomname": "Triple Room1C"}]},{"hotelcode": "GLD","hotelname": "Galadari Hotel","rms": [{"roomcode": "SGL-2-A","roomname": "Single Room2A"},{"roomcode": "DBL-2-B","roomname": "Double Room2B"},{"roomcode": "TRP-2-C","roomname": "Triple Room2C"}]},{"hotelcode": "KNB","hotelname": "Kingsbury Hotel","rms": [{"roomcode": "SGL-3-A","roomname": "Single Room3A"},{"roomcode": "DBL-3-B","roomname": "Double Room3B"},{"roomcode": "TRP-3-C","roomname": "Triple Room3C"}]}]}]}' http://localhost:5984/couch_dev/_bulk_docs -H "Content-Type:application/json"

This will update all the documents at once.

 

Written by Namal Fernando

August 16, 2017 at 10:37 pm

Posted in CouchDB, Insert

CouchDB – Installation and Setup

leave a comment »

First Time Installation

Note OS is Ubuntu 16.04 (xenial). Please refer the couchdb-docs for other versions.

Run below commands in there


echo "deb https://apache.bintray.com/couchdb-deb xenial main" \
| sudo tee -a /etc/apt/sources.list

curl -L https://couchdb.apache.org/repo/bintray-pubkey.asc \
| sudo apt-key add -

sudo apt-get update

sudo apt-get install couchdb

In this case you have to pass through a series of initial setup steps.Here, I have selected standalone version

And finally it will be installed and run in default 5984 port.

You can access the UI at http://127.0.0.1:5984/_utils/#

CouchDB will be installed at /opt/couchdb folder. (in older versions this was installed in /etc/couchdb).

Change the configurations.

This can be done via couchdb config area (http://127.0.0.1:5984/_utils/#_config/couchdb@localhost) as mentioned below

In the older version this could be done by accessing /etc/couchdb/default.ini file.

Restarting couchdb


sudo service couchdb restart

Written by Namal Fernando

August 16, 2017 at 5:52 am

Posted in CouchDB, Installation

Implement RollingPerInvoke Appender using org.apache.log4j.Logger

leave a comment »

Requirement :

  1. Log data using org.apache.log4j.Logger.
  2. Log data with a unique trace id in log4j pattern.
  3. Log data in seperate files per each invoke.
  4. Log data seperate folders per each supplier threads (eg : DerbySoftImpl, HBSIImpl, HotelbedsImpl, SynxisImpl) and levels (eg : Availabiity, Reservation, Cancellation) at run time.

Approach :

  1. Log data using org.apache.log4j.Logger. :
    We use org.apache.log4j.Logger to log data (eg : logger.info(data))
  2. Log data with a unique trace id in log4j pattern.
    We do this through the org.apache.log4j.MDC
  3. Log data in seperate files per each invoke.
    We create a custome Appender extending org.apache.log4j.FileAppender and override the file name with MDC String and System milliseconds
  4. Log data seperate folders per each supplier threads (eg : DerbySoftImpl, HBSIImpl, HotelbedsImpl, SynxisImpl) and levels (eg : Availabiity, Reservation, Cancellation) at run time.
    In the created custome Appender, we create the new folder structure using the extracted values from mDCStr and override the FileAppender’s folder path using created one.

LogDataClient.java
This is the demo class for the RollingPerInvokeImplemnetation.
In this case, there are two set of threads. Air threads and hotel threads. Actually air threads are kind of control threads here. It logs data to one seperate file (daily) by appending to it. And hotel threads will do logging data to seperate files in each invoke. All these happens in multithreaded environment. So, LogDataClient initializes the hotel and air supplier threads.

Hotel Supplier Threads. (eg : DerbySoftImpl, HBSIImpl, HotelbedsImpl, SynxisImpl)
In each invoke, it calls logData method passing data to be logged and the unique ID (traceid). We have done this in multiple times to create a realtime traffic in there. So, when there are 10 supplier threads per each supplier and they invoked logdata method 10 times by each supplier thread, that means there are 10 calls per supplier thread.
eg :

Log4jFileLogger.logData("&amp;amp;amp;lt;RESPONSE&amp;amp;amp;gt;&amp;amp;amp;lt;DERBY_RS&amp;amp;amp;gt;&amp;amp;amp;lt;RESPONSE&amp;amp;amp;gt;","derbysoft|Availabiity|Response|"+UUID.randomUUID());

Log4jFileLogger
This is the class that declare and initializes org.apache.log4j.Logger instance and invoke it with data passed by the suppier thread. unique id will be passed to the logger via MDC.
In this case we have make the logData method as synchronized one to avoid being conflict with the FileAppender (to be discussed little bit later here).


 public static synchronized void logData(String data, String mDCStr) {

 MDC.put("ridelogid", mDCStr);

 DOMConfigurator.configure("log4j.xml");
 logger.info(data);

 MDC.remove("ridelogid");
 }

In this case, for hotel supplier threads we invoke the log4j.hotel.Log4jFileLogger and for air supplier threads we invoke log4j.air.Log4jFileLogger. We locate these Log4jFileLoggers to seperate packages. So, when the logger is invoked (eg : logger.info()), it looks at the relevant <logger> tag the log4j.xml.
eg :

<logger name="log4j.hotel">
<appender-ref ref="HOTEL_AVAILABIITY" />
</logger>

<logger name="log4j.air">
<appender-ref ref="loggers initialized through the classes in log4j.hotel will use the appernder named HOTEL_AVAILABIITY" />
</logger>

So, in this case, loggers initialized through the classes in log4j.hotel (Logger logger = Logger.getLogger(log4j.hotel.Log4jFileLogger.class);) will use the appernder named HOTEL_AVAILABIITY and loggers initialized through the classes in log4j.hotel will use the appernder named loggers initialized through the classes in log4j.air will use the appernder named AIR_AVAILABIITY.

<appender name="HOTEL_AVAILABIITY" class="log4j.RollingPerInvokeFileAppender">
<param name="append" value="false" />
<param name="File" value="/var/log/rezg/app/bonologs/fileNamex" />
<param name="Threshold" value="INFO" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d [%X{ridelogid}] %m%n" />
</layout>
</appender>

<appender name="AIR_AVAILABIITY" class="org.apache.log4j.DailyRollingFileAppender">
<param name="append" value="true" />
<param name="File" value="/var/log/rezg/app/bono-airlogs/airlogs.log" />
<param name="Threshold" value="INFO" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c] %m%n" />
</layout>
</appender>

Then in those apenders, HOTEL_AVAILABIITY uses a custome fileAppender log4j.RollingPerInvokeFileAppender we implemented. And AIR_AVAILABIITY uses inbuilt org.apache.log4j.DailyRollingFileAppender to log Data passed through the logger invocation in relevant Log4jFileLogger (eg : logger.info(data)) .
In this case unique trace Id put to the MDC (eg : MDC.put(“ridelogid”, mDCStr);) in log4j.hotel.Log4jFileLogger, will be passed to relevant appender via log4j ConversionPattern (eg : <param name=”ConversionPattern” value=”%d [%X{ridelogid}] %m%n” />) to be logged with the log data.
As mentioned earlier, the real implementation will be in HOTEL_AVAILABIITY appender. So, moving forward we will discuss about the HOTEL_AVAILABIITY. In AIR_AVAILABIITY appender it will just append the data to a daily rolling log file in old school style :).

So, when the MDC string is put and logger.info(data) method is invoked, log4j.RollingPerInvokeFileAppender will be invoked passing the MDC string to it via the ConversionPattern.

log4j.RollingPerInvokeFileAppender
RollingPerInvokeFileAppender is a org.apache.log4j.FileAppender. (RollingPerInvokeFileAppender extends FileAppender). So, the core implementation happens in the org.apache.log4j.FileAppender. And we have override some methods (eg : append(LoggingEvent event)) suit for our requirement mentioned at the top.
So, here, basically, what we are doing is taking the MDC string set in the invoke, create the new file name with relavant folder structure using the parameters passed in MDC string for each millisecond.

append method :

 @Override
 public void append(LoggingEvent event) {

 String mDCString = (String) event.getMDC("ridelogid");

 modifyLogFileName(mDCString);

 super.append(event);

 }

As mentioned, this is an overriden method from org.apache.log4j.FileAppender.
In this case, first we get the mDCString via event.getMDC(“ridelogid”) and pass the modifyLogFileName method to modify and set the relavant file name with relevant folder structure. Then it calls org.apache.log4j.FileAppender’s append method to do the rest (eg : super.append(event)).

modifyLogFileName method :

Here first we create a file instance with the default file name mentioned in the appender (eg : <param name=”File” value=”/var/log/rezg/app/bonologs/fileNamex” />).
We will use this to get the root folder (eg : /var/log/rezg/app/bonologs/).

 final File logFile = new File(fileName);
 String rootFolder = logFile.getParent();

Then we identify the required parameters from the MDC string (eg : derbysoft|Availabiity|Response|5395de83-f507-436b-8b4d-25e3ff86ce33) and create the new folder path.

 String[] fileProps = mDCString.split("\\|");

 String vendorId = null;
 String traceId = null;
 String flow = null;
 String type = null;

 try { vendorId = fileProps[0];} catch (Exception e) {}
 try { flow = fileProps[1];} catch (Exception e) {}
 try { type = fileProps[2];} catch (Exception e) {}
 try { traceId = fileProps[3];} catch (Exception e) {}

 String newfolderPath = rootFolder + File.separator + vendorId + File.separator + flow;

Then we create the new Folder structure (for the first time only) (requirement 4)

 File file = new File(newfolderPath); 
 if(! file.isDirectory()) file.mkdirs(); 

Then we create the new file name with the System millisecond along with the mDCString. This will create unique file per each invoke (requirement 3).


String newfileName = newfolderPath + File.separator + mDCString.replaceAll("\\|", "-") + "_" + System.currentTimeMillis() + ".log";

Then we set the created newfileName to the org.apache.log4j.FileAppender’s setFile() method.

setFile(newfileName, fileAppend, bufferedIO, bufferSize);

After this, modifyLogFileName method is comlpleted and it will log the data through log4j (requirement 1) with MDC string (requirement 2) as default org.apache.log4j.FileAppender behaviour.

Note : we must synchronized the logData method in Log4jFileLogger to avoid conflicts with creating the newfolderPath for each mDCString (ridelogid).

You can find the comlplet source code at https://github.com/namalfernandolk/log4j-rolling-per-invoke.git

Written by Namal Fernando

January 20, 2016 at 5:51 am

Posted in Java, log4j

Tagged with , ,

Measuring Memory of JAVA objects

leave a comment »

Build the JAMM Master Project.

This project includes all the implemnetation to measure the memoory of the Java Objects. We are going to build it and package it to a jar file so that we can use in our client to do memory measurements.

1. Get the jeblis-jamm client project from here.

2. Build it and package it to a jar file.

3. Specify the org.github.jamm.MemoryMeter class as the Premain-Class in jar file’s MANIFEST.MF.

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: namal
Build-Jdk: 1.7.0_03
Premain-Class: org.github.jamm.MemoryMeter

Now your jar is ready to use (jamm-0.3.2-SNAPSHOT.jar).

I have added my project also built using above steps in here.

Build the JAMM Client Project.

1. Create a new JAVA project and add the JAMM-Master jar file built in above step.

TestMemory.java


public class TestMemory {

public static void main(String[] args) {

String str = &amp;quot;Namal Fernando&amp;quot;;

ArrayList&amp;lt;String&amp;gt; strList = new ArrayList&amp;lt;String&amp;gt;();
strList.add(str);
strList.add(str+&amp;quot;1&amp;quot;);
strList.add(str+&amp;quot;2&amp;quot;);
strList.add(str+&amp;quot;3&amp;quot;);
strList.add(str+&amp;quot;4&amp;quot;);

MemoryMeter memoryMeter = new MemoryMeter().enableDebug();
System.out.println(&amp;quot;main().General Measure : &amp;quot; + memoryMeter.measure(strList));
System.out.println(&amp;quot;main().Deep Measure : &amp;quot; + memoryMeter.measureDeep(strList));
System.out.println(&amp;quot;main().Count Child : &amp;quot; + memoryMeter.countChildren(strList));

}

}

2. Run the TestMemory class giving the below VM Arguments to point the JAMM-Master jar file (jamm-0.3.2-SNAPSHOT.jar) built in above step as javaagent for memory measurement.

-javaagent:/rezsystem/workspace/jamm-client/lib/jamm-0.3.2-SNAPSHOT.jar

Output will be looked like this.

main().General Measure : 24

root [java.util.ArrayList] 432 bytes (24 bytes)
|
+–elementData [java.lang.Object[]] 408 bytes (56 bytes)
|
+–0 [java.lang.String] 64 bytes (24 bytes)
| |
| +–value [char[]] 40 bytes (40 bytes)
|
+–1 [java.lang.String] 72 bytes (24 bytes)
| |
| +–value [char[]] 48 bytes (48 bytes)
|
+–2 [java.lang.String] 72 bytes (24 bytes)
| |
| +–value [char[]] 48 bytes (48 bytes)
|
+–3 [java.lang.String] 72 bytes (24 bytes)
| |
| +–value [char[]] 48 bytes (48 bytes)
|
+–4 [java.lang.String] 72 bytes (24 bytes)
|
+–value [char[]] 48 bytes (48 bytes)

main().Deep Measure : 432

root [java.util.ArrayList]
|
+–elementData [java.lang.Object[]]
|
+–0 [java.lang.String]
| |
| +–value [char[]]
|
+–1 [java.lang.String]
| |
| +–value [char[]]
|
+–2 [java.lang.String]
| |
| +–value [char[]]
|
+–3 [java.lang.String]
| |
| +–value [char[]]
|
+–4 [java.lang.String]
|
+–value [char[]]

main().Count Child : 12

This JAMM Client Project is available in here.

Written by Namal Fernando

December 23, 2015 at 8:56 am

Posted in Java, Performance

Tagged with , , ,

Write XMPP client using Smack API

leave a comment »

Smack is written in Java. So, it is cross platform. Current version can be downloaded from here.

To start with this, create a Java Project (eg : XMPPProject) and, copy the “smack.jar” and “smackx.jar” files into your classpath.

These are two main classes for this application.

XmppManager.java


package com.javacodegeeks.xmpp;

import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.MessageListener;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.ConnectionConfiguration.SecurityMode;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Type;

public class XmppManager {

private static final int packetReplyTimeout = 500; // millis

private String server;
private int port;

private ConnectionConfiguration config;
private XMPPConnection connection;

private ChatManager chatManager;
private MessageListener messageListener;

public XmppManager(String server, int port) {
this.server = server;
this.port = port;
}

public void init() throws XMPPException {

System.out.println(String.format("Initializing connection to server %1$s port %2$d", server, port));

SmackConfiguration.setPacketReplyTimeout(packetReplyTimeout);

config = new ConnectionConfiguration(server, port);
config.setSASLAuthenticationEnabled(false);
config.setSecurityMode(SecurityMode.disabled);

connection = new XMPPConnection(config);
connection.connect();

System.out.println("Connected: " + connection.isConnected());

chatManager = connection.getChatManager();
messageListener = new MyMessageListener();

}

public void performLogin(String username, String password) throws XMPPException {
if (connection!=null &amp;&amp; connection.isConnected()) {
connection.login(username, password);
}
}

public void setStatus(boolean available, String status) {

Presence.Type type = available? Type.available: Type.unavailable;
Presence presence = new Presence(type);

presence.setStatus(status);
connection.sendPacket(presence);

}

public void destroy() {
if (connection!=null &amp;&amp; connection.isConnected()) {
connection.disconnect();
}
}

public void sendMessage(String message, String buddyJID) throws XMPPException {
System.out.println(String.format("Sending mesage '%1$s' to user %2$s", message, buddyJID));
Chat chat = chatManager.createChat(buddyJID, messageListener);
chat.sendMessage(message);
}

public void createEntry(String user, String name) throws Exception {
System.out.println(String.format("Creating entry for buddy '%1$s' with name %2$s", user, name));
Roster roster = connection.getRoster();
roster.createEntry(user, name, null);
}

class MyMessageListener implements MessageListener {

@Override
public void processMessage(Chat chat, Message message) {
String from = message.getFrom();
String body = message.getBody();
System.out.println(String.format("Received message '%1$s' from %2$s", body, from));
}

}

}

XmppTest.java


package com.javacodegeeks.xmpp;

public class XmppTest {

public static void main(String[] args) throws Exception {

String username = "testuser1";
String password = "testuser1pass";

XmppManager xmppManager = new XmppManager("myserver", 5222);

xmppManager.init();
xmppManager.performLogin(username, password);
xmppManager.setStatus(true, "Hello everyone");

String buddyJID = "testuser2";
String buddyName = "testuser2";
xmppManager.createEntry(buddyJID, buddyName);

xmppManager.sendMessage("Hello mate", "testuser2@myserver");

boolean isRunning = true;

while (isRunning) {
Thread.sleep(50);
}

xmppManager.destroy();

}

}

 

Description :
XMPPConnection – to Connect

This is basically to connect to the remote server. Connecting and performing the Login can be done as follows :

// Create a connection to the igniterealtime.org XMPP server.
XMPPConnection connection = new XMPPConnection("myxmppserver.com");
// Connect to the server
connection.connect();
// Most servers require you to login before performing other tasks.
connection.login("myuser", "mypass");

 

ConnectionConfiguration – to configure sohisticated conection attributes

This can be used to achieve more sophisticated connection attributes. In this case, various parameters can be configured (server host, port and securrity -encrypt- issues). You can use SmackConfiguration class to configure an internal Smack stack.


ConnectionConfiguration config = new ConnectionConfiguration(serverHost, serverPort);
XMPPConnection connection = new XMPPConnection(config);
connection.connect();
connection.login("myuser", "mypass");

 

ChatManager – to manages chats
From a valid XMPPConnection, you can recive a ChatManager object. This keeps a referenc to all current chats and it allows you to create chat instances (series of messages sent between two users). Chat objects can send messages to the other participants. These messages can be a plain String or construted XMPP messages represented by the Message class.

 

Message class – messages
Message class provides the direct access to all message attributes (eg : message types).

 

MessageListener – to listen
To process incoming messages, you must implement the MessageListener and attach it to the chat.


ChatManager chatManager = connection.getChatManager();
Chat chat = chatManager.createChat("mybuddy", new MyMessageListener());
chat.sendMessage(message);

 

Presence – to setup the status
You can set your online status using the Presence class.


Presence presence = new Presence(Presence.Type.available);
presence.setStatus("What's up everyone?");
connection.sendPacket(presence);

 

Roster – allocate user(s)
A new buddy can be allowcated to your list by using the Roasterr class. A user’s Roaster is a collection of users a persion recieves presence updates for. A user can be associaated with a group too.


Roster roster = connection.getRoster();
roster.createEntry(user, name, null);

 

Note :
In this example no security authentication is done (it is disabled). So, there’s no any protection on the credentials and the messages and the messages that has been exchanged.
Here, an infinite loop has been created (via isRunning boolean) to send the message from the other client and see the response from the console. In real time situaations, this must be set as false if the program exit. And the thread must be slept for some time otherwise machine’s CPU will be much higher.

You can find the project in here.

Related Articles :

Written by Namal Fernando

December 18, 2015 at 6:44 am

Posted in Smack API

Tagged with , , ,

Manage Google Calendars in Java

leave a comment »

Do Step 1 as mentioned in [developers.google.com]

Step 1: Turn on the Google Calendar API

  1. Use this wizard to create or select a project in the Google Developers Console and automatically turn on the API.
  2. Click Continue, then Go to credentials.
  3. At the top of the page, select the OAuth consent screen tab. Select an Email address, enter a Product name if not already set, and click the Save button. (These are the options you will display to the user when you asking for the permission for the app via consent screen).
  4. Select the Credentials tab, click the Add credentials button and select OAuth 2.0 client ID.
  5. Select the application type Other, enter the name of the app “eg : Google Calendar API Quickstart”, and click the Create button.
  6. Click OK to dismiss the resulting dialog.
  7. Click the (Download JSON) button to the right of the client ID.
  8. Move this file to your working directory and rename it client_secret.json. This is the one that you will use to communicate with the Google app via Java program.

 

This is the Java class that you can use to manage the Calenders.

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.client.util.DateTime;
import com.google.api.services.calendar.CalendarScopes;
import com.google.api.services.calendar.model.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;

public class CalendarQuickstart {

private static final String APPLICATION_NAME = "Google Calendar API Java Quickstart";

private static final java.io.File DATA_STORE_DIR = new java.io.File(
System.getProperty("user.home"), ".credentials/calendar-java-quickstart-1.0.0");

private static FileDataStoreFactory DATA_STORE_FACTORY;
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

private static HttpTransport HTTP_TRANSPORT;

private static final List&lt;String&gt; SCOPES = Arrays.asList(CalendarScopes.CALENDAR);

static {
try {
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
} catch (Throwable t) {
t.printStackTrace();
System.exit(1);
}
}

/**
* Creates an authorized Credential object.
* @return an authorized Credential object.
* @throws IOException
*/
public static Credential authorize() throws IOException {

InputStream in = CalendarQuickstart.class.getResourceAsStream("/client_secret_1.0.0.json");
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(DATA_STORE_FACTORY)
.setAccessType("offline")
.build();

Credential credential = null;
try { credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("namal");} catch (Exception e) {}

System.out.println("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());

return credential;
}

/**
* Build and return an authorized Calendar client service.
* @return an authorized Calendar client service
* @throws IOException
*/
public static com.google.api.services.calendar.Calendar getCalendarService() throws IOException {

Credential credential = authorize();

return new com.google.api.services.calendar.Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
}

private static void viewCalenders() throws IOException {

com.google.api.services.calendar.Calendar service = getCalendarService();

String pageToken = null;

do {
CalendarList calendarList = service.calendarList().list().setPageToken(pageToken).execute();
List&lt;CalendarListEntry&gt; items = calendarList.getItems();

for (CalendarListEntry calendarListEntry : items) {
System.out.println("viewCalenders()." + calendarListEntry.getSummary() + " --&gt; " + calendarListEntry.getId() + " --&gt; " + calendarListEntry.getAccessRole());
}

pageToken = calendarList.getNextPageToken();

} while (pageToken != null);

}

private static void insertEvent() throws IOException {

com.google.api.services.calendar.Calendar service = getCalendarService();

Event event = new Event()
.setSummary("Google I/O 2 2016/15")
.setLocation("800 Howard St., San Francisco, CA 94103")
.setDescription("A chance to hear more about Google's developer products.");

DateTime startDateTime = new DateTime("2015-12-15T09:00:00-07:00");

EventDateTime start = new EventDateTime()
.setDateTime(startDateTime)
.setTimeZone("America/Los_Angeles");

event.setStart(start);
DateTime endDateTime = new DateTime("2015-12-16T17:00:00-07:00");
EventDateTime end = new EventDateTime()
.setDateTime(endDateTime)
.setTimeZone("America/Los_Angeles");
event.setEnd(end);

String[] recurrence = new String[] {"RRULE:FREQ=DAILY;COUNT=2"};
event.setRecurrence(Arrays.asList(recurrence));
EventAttendee[] attendees = new EventAttendee[] {
new EventAttendee().setEmail("lwepage@example.com"),
new EventAttendee().setEmail("swebrin@example.com"),
};

event.setAttendees(Arrays.asList(attendees));
EventReminder[] reminderOverrides = new EventReminder[] {
new EventReminder().setMethod("email").setMinutes(24 * 60),
new EventReminder().setMethod("popup").setMinutes(10),
};

Event.Reminders reminders = new Event.Reminders()
.setUseDefault(false)
.setOverrides(Arrays.asList(reminderOverrides));

event.setReminders(reminders);

String calendarId = "primary";
event = service.events().insert(calendarId, event).execute();

System.out.printf("Event created: %s\n", event.getHtmlLink());

}

private static void viewEvents() throws IOException {

// Build a new authorized API client service.
// Note: Do not confuse this class with the
// com.google.api.services.calendar.model.Calendar class.

com.google.api.services.calendar.Calendar service = getCalendarService();

// List the next 10 events from the primary calendar.
DateTime now = new DateTime(System.currentTimeMillis());

Events events = service.events().list("primary")
.setMaxResults(10)
.setTimeMin(now)
.setOrderBy("startTime")
.setSingleEvents(true)
.execute();

List&lt;Event&gt; items = events.getItems();

if (items.size() == 0) {
System.out.println("No upcoming events found.");
} else {
System.out.println("Upcoming events");
for (Event event : items) {
DateTime start = event.getStart().getDateTime();
if (start == null) {
start = event.getStart().getDate();
}

System.out.printf("%s (%s)\n", event.getSummary(), start);
}
}
}

public static void main(String[] args) throws IOException {
// viewCalenders();
viewEvents();
// insertEvent();
}

}

Dependencies :
You must download all the dependencies (eg : google client, google 0auth client etc) for this. There are 49 jars so far.
<dependencies>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.20.0</version>
</dependency>

<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-calendar</artifactId>
<version>v3-rev125-1.20.0</version>
</dependency>

<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-jetty</artifactId>
<version>1.20.0</version>
</dependency>
</dependencies>

Here is the list of jars.

commons-cli-1.0.jar
commons-codec-1.3.jar
commons-lang-2.1.jar
commons-logging-1.1.1.jar
doxia-sink-api-1.0-alpha-7.jar
fit-google-calander-1.0.0.jar
google-api-client-1.20.0.jar
google-api-services-calendar-v3-rev125-1.20.0.jar
google-http-client-1.20.0.jar
google-http-client-jackson2-1.20.0.jar
google-oauth-client-1.20.0.jar
google-oauth-client-java6-1.20.0.jar
google-oauth-client-jetty-1.20.0.jar
guava-jdk5-13.0.jar
httpclient-4.0.1.jar
httpcore-4.0.1.jar
jackson-core-2.1.3.jar
jetty-6.1.26.jar
jetty-util-6.1.26.jar
jsr305-1.3.9.jar
junit-3.8.1.jar
maven-archiver-2.4.2.jar
maven-clean-plugin-2.4.1.jar
maven-common-artifact-filters-1.3.jar
maven-compiler-plugin-2.3.2.jar
maven-filtering-1.0.jar
maven-install-plugin-2.3.1.jar
maven-jar-plugin-2.3.2.jar
maven-reporting-api-2.0.6.jar
maven-reporting-api-2.0.9.jar
maven-resources-plugin-2.5.jar
maven-surefire-common-2.10.jar
maven-surefire-plugin-2.10.jar
plexus-archiver-2.0.1.jar
plexus-build-api-0.0.4.jar
plexus-compiler-api-1.8.1.jar
plexus-compiler-javac-1.8.1.jar
plexus-compiler-manager-1.8.1.jar
plexus-digest-1.0.jar
plexus-interactivity-api-1.0-alpha-4.jar
plexus-interpolation-1.13.jar
plexus-io-2.0.1.jar
plexus-utils-2.0.5.jar
plexus-utils-2.1.jar
plexus-utils-3.0.jar
servlet-api-2.5-20081211.jar
surefire-api-2.10.jar
surefire-booter-2.10.jar
surefire-junit3-2.10.jar

Here’s the interesting part – MY FINDINGS –

APPLICATION_NAME –
This should be the same name that you used for the OAuth 2.0 client ID.

DATA_STORE_DIR –
This is the directory where data (credentials etc) retrieved from the authorized users from the consent screen.

SCOPES –
There are two main scopes here.
1. CalendarScopes.CALENDAR : This is used to Manage the Calendar (Read, Insert, Delete, Update etc) data
2. CalendarScopes.CALENDAR_READONLY : This is used to only Read the Calender data
These scopes are very important when you grant the App permission from a user through the consent screen. It says you are asking the permission to Manage the Calendar or only Read the Calendar.
client_secret_1.0.0.json
This is the client secret that you have downloaded from the OAuth 2.0 client ID setup. This is Used to communicate with the Google App you have created as mentioned earlier. In this example it should be in the root folder. Anyway the path and name must be provided as below.

InputStream in = CalendarQuickstart.class.getResourceAsStream("/client_secret_1.0.0.json");

Grant the permission and credenials for a user.

Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("namal");

In this case when you are run the authorize method for the first time on each user (eg : namal as per .authorize(“namal”) ), iit will provide you a URL to display the consent screen

https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=123456789101-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com&redirect_uri=http://localhost:12345/Callback&response_type=code&scope=https://www.googleapis.com/auth/calendar

Then once run that on a browser you will be requested for permission for currently logged-in google account. If you haven’t logged-in yet you will be asked to log-in then will be requested for permission. Here, the consent screen contains the information you provided when you set-up it as mentioned earlier (eg : Developer’s email address, Product Name, Logo, URL for your site, Policies, Terms of Service, Permission you are requesting as mentioned in the SCOPE etc).

ConsentScreen

Then when you are Allowed, it will display the success message as mentioned below.

http://localhost:12345/Callback?code=1/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#
Received verification code. You may now close this window…

Here, in this case, the credentials (of the google account used to allow the app) will be stored against the mentioned user (eg : “namal”) in DATA_STORE_DIR. So, you can use that user as the key to access the Google Calender (s) belongs to the Google account that allowed the app. This way you can manage Google Calender(s) of multiple Google Accounts using the keys.

View Calendar events

In this case, the Calender for the user’s email address will be mentioned as the “primary” one.

Events events = service.events().list("primary")
.setMaxResults(10)
.setTimeMin(now)
.setOrderBy("startTime")
.setSingleEvents(true)
.execute();

You can specify the Calender ID -as mentioned in the viewCalenders() method- to obtain events in a perticular caleder. You can get this Calender ID from the Calendar Setting’s Calendar Address area.

Events events = service.events().list("xxxxxxxxxxxxxxxxxxxxxxxxxx@group.calendar.google.com")
.setMaxResults(10)
.setTimeMin(now)
.setOrderBy("startTime")
.setSingleEvents(true)
.execute();

You can check the applications enabled for your google account via :
https://security.google.com/settings/security/permissions

References :

Written by Namal Fernando

December 15, 2015 at 6:48 am

Import Project from Remote Repository to the eclipse

leave a comment »

1. Go to [File] > [Import]

1

Select project from Git (type “git” in the search field if needed)

{Git} > {Project from Git} > [ Next ]

2

Click on [Clone URI] and hit [Next]

1

2. Copy the Cloned URL from remote GIT repository.

2

3. Paste it in the URI area in eclipse window. (Of course you need the authentication details)

3

It will get the branch information. Select a branch (or master), click [Next]

Configure the local storage location for the Project.

Screenshot from 2015-04-10 07:50:33

After this step it will take you to the same path that can be followed to import a project from local git repository.

Written by Namal Fernando

April 10, 2015 at 7:54 am

Posted in Eclipse, GIT

Tagged with ,

How to commit a file to the remote git repository

leave a comment »

1. Commit it to the local repository

Right Click on the file [Team] > [Commit]

Add the Commit message and Hit [Commit]. (You can so this also by Right Click on the local repository in Git view)

Screenshot from 2015-04-10 07:17:19

2. Go to the local git repository


cd /rezsystem/workspace/demo-parsers

3. Just Push it! (Of course, it will ask the user name and password for the remote repo)


$ git push

Reference :

Written by Namal Fernando

April 10, 2015 at 7:18 am

Posted in Eclipse, GIT

Tagged with

How to import a GIT project from local Git repositories to the eclipse

with 2 comments

Method 1

Go to [File] > [Import]

1

Select project from Git (type “git” in the search field if needed)

{Git} > {Project from Git} > [ Next ]

2

Select Existing local repository (There’s an option also to get it directly from the Git repository too)

3

Select a Git repository

Select a Git repository from the list. (Or you can add an exisiting Git project to the list using the [Add] button and then select from there)

4

Just click [Next]

5

Finally [Finish] (as usually 😉 ). Here in the screenshot it is not selected to add and Finish is disabled since I have already imported it.

6

Or You can directly import from the Git perspective by Right Click on the relevant Git Repository and click on [Import Projects..]

7

Written by Namal Fernando

April 10, 2015 at 7:08 am

Posted in Eclipse, GIT

Tagged with

How to Add Existing local Git repositories to the eclipse view

leave a comment »

1. Open GIT perspective in eclipse
GoTo [Window] > {Open Perspective} > [Other]

1

Select [Git] > [OK]
2

This will take the Git Repositories view with the perspective to the eclipse.

2. Add Existing Git repositories
Click on the [Git and + mark] icon with the tooltip saying “Add Existing local Git repositories to this view”.
3

Browse the project converted to the Git and hit [OK]
4

In the big white textArea the .git with yellow icon will be selected (In the screen shot it is not there since the project is already added. Feel a bit lazy to create another and add 😉 )
5

Then it will add the project to the git repo view

6

If you can see the navigator, it will be also in there with the GIT information in square brackets.

7

If your project is not yet opened in eclipse…
Check post on How to import a GIT project from local Git repositories to the eclipse

Written by Namal Fernando

April 10, 2015 at 6:45 am

Posted in Eclipse, GIT

Tagged with ,

Adding a local project to the GITHUB

leave a comment »

1. Install GIT in Linux

sudo apt-get install git

or Synaptic Package Manager > git.

 

2. Create a repository in github (eg : CamelInAction)

repo-create

 

3.cd to the local project directory. (cd /rezsystem/workspace/CamelInAction)

 

4. Initialize the local project directory as a Git local repository.

git init

 

5. Add the git related files in to your new local repository. This stages them for the first commit.

git add .

6. Commit the files that you’ve staged in your local repository. Here, this will commit the tracked changes and prepares them to be pushed to a remote repository.

git commit -m 'First commit'

In this case, you may get a below like warning.

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got 'namal@namal.(none)')

In this case, run the config commands as below.

git config --global user.email "namal@yahoo.com"
git config --global user.name "namalfernandolk"

 

7. Copy the remote repository URL.(GitHub repository, in the right sidebar)

copy-remote-repository-url

 

8. In Terminal, add the URL for the remote repository where your local repository will be pushed.
– Sets the new remote

git remote add origin https://github.com/namalfernandolk/CamelInAction.git

– Verifies the new remote URL

git remote -v

9. Push the changes in your local repository to GitHub. Here, it will pushes the changes in your local repository up to the remote repository you specified as the origin.

git push -u origin master

Here, In this step if you are getting 407 error.(eg : error: The requested URL returned error: 407 while accessing https://github.com/namalfernandolk/CamelInAction.git/info/refs
), add the proxy authentication details as (proxy = http://username:passwd@your-proxy-ip:your-proxy-port) to the git conf file. This will be the /rezsystem/workspace/CamelInAction/.git/conf file or .gitconfig file that is located in your $HOME folder.

Reference :

Written by Namal Fernando

June 30, 2014 at 8:45 am

Posted in GIT

Tagged with ,

Demo REST project with Camel CXF

leave a comment »

1. Create a .war project (java 1.7 or above) using Maven as follows.

Here we are using the eclipse as the IDE and the Maven. The prefered java version is 1.7 or greater.

1-create_maven_war_prj

2. This is the folder structure of it once it is created.

2-folderStructure

3. Include the necessary dependencies to the pom.xml file as follows.

Here, we’re mainly include the Apache Camel (including camel cxf jars), Apache Common IO and SLF4j jars. Camel is using Common IO internally so it must be also used. And spring jars are also used in here. Springs are used to load the ApplicationContexts automatically.


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>demo.restapi</groupId>
<artifactId>demo.restapi</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<name>Rest API demo project</name>
<description>Rest API demo project</description>

<properties>
<camel-web>2.5.0</camel-web>
<camel-version>2.12.0</camel-version>
<xbean-spring-version>3.5</xbean-spring-version>
</properties>

<dependencies>

<!-- Spring + Camel jars -->

<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<version>${xbean-spring-version}</version>
</dependency>

<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spring</artifactId>
<version>${camel-version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jms</artifactId>
<version>${camel-version}</version>
</dependency>

<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-stream</artifactId>
<version>${camel-version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.4.RELEASE</version>
</dependency>

<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf</artifactId>
<version>${camel-version}</version>
</dependency>

<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-cxf-transport</artifactId>
<version>${camel-version}</version>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>2.7.6</version>
</dependency>

<!-- Other jars (logging, io etc) -->

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>

</dependencies>

</project>

4. Add the below configurations to the WEB-INF/web.xml

Here, we are adding the applicationContext.xml as the contextConfigLocation and the listener classes. Package of the  all routers implementation classes must be mentioned in the applicationContext.xml.


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:web="http://xmlns.jcp.org/xml/ns/javaee"
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 <context-param>
 <param-name>test</param-name>
 <param-value>true</param-value>
 </context-param>
 <context-param>
 <param-name>contextConfigLocation</param-name>
 <param-value>/WEB-INF/applicationContext.xml</param-value>
 </context-param>
 <listener>
 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
</web-app>

5. Add the below configurations to the WEB-INF/applicationContext.xml.

The package containing all the routes must be specified in the camelContext/camel:package tag. Here in our demo project, the router is mentioned in the camel.route package.


<?xml version="1.0" encoding="UTF-8"?>
<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
 license agreements. See the NOTICE file distributed with this work for additional
 information regarding copyright ownership. The ASF licenses this file to
 You under the Apache License, Version 2.0 (the "License"); you may not use
 this file except in compliance with the License. You may obtain a copy of
 the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
 by applicable law or agreed to in writing, software distributed under the
 License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
 OF ANY KIND, either express or implied. See the License for the specific
 language governing permissions and limitations under the License. -->

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xmlns:camel="http://camel.apache.org/schema/spring" xmlns:p="http://www.springframework.org/schema/p"
 xsi:schemaLocation="
 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
 http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
 ">

<bean id="contextApplicationContextProvider" class="conf.ApplicationCtxProvider"></bean>

 <camelContext xmlns="http://camel.apache.org/schema/spring"
 id="Demo-Camel">

 <!-- All the Routes should be created within below Package -->
 <camel:package>camel.route</camel:package>

 </camelContext>

</beans>

6. Add the ApplicationContext classes

These classes are loaded during the Spring-Initialization.

a. ApplicationCtxProvider

This class which implements ApplicationContextAware, is automatically loaded during Spring-Initialization.


package conf;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class ApplicationCtxProvider implements ApplicationContextAware {

@Override
public void setApplicationContext(ApplicationContext ctx)
throws BeansException {
ApplicationCtx.setApplicationContext(ctx);
}
}

b.ApplicationCtx.

This is injected from the class “ApplicationCtxProvider” which is automatically loaded during Spring-Initialization. This get access to the Spring ApplicationContext from everywhere in your Application.


package conf;

import org.springframework.context.ApplicationContext;

public class ApplicationCtx {

private static ApplicationContext ctx;

// Injected from the class "ApplicationCtxProvider" which is automatically loaded during Spring-Initialization.

public static void setApplicationContext(
ApplicationContext applicationContext) {
ctx = applicationContext;
}

// Get access to the Spring ApplicationContext from everywhere in your Application.

public static ApplicationContext getApplicationContext() {
return ctx;
}
}

7. Implement the Camel router (DemoRouteBuilder).

This class is the router that takes all the REST calls to our REST service. To be run automatically, this must be included in the camel.route as it is mentioned in the aplicationContext.xml. So, it will run automatically start to run when the server is starting. Here we are mentioning the cxfrs URI that will be considered as the Endpoint URI. Here we should specify the resourceClasses to point the request to the implementation. Here,  http://localhost:9003/rest is considered as the root URI for the REST service. Rest of the path will be defined in the resource classes. Here, MappingProcessor implements the Camel Process


package camel.route;

import org.apache.camel.builder.RouteBuilder;

import camel.process.MappingProcessor;
import rs.DemoRequestServiceImpl;

public class DemoRouteBuilder extends RouteBuilder {

private static final String REST_ENDPOINT_URI = "cxfrs://http://localhost:9003/rest?resourceClasses=rs.DemoRequestServiceImpl";

@Override
public void configure() {
errorHandler(noErrorHandler());

from(REST_ENDPOINT_URI)
.routeId("RestFulService")
.process(new MappingProcessor(new DemoRequestServiceImpl()));
}

}

8. Implement the Camel Processes (MappingProcessor).

Here, MappingProcessor implements the Camel Process. It takes the REST Impl instance and uses the reflection in the process method for it’s implementation as below.


package camel.process;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.component.cxf.common.message.CxfConstants;
public class MappingProcessor implements Processor {

private Class<?> beanClass;
private Object instance;

public MappingProcessor(Object obj) {
beanClass = obj.getClass();
instance = obj;
}

@Override
public void process(Exchange exchange) throws Exception {
String operationName = exchange.getIn().getHeader(CxfConstants.OPERATION_NAME, String.class);
Method method = findMethod(operationName,exchange.getIn().getBody(Object[].class));
try {
Object response = method.invoke(instance, exchange.getIn().getBody(Object[].class));
exchange.getOut().setBody(response);
} catch (InvocationTargetException e) {
throw (Exception) e.getCause();
}
}

private Method findMethod(String operationName, Object[] parameters)throws SecurityException, NoSuchMethodException {
return beanClass.getMethod(operationName,getParameterTypes(parameters));
}

private Class<?>[] getParameterTypes(Object[] parameters) {
if (parameters == null) {
return new Class[0];
}
Class<?>[] answer = new Class[parameters.length];
int i = 0;
for (Object object : parameters) {
answer[i] = object.getClass();
i++;
}
return answer;
}

}

9. Creating the Rest IMPL classes.

Here, this is the main IMPL classes of the REST implementation. Here the paths are defined by using the @Path annotation. Here, the main path is defined as the /hotelservice. So, each method defined in this class must be called starting from http://localhost:9003/rest/hotelservice. Each implementation methods is defined with dedicated paths.

Here,  getAvailabilityResults(Long id) will be called as http://localhost:9003/rest/hotelservice./hotels/10. Here this methods takes the Long path parameter as 10. And it will be forwarded to the concrete implementation in DemoRequestServiceImpl.java class. Here, getAvailabilityResults is defined as a GET method and getSearhResults(String request) as a POST methos.

a. IDemoRequestService.java

package rs;

import javax.jws.WebParam;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("/hotelService")
@Consumes("application/json")
@Produces(MediaType.APPLICATION_JSON)
public interface IDemoRequestService {

 @GET
 @Path("/hotels/{id}")
 @Produces(MediaType.APPLICATION_JSON)
 Response getAvailabilityResults(@PathParam("id") Long id); 

 @POST
 @Path("/search")
 @Produces(MediaType.APPLICATION_JSON)
 String getSearhResults(@WebParam(name="request") String request); 

}

b. DemoRequestServiceImpl.java

package rs;

import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DemoRequestServiceImpl implements IDemoRequestService {

 final Logger logger = LoggerFactory.getLogger(DemoRequestServiceImpl.class);

 @Override
 public String getSearhResults(String request) {

 logger.info("getSearhResults().request : " + request);

 return "Hello request " + request;
 }

 @Override
 public Response getAvailabilityResults(Long id){

 logger.info("getSearhResults().Long : " + id);
 return Response.ok("Hello request ID :"+id).status(Status.OK).build();
 }

}

9. Final Folder structure.

3-final-folder-structure

10. Build the project by running the pom.xml through Maven.

Here, I have used clean install package as the maven goal. I executed the maven goals within the eclipse.

11. Deploy the demo.restapi-1.0.0.war in a web container like tomcat.

Here, I used the tomcat8 to deploy the REST service. When tomcat is starting, router is deployed automatically. Then the specified requests (GET ot POST) we are sent to the END POINT URI will be taken to process by the router.

12. Test the GET method.

Here, we can test the GET method using the browser as follows

Hit http://localhost:9003/rest/hotelService/hotels/17 in the browser and get the response as “Hello request ID :17”

13. Test the POST method

– Await !!!

Written by Namal Fernando

June 29, 2014 at 5:18 pm

Static analysis with HammurAPI

leave a comment »

Install the HammurAPI.

1

2

  • Then go to the path that hammurapi-5.7.0-setup.jar is downloaded.
  • Install hammmurapi using this command in the terminal.
    • java -jar hammurapi-5.7.0-setup.jar
  • Then this will install hammerapi in your home folder. This contains DB (HSQLDB) and Tomcat also in the same package (eg : /home/namal/Hammurapi)

Start the DB (HSQLDB)

  • Go to the /home/namal/Hammurapi/db.
  • Give the excecution permission to runServer.bat.
  • Run it. (I double clicked and selected to “Run In the Terminal”).
    • The default port for the db is 9001. If the port is already bound, kill it after identifying the process ids using the netstat commands as mentioned below and run the runServer.bat again.
      • netstat –listen – You’ll get all the port numbers currently using
      • netstat -lpn | grep 9001 – You’ll get the process with process id that is using the port 9001
      • sudo kill 4758 : kill it

Start the Tomcat

  • Go to the /home/namal/Hammurapi/tomcat/bin
  • Give the excecution permission to ./startup.sh
  • Run it as ./startup.sh
  • If not executing run chmod +x *.sh first and then run it ./startup.sh again.
  • Test it with the http://localhost:8080

Install the ant to your system

3

  • Download the apache-ant-1.9.3-bin.zip archive using the mentioned link.
  • Extract it to some directory. (In my case I copied it to the project folder that I’m willing to test)

Test the provided sample project.

There’s a sample project in the Hammurapi. We can test it first to verify that everything is OK behind the scene.

  • Go to the /home/namal/Hammurapi/sample
  • Run the following tasks on build.xml
    • apache-ant-1.9.3/bin/ant
    • apache-ant-1.9.3/bin/ant review
    • apache-ant-1.9.3/bin/ant -Dhammurapi.report.id=2 wget
      • Here the report will be extracted into the /home/namal/Hammurapi/report folder
      • In this case provide the hammurapi.report.id as a VM argument as mentioned above.

Test the project.

  • Take the project to the /home/namal/Hammurapi folder.
  • Put all the related jars refering from it in the lib folder.
  • Copy the build.xml to that folder.
  • Follow above tasks mentioned in the sample project

Reference

Written by Namal Fernando

May 1, 2014 at 7:49 am

Posted in HammurAPI, Static Analysis

Tagged with , ,

SSL Certificate installation using keytool in Linux

leave a comment »

Download the certificate using the browser. and save to a download folder (/rezsystem/jboss-4.0.3SP1/bin/certs/)

Browse the keystore.

keytool -list -keystore /rezsystem/jboss-4.0.3SP1/bin/certs/mycert.keystore

Delete the particular key by alias (api.abreuonline.com) if exists.

keytool -delete -keystore /rezsystem/jboss-4.0.3SP1/bin/certs/mycert.keystore -alias api.abreuonline.com

Install the certificate again to the keystore from the downloaded location by alias (api.abreuonline.com).

keytool -keystore /rezsystem/jboss-4.0.3SP1/bin/certs/mycert.keystore -import -v -trustcacerts -alias api.abreuonline.com -file /rezsystem/jboss-4.0.3SP1/bin/certs/api.abreuonline.com

Check certificates using sslshopper.

Written by Namal Fernando

February 25, 2014 at 10:13 am

Posted in SSL

Tagged with , ,

How to recover eclipse?

leave a comment »

Follow this if your eclipse got crashed.

  • Delete the .lock file in the workspace/.metadata folder and restart the IDE
  • If this is not working delete the .snap file in the workspace/.metadata/.plugins/org.eclipse.core.resources and restart the IDE
  • If this is also not working
    • cd .metadata/.plugins
    • mv org.eclipse.core.resources org.eclipse.core.resources.bak
    • Start eclipse. (It should show an error message or an empty workspace because no project is found.)
    • Close all open editors tabs.
    • Exit eclipse.
    • rm -rf org.eclipse.core.resources (Delete the newly created directory.)
    • mv org.eclipse.core.resources.bak/ org.eclipse.core.resources (Restore the original directory.)
    • Start eclipse and start working.

More about the .lock

Eclipse comes with a locking mechanism that is on a ‘per workspace’ basis to ensure that there is no data corruption; only one Eclipse instance can operate on a particular workspace at a time, and as such each workspace is locked while it is open for business.

So… how do you break in to Eclipse when you leave your keys on the dresser? Well, it’s actually quite simple. When a workspace is brought up by a particular instance, that Eclipse instance will produce a ‘ .lock ‘ file and store it in a special folder for that workspace. Each workspace captures unique settings in a ‘.metadata ‘ folder. As a side note, this is also where the unique Eclipse workspace settings are stored.

If you are on Eclipse 2.1, to get back in to Eclipse so you can do your needed work, simply delete your ‘ [Workspace Home]/.metadata/.lock ‘ file.

As of Eclipse 3.0, however, the existence of the file is no longer the relevant state. The good news is that reserved file locks should happen a lot less now due to the nature of the locking mechanism. The bad news is it is somewhat less apparent how to unlock the environment if something does go wrong. Eclipse 3.0 will attempt to use an operating system file lock on the .lock file (file lock on the lock file, that’s a mouthful). If, for some reason, Eclipse cannot lock this file, in 99% of the cases simply restarting your OS will clear up any file locks or file handles that may be in place. It also doesn’t hurt to delete the file, but chances are if you can delete the file, Eclipse could lock it – so this probably isn’t a plausible solution.

The remaining 1% of the cases are more than likely caused because you are fiddling with folder permissions, and Eclipse can’t write to the .metadata folder. Bad user!

More About .snap file

It looks like your eclipse platform is crashing quite often. Because otherwise, the snapshot files should not be there while the platform is not running. As the referenced page in roe’s comment explains, they are just needed for crash recovery and are deleted during normal shutdown of the platform. Deleting them will make eclipse think, that no crash occurred but then it can’t recover and you may have to refresh/rebuild your workspace (which may take the same time).

I’d not delete those files except eclipse won’t recover from a crash. Have a look at the eclipse workspace and platform log files if you have troubles with some plugins and fight the problem from this side (updating plugins or sending error reports) instead of deleting those files.

Written by Namal Fernando

November 6, 2013 at 4:25 pm

Posted in Eclipse

Tagged with , ,

Why it cannot be to create an Array of generic ArrayLists (eg : ArrayList[])?

leave a comment »

Why first try says “Cannot create a generic array of ArrayList<String>”.

ArrayList<String>[] arryListArry = new ArrayList<String>[4];

Answer :

If the first one is allowed to do, followig will be happend.

ArrayList<String>[] alist = new ArrayList<String>[10];
Object[] olist = alist; // This is okay because ArrayList is an Object
olist[0] = new ArrayList<Dog>();
olist[0].add(new Dog());
String s = alist[0].get(0); //Uh oh, Dog is not string

Ok versions :

ArrayList[] arryListArry = new ArrayList[4];
ArrayList<String>[] arryListArry = new ArrayLis[4];
ArrayList<ArrayList<String>> arryListArry= new ArrayList<ArrayList<String>>(4);

Written by Namal Fernando

October 22, 2013 at 7:35 am

Posted in Java, Q&A

Tagged with , , ,

Java Reflection 2 – How to invoke private methods and read private fields

with one comment

Followings provides only public fields and methods.

Class.getField(String name);
Class.getFields();
Class.getMethod(String name, Class[] parameterTypes);
Class.getMethods();

You must do two things to access the non-public fields and methods.
1. Get them as declared ones

Class.getDeclaredField(String name);
Class.getDeclaredFields();
Class.getDeclaredMethod(String name, Class[] parameterTypes);
Class.getDeclaredMethods();

2. Make setAccessible(true) on them

Otherwise this will throw  java.lang.IllegalAccessException.

Example :

Tester.java


package reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import reflection.anotherPackage.GeneralTestee;

public class Tester {

public static void main(String[] args) throws Exception {
 Tester tester = new Tester();
 tester.reflect();
 }

 public void reflect() throws Exception{

 Class testeeCls = Class.forName("reflection.anotherPackage.Testee");

 Constructor testeeConstructor = testeeCls.getConstructor(null);
 GeneralTestee generalTestee = (GeneralTestee) testeeConstructor.newInstance(null);
 System.out.println("reflect().generalTestee : " + generalTestee);

 Field[] testeeFields = testeeCls.getDeclaredFields(); // This gets all a,b,c,d
// Field[] testeeFields = testeeCls.getFields(); // This gets only a
 for (int i = 0; i < testeeFields.length; i++) {
 Field testeeField = testeeFields[i];
 testeeField.setAccessible(true);
 System.out.println(testeeField.getName() + " : " + testeeField.get(generalTestee));

 }

 Method[] testeeMethods = testeeCls.getDeclaredMethods();
 for (int i = 0; i < testeeMethods.length; i++) {
 Method testeeMethod = testeeMethods[i];
 testeeMethod.setAccessible(true);
 Object retObj = testeeMethod.invoke(generalTestee, null);
 System.out.println(testeeMethod.getName() + " : " + retObj );
 }
 }
}

Testee.java


package reflection.anotherPackage;

import java.security.Permission;

public class Testee extends GeneralTestee{

 public String a = "pu_blic";
 protected String b = "pro_tected";
 String c = "de_fault";
 private String d = "pri_vate";

 public String meth_A(){
 return "Successfully read " + a + " | "+ b + " | "+ c + " | "+ d +" in a public method";
 }

 protected String meth_B(){
 return "Successfully read " + a + " | "+ b + " | "+ c + " | "+ d +" in a protected method";
 }

 String meth_C(){
 return "Successfully read " + a + " | "+ b + " | "+ c + " | "+ d +" in a default method";
 }

 private String meth_D(){
 return "Successfully read " + a + " | "+ b + " | "+ c + " | "+ d +" in a private method";
 }

}

GeneralTestee.java


package reflection.anotherPackage;

public class GeneralTestee {}

How to avoid / control this private access in reflection

– Will be discussed with Java Reflection 3 – SecurityManager –

Written by Namal Fernando

August 14, 2013 at 5:16 pm

Posted in Java, Reflection

Tagged with ,

Java Reflection 3 – Avoiding access to the Private methods and fields with SecurityManager

leave a comment »

SecurityManager is an object that defines the security policy for an application. These SecurityPolicies defines the actions that are unsafe or sensitive and any action that is not allowed by this, causes a SecurityException to be thrown.
Normally, web applets like limited applications are running with a security manager. But other applications are normally running without SecurityManager unless the applications defines one by itself.

This can be widely used in many areas like Files and System Properties, Thread control, Networking, Object serialization and many applications like restricting access to specific functions like reading/writing.

SecurityManager can be integrated in two main ways
1. By having a reference of your own SecurityMenager file.
2. Through a .policy file referenced by the VM arguments

Once the application has a reference to the SecurityManager, it can request permission to do specific things. Many classes in the standard libraries uses this. (Eg : System.exit invokes SecurityManager.checkExit to ensure that the current thread has permission to shut down the application.).

1. By having a reference of your own SecurityManager file.

In SecurityManager, each operation / group of operations has its own chckXXX() method as follows. But application doesn’t have to directly invoke any checkXXX() method and also the application will consult it iff the code said so and it won’t call it in each operation once it is intergrated.

Example :

Tester.java


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Tester {

public static void main(String[] args) throws Exception {
 Tester tester = new Tester();
 tester.reflect();
 }

public void reflect() throws Exception{
 Class testeeCls = Class.forName("security.mySecurityManager.anotherPackage.Testee");
 Constructor testeeConstructor = testeeCls.getConstructor(null);
 GeneralTestee generalTestee = (GeneralTestee) testeeConstructor.newInstance(null);
 System.out.println("reflect().generalTestee : " + generalTestee);

Field[] testeeFields = testeeCls.getDeclaredFields();

 for (int i = 0; i < testeeFields.length; i++) {
 Field testeeField = testeeFields[i];
 testeeField.setAccessible(true);
 System.out.println(testeeField.getName() + " : " + testeeField.get(generalTestee));
 }

}
}

Testee.java


import security.mySecurityManager.GeneralTestee;
import security.mySecurityManager.NewSecurityManager;

public class Testee extends GeneralTestee{

 static{
 try {
 System.setSecurityManager(new NewSecurityManager("1"));
 } catch (SecurityException se) {
 System.out.println("SecurityManager already set!");
 }
 }

 public String a = "pu_blic";
 protected String b = "pro_tected";
 String c = "de_fault";
 private String d = "pri_vate";

}

GeneralTestee.java


public class GeneralTestee {}

NewSecurityManager.java


import java.io.DataInputStream;
import java.io.IOException;
import java.security.Permission;

public class NewSecurityManager extends SecurityManager{

public NewSecurityManager(String password) {
 this.password = password;
 }

public void checkPermission(Permission perm) {
 if(perm.getName().equals("suppressAccessChecks")){
 if(!accessOK()) throw new SecurityException("You are drunk. Please go home!");
 }
 }

private boolean accessOK() {
 DataInputStream dis = new DataInputStream(System.in);
 String response;
 System.out.println("Pasword please : ");

 try {
 response = dis.readLine();
 if (response.equals(password)) return true;
 else return false;
 } catch (IOException e) {
 return false;
 }
 }

String password = null;

}

2. Through a .policy file referenced by the VM arguments

1. Create a policy file (security.policy) and grant the permission for the desired areas.

java.awt.AWTPermission
java.io.FilePermission
java.net.NetPermission
java.util.PropertyPermission
java.lang.reflect.ReflectPermission
java.lang.RuntimePermission
java.security.SecurityPermission
java.io.SerializablePermission
java.net.SocketPermission

2. Execute the file providing the following VM arguments with the .policy file path.

-Djava.security.manager -Djava.security.policy=security.policy

Example :

Tester.java


import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Tester {

public static void main(String[] args) throws Exception {
 Tester tester = new Tester();
 tester.reflect();
 }

public void reflect() throws Exception{
 Class testeeCls = Class.forName("security.policyFile.anotherPackage.Testee");
 Constructor testeeConstructor = testeeCls.getConstructor(null);
 GeneralTestee generalTestee = (GeneralTestee) testeeConstructor.newInstance(null);
 System.out.println("reflect().generalTestee : " + generalTestee);

Field[] testeeFields = testeeCls.getDeclaredFields();

 for (int i = 0; i < testeeFields.length; i++) {
 Field testeeField = testeeFields[i];
 testeeField.setAccessible(true);
 System.out.println(testeeField.getName() + " : " + testeeField.get(generalTestee));
 }

}
}

Testee.java


import security.policyFile.GeneralTestee;

public class Testee extends GeneralTestee{

 public String a = "pu_blic";
 protected String b = "pro_tected";
 String c = "de_fault";
 private String d = "pri_vate";

}

GeneralTestee.java


public class GeneralTestee {}

security.policy


grant {
 permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
};

Written by Namal Fernando

August 14, 2013 at 2:41 am

Posted in Java, Reflection

Tagged with , ,

Speedup the log4j logging in eclipse

with one comment

This is the method that I found to speedup the logging.

1. Go to Windows > Preferences

0

2. Go to Java > Editor > Templates in there and create a new template or select the Existing one to edit

1

3. Sample command

logger.info(“${enclosing_mathod}().${word_selection} : ” + ${word_selection}${});${cursor}

(Note : If you are copy paste this. Please replace the ” by typing double quotes. It will not added as double quotes.)

2

4. It’s Show-Time!!!

  • Type the variable you want to log
  • Select it.
  • Press Ctrl + Space
  • Type shortcut name you added or edited (eg: li) to select it from the drop down suggestions.
  • Hit enter and see what happens.

Written by Namal Fernando

August 14, 2013 at 12:03 am

Posted in Eclipse, log4j

Tagged with , ,

Java Reflection 1 – Accessing classes, interfaces, fields, methods at the run-time without knowing their names at the compile time

with 4 comments

This allows invoking classes, interfaces, fields and methods at the run-time without knowing their names at the compile time. It is also possible to instantiate new objects, invoke methods and get / set values using the reflections.

Classes


Class aClass = AClass.class; // If you know the class name at compile time :
 Class aClass = Class.forName("com.jenkov.myapp.AClass"); // If you don't know the class name at compile time but have the class name as a string at runtime

 String className = aClass.getName(); //Class Name With package name :
 String simpleClassName = aClass.getSimpleName(); //Without package name :

 int modifiers = aClass.getModifiers(); // Obtain the Class modifiers. Modifier is a flag bit that is either set or cleared and all the modifires like class modifiers here are packed in to one int
 Modifier.isProtected(modifiers);
 Modifier.isPublic(modifiers);
 Modifier.isStatic(modifiers);

 Package package = aClass.getPackage();

 Class superclass = aClass.getSuperclass();

 Class[] interfaces = aClass.getInterfaces(); // Here only the interfaces that directly implemented the invoked class are returned

 Constructor[] constructors = aClass.getConstructors();

 Method[] method = aClass.getMethods();

 Field[] field = aClass.getFields();

 Annotation[] annotations = aClass.getAnnotations();

Constructors


// If you don't know the precise parameter types.
 Constructor[] constructors = aClass.getConstructors();
 Class[] parameterTypes = constructor.getParameterTypes(); // Read set of parameters for a given constructor in the order

// If you know the precise parameter types.
 Constructor constructor = aClass.getConstructor(new Class[]{String.class,String.class}); // getConstructor(String.class , String.class) and getConstructor(new Class[]{String.class,String.class}) are same.

AClass aClassObj = (AClass)constructor.newInstance("constructor-arg1"); // Creating an object

Fields


//If you don’t know the field name :
Field[] fileds = aClass.getFields();
String fieldName = field.getName();

//If you know the field name :
Field field = aClass.getField("someField");

Object fieldType = field.getType(); // Field type

//If the field is an instance field you can get and set the values like this :
Object value = field.get(objectInstance);
field.set(objetInstance, value);

//If the field is a static field pass null as the objectInstance parameter passed above.

Methods


//If you don’t know the method name
Method[] methods = aClass.getMethods();
String methodName = method.getName();
Class[] parameterTypes = method.getParameterTypes();

//If you know the method name and the it’s parameter Types (types, numbers and order) :
Method method = aClass.getMethod("doSomething", new Class[]{String.class}); // If it takes no parameters, pass it as null

Class returnType = method.getReturnType();

Object returnValue = method.invoke(objetInstance, "parameter-value1"); //If the method is a static method, pass null as the objectInstance parameter passed above. This must pass the exactly same number of arguments that was mentioned in the method definition.

Private Fields and Private Methods

– Will be available at the Java Reflection 2 –

Written by Namal Fernando

August 12, 2013 at 11:09 pm

Posted in Java, Reflection

Tagged with ,

Why is [427.14 + 61.02 != 488.16] in double and how to do it in correct way?

leave a comment »

Followings are some scenarios that I experienced and information that I found in The need for BigDecimal by John Zukowski and StackOverFlow posts.

The BigDecimal class stores floating-point numbers with practically unlimited precision. To manipulate the data, you call the add(value), subtract(value), multiply(value), or divide(value, scale, roundingMode)methods.

To output BigDecimal values, set the scale and rounding mode with setScale(scale, roundingMode), or use either the toString() or toPlainString() methods. The toString() method may use scientific notation whiletoPlainString() never will.

Available roundingMode enumerations

  • CEILING which always rounds towards positive infinity
  • DOWN which always rounds towards zero
  • FLOOR which always rounds towards negative infinity
  • UP which always rounds away from zero
  • HALF_DOWN which always rounds towards nearest neighbor, unless both neighbors are equidistant, in which case it rounds down
  • HALF_UP which always rounds towards nearest neighbor, unless both neighbors are equidistant, in which case it rounds up
  • UNNECESSARY which asserts exact result, with no rounding necessary

Don’t create a BigDecimal from a primitive type like this.

double dd = .35;
BigDecimal d = new BigDecimal(dd); // here d = .34999999999999997779553950749686919152736663818359375

Instead create a BigDecimal as follows


BigDecimal d = new BigDecimal(".35");

After creating the value, you can explicitly set the scale of the number and its rounding mode with setScale(). Like other Number subclasses in the Java platform, BigDecimal is immutable, so if you call setScale(), you must “save” the return value:


d = d.setScale(2, RoundingMode.HALF_UP);

Example :


package floatingPoints;

import java.math.BigDecimal;

public class TestingFloatingPoints {

public static void main(String[] args) {

 TestingFloatingPoints testingFloatingPoints = new TestingFloatingPoints();
 testingFloatingPoints.floatingPointsInDouble();
 testingFloatingPoints.floatingPointsInBigDecimle();

 }

 private void floatingPointsInDouble() {

 double total = 427.14;
 double tax = 61.02;
 double taxedTotal = tax + total; // This is 488.15999999999997

 }

 private void floatingPointsInBigDecimle() {

 BigDecimal total = new BigDecimal("427.14");
 BigDecimal tax = new BigDecimal("61.02");
 BigDecimal taxedTotal = total.add(tax); // This is 488.16

}

}

According to the Peter Lawry, The exact reason is that you get a number slightly less than you expect is that 427.14 is actually 427.1399999999999863575794734060764312744140625 and 61.02 is actually 61.02000000000000312638803734444081783294677734375 and when you add these together you get the nearest double value to 488.15999999999998948396751075051724910736083984375 which is slightly less than you expected. If you round this to 2 decimal places you get the expected answer 488.16

You can check the corresponding binary value for each floating point number by using binaryconvert.com.

Another comment for floating point numbers in StackOverFlow

Remember, a decimal value can not be represented exactly in a computer” It can, it just isn’t in IEEE 754 floating point. – T.J. Crowder

It can, if you have infinite memory. In a practical sense, and for the general case, it can’t. – Óscar López

@ Óscar: No, that’s not true at all. It’s just a matter of how many decimal places you want to hold. Or more accurately, how many significant digits you want. To get about the same range as a double but with perfect decimal accuracy, you only need about 56 significant digits and an indicator of where the decimal point goes. Of course, decimal numbers have their own issues, such as not being able to accurately store 1 / 3. 😉 – T.J. Crowder

Written by Namal Fernando

August 6, 2013 at 4:31 pm

Posted in Java, Q&A

Tagged with , ,

Java compiler settings for e-clipse when creating a jar file (ANT / MAVEN).

leave a comment »

This is a common thing that will miss at most of the times. We must consider all of these build paths while using eclips.

1. This is the Java Build Path

1.BuildPath-Libraries

2

2. This is the Java Compiler

3

3. This is the ANT – External Tool Configuration

4

5

4.This is the Maven Run Configuration

6

7

You can easily check the java version of a class file by using

WINDOWS > javap -verbose TraceLogger | find "version"

LINUX > javap -verbose TraceLogger | grep version

javap -verbose TraceLogger will out put all details with the versions Java versions:

  • Java 1.2 uses major version 46
  • Java 1.3 uses major version 47
  • Java 1.4 uses major version 48
  • Java 5 uses major version 49
  • Java 6 uses major version 50
  • Java 7 uses major version 51

Written by Namal Fernando

August 5, 2013 at 1:02 pm

Posted in Eclipse

Tagged with , , , ,

SOLID – SRP (Single Relationship Principle)

leave a comment »

This is the principle that simply described through cohesion.

Facts :

Each responsibility should be a separate class.

Because each responsibility is an axis of change.

So simply, there should never be more than one reason for a class to change.

Example :

Bad SRP Design

WeatherDisplay.java

public class WeatherDisplay{

 private int temperature;
 private int windSpeed;

public WeatherDisplay(int temperature, int windSpeed){
 this.temperature = temperature;
 this.windSpeed = windSpeed;
 }

public void DisplayWeather(){
 DisplayTemperature();
 DisplayWindSpeed();
 }

private void DisplayTemperature(){
 System.out.println("The current temperature is: " + temperature + " degrees celcius.");
 }

 private void DisplayWindSpeed(){
 System.out.println("The current wind speed is: " + windSpeed + " meters per second.");
 }
}

Here, WeatherDisplay class has two distinct responsibilities (display Temperature and display Wind Speed). So,  There’s two reason to change the WeatherDisplay class in the future. (Eg :  the temperature should be displayed in Fahrenheit and the wind speed should be displayed in knots)

Good SRP Desing

WeatherDisplay.java

public class WeatherDisplay{

 private DisplayTemperature displayTemperature;
 private DisplayWindSpeed displayWindSpeed;

public WeatherDisplay(int temperature, int windSpeed){
 displayTemperature = new DisplayTemperature(temperature);
 displayWindSpeed = new DisplayWindSpeed(windSpeed);
 }

public void DisplayWeather(){
 displayTemperature.Display();
 displayWindSpeed.Display();
 }
}

DisplayTemperature.java


public class DisplayTemperature{
 private int temperature;

public DisplayTemperature(int temperature){
 this.temperature = temperature;
 }

public void Display(){
 System.out.println("The current temperature is: " + temperature + " degrees celcius.");
 }
}

DisplayWindSpeed.java


public class DisplayWindSpeed{
 private int windSpeed;

public DisplayWindSpeed(int windSpeed){
 this.windSpeed = windSpeed;
 }

public void Display(){
 System.out.println("The current wind speed is: " + windSpeed + " meters per second.");
 }
}

Here because of delegating the responsibilities for each classes, each class have one responsibility hence each have exact one reason to change it

Written by Namal Fernando

August 4, 2013 at 4:48 pm

OCP – Open Close Principle

with 7 comments

This is firstly described by Bertrand Mayer as “software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”.

This is basically for designing a code as can be acted more robust when you need to add a new feature.

It makes the code more strong by making it Open for Extension and Closed for modification.

How to make a class open for extension and closed for modification at the same time?

You can make a class closed for modification by open it for extension.

So, in the Bad OCP version, the implementation logic for each sub class is included in the centralized control hub. But in the Good OCP version the implementation is delegate to each sub classes. So no need to change the centralized code each time you need to add a new feature.

Bad OCP Design

AreaCalculator .java

package ocp.bad;

import ocp.bad.shapes.Circle;
import ocp.bad.shapes.Rectangle;
import ocp.bad.shapes.Shape;

public class AreaCalculator {

public double caclculateArea(Shape[] shapes){
double totalArea = 0d;

for (Shape shape : shapes) {

double area = 0d;

if(shape instanceof Rectangle){
area = ((Rectangle) shape).getHeight() * ((Rectangle) shape).getWidth();
System.out.println("Area of the rectangle : "+area);
}else if (shape instanceof Circle){
area = ((Circle) shape).getRadius() * ((Circle) shape).getRadius() * Math.PI;
System.out.println("Area of the circle : "+area);
}
// When more shapes added more else-if need to be added s and changes of the code here.

totalArea += area;
}
System.out.println("Returning totalArea : "+totalArea);
return totalArea;
}

}

Shape.java

package ocp.bad.shapes;

public class Shape {}

Rectangle.java

package ocp.bad.shapes;

public class Rectangle extends Shape {

	public Rectangle( double width, double height) {
		this.width 	= width;
		this.height = height;
	}

	public double getWidth() {
		return width;
	}

	public double getHeight() {
		return height;

	}

	private double width = 0d;
	private double height = 0d;

}

Circle.java

package ocp.bad.shapes;

public class Circle extends Shape {

	public Circle(double radius) {
		this.radius = radius;
	}

	public double getRadius() {
		return radius;
	}

	private double radius = 0d;

}

Good OCP Design

Here, the implementation logic (what it differs has been delegated to its own sub classes). So, no need to change the centralized code each time you need to add a new feature.

AreaCalculator .java

package ocp.good;

import ocp.good.shapes.Shape;

public class AreaCalculator {

	public double caclculateArea(Shape[] shapes){
		double totalArea = 0d;

		for (Shape shape : shapes) {

			totalArea += shape.calculateArea();
			// When more shapes added no need to change here. Implementation has deligate to the new objects through abstraction
		}
		System.out.println("Returning totalArea : "+totalArea);
		return totalArea;
	}

}

Shape.java

package ocp.good.shapes;

public abstract class Shape {
	public abstract double calculateArea();
}

Rectangle.java

package ocp.good.shapes;

public class Rectangle extends Shape {

	public Rectangle( double width, double height) {
		this.width 	= width;
		this.height = height;
	}

	@Override
	public double calculateArea() {
		return width * height;
	}

	private double width = 0d;
	private double height = 0d;

}

Circle.java

package ocp.good.shapes;

public class Circle extends Shape {

	public Circle(double radius) {
		this.radius = radius;
	}

	@Override
	public double calculateArea() {
		return radius * radius * Math.PI;
	}

	private double radius = 0d;

}

References :

Written by Namal Fernando

July 28, 2013 at 4:20 pm

Create / Build / Package and Deploy web service(s) with Axis2

leave a comment »

Create a java project using the created WSDL mentioned post Create a WSDL for a WebService

Initially the project structure will be like mentioned below.

1_pub_projectstructure

Generate the server code using Axis2CodeGen pluggin :

Select File > Select New > Click Other…

Select Axis2 Code Generator under the Axis2 Wizrds and Click Next

Select Generate the Java Source code from the WSDL file option and Click Next

Provide the WSDL file location eg : /rezsystem/workspace/MathService/src/gradethree/wsdl/GradeThreeMath.wsdl Use Browse button if you need.

Select
CodeGen Option : custom
Generate Service Side Code
Generate a default services.xml
Generate interface for Skeleton

Provide an Output Path (eg : /home/namal/Desktop/WORKS/WS/Math/Grade3). Use Browse button if needed.

Click Finish.

Take generated files to the project

This will generate the files mentioned in the LHS of the below image. Put those files in to the project as mentioned in the RHS.
Here, I have added resources and the server code to a seperate package (gradethree) since I have an intension to add another WebService within this same Project. You need to modify the package declarations in the Server Code and the services.xml

2_pub_folder_structure

Implement the logics in the GradeThreeMathSkeleton class.

eg : for Addition Operation


public gradethree.org.tempuri.AdditionResponse Addition(gradethree.org.tempuri.AdditionRequest additionRequest0){

AdditionResponse additionResponse = new AdditionResponse();

int operand1 = additionRequest0.getOperand1();
int operand2 = additionRequest0.getOperand2();

additionResponse.setResult(operand1+operand2);
additionResponse.setRemarks("This is enough for Grade Three Addition!");

return additionResponse;

}

Packaging : Generate the aar and jar files using the build.xml

Ant task :

<echo>Building GradeThreeMath AAR</echo>
<delete dir="${classes}/META-INF" />
<copy toDir="${classes}/META-INF" failonerror="false">
<fileset dir="${resources}/gradethree">
<include name="*.xml" />
<include name="*.wsdl" />
<include name="*.xsd" />
</fileset>
</copy>

<jar destfile="${lib}/GradeThreeMath.aar">
<fileset dir="${classes}">
<include name="META-INF/**" />
</fileset>
</jar>

<jar destfile="${lib}/GradeThreeMath.jar">
<fileset dir="${classes}">
<include name="gradethree/**" />
</fileset>
</jar>

So, this will return the GradeThreeMath.jar and GradeThreeMath.aar as follows.

3_pub-packaging

 

Deploy :

You can deploy them as mentioned below
4_pub-dployment

Start the server.

WSDL : http://localhost:8081/axis2/services/GradeThreeMath?wsdl

You can test the service using the SOAP UI with above WSDL as below

5_pub_soapui

You can add another service also within the same project, build/package with another ant task and deploy as mentioned in the below project.

6_pbl

Project lin : https://github.com/namalfernandolk/MathService.git

Written by Namal Fernando

October 25, 2016 at 9:09 am

Posted in WebServices

Tagged with ,

Create a WSDL for a WebService

leave a comment »

We are creaeting this web service from Top-Down approach. That means we are creating the WSDL first and then create the web service using that.

Understanding a WSDL:
There are main 6 sections in a WSDL.

  • wsdl:definitions
  • wsdl:service
  • wsdl:binding
  • wsdl:portType
  • wsdl:message
  • wsdl:types

wsdl:service

The element defines the ports supported by the web service. For each of the supported protocols, there is one port element. So, the service element is a collection of ports.

Web service clients can learn the following from the service element:

  1. where to access the service,
  2. through which port to access the web service, and
  3. how the communication messages are defined.

The service element includes a documentation element to provide human-readable documentation.

eg :

	<wsdl:service name="GradeThreeMath">
		<wsdl:port name="GradeThreeMathPort" binding="tns:GradeThreeMathBinding">
			<soap:address location="http://localhost:8081/axis2/services/GradeThreeMath" />
		</wsdl:port>
	</wsdl:service>

The binding attributes of port element associate the address of the service with a binding element defined in the web service.

wsdl:binding

The element provides specific details on how a portType operation will actually be transmitted over the wire.

  • The bindings can be made available via multiple transports including HTTP GET, HTTP POST, or SOAP.
  • The bindings provide concrete information on what protocol is being used to transfer portType operations.
  • The bindings provide information where the service is located.
  • For SOAP protocol, the binding is , and the transport is SOAP messages on top of HTTP protocol.
  • You can specify multiple bindings for a single portType.

The binding element has two attributes : name and type attribute. The name attribute defines the name of the binding, and the type attribute points to the port for the binding, in this case the “tns:Hello_PortType” port.

SOAP Binding

WSDL 1.1 includes built-in extensions for SOAP 1.1. It allows you to specify SOAP specific details including SOAP headers, SOAP encoding styles, and the SOAPAction HTTP header. The SOAP extension elements include the following:

  • soap:binding
  • soap:operation
  • soap:body

soap:binding

This element indicates that the binding will be made available via SOAP. The style attribute indicates the overall style of the SOAP message format. A style value of rpc specifies an RPC format. Normally we are using document in this case.

The transport attribute indicates the transport of the SOAP messages. The value http://schemas.xmlsoap.org/soap/http indicates the SOAP HTTP transport, whereas http://schemas.xmlsoap.org/soap/smtp indicates the SOAP SMTP transport.

soap:operation

This element indicates the binding of a specific operation to a specific SOAP implementation. The soapAction attribute specifies that the SOAPAction HTTP header be used for identifying the service.

soap:body

This element enables you to specify the details of the input and output messages. Here, the body element specifies the SOAP encoding style and the namespace URN associated with the specified service. We are using the literal as use to include XML as is.

eg :

	<wsdl:binding name="GradeThreeMathBinding" type="tns:GradeThreeMathPortType">

		<!-- Use document style and not rpc -->
		<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />

		<!-- Use 'literal' to include OTA XML as-is -->
		<wsdl:operation name="Addition">
			<soap:operation soapAction="Addition" style="document" />
			<wsdl:input>
				<soap:body use="literal" />
			</wsdl:input>
			<wsdl:output>
				<soap:body use="literal" />
			</wsdl:output>
		</wsdl:operation>

		<wsdl:operation name="Devision">
			<soap:operation soapAction="Devision" style="document" />
			<wsdl:input>
				<soap:body use="literal" />
			</wsdl:input>
			<wsdl:output>
				<soap:body use="literal" />
			</wsdl:output>
		</wsdl:operation>

	</wsdl:binding>

wsdl:portType

The element combines multiple message elements to form a complete one-way or round-trip operation.

For example, a can combine one request and one response message into a single request/response operation. This is most commonly used in SOAP services. A portType can define multiple operations.

eg :

	<wsdl:portType name="GradeThreeMathPortType">

		<wsdl:operation name="Addition">
			<wsdl:input message="tns:AdditionRequest" />
			<wsdl:output message="tns:AdditionResponse" />
		</wsdl:operation>

		<wsdl:operation name="Devision">
			<wsdl:input message="tns:DevisionRequest" />
			<wsdl:output message="tns:DevisionResponse" />
		</wsdl:operation>

	</wsdl:portType>

The portType element defines two operations, called Addition and Devision.

The Addition operation consists of a single input message AdditionRequest and an output message AdditionResponse.

Patterns of Operation

WSDL supports four basic patterns of operation:

One-way
The service receives a message. The operation therefore has a single input element.

Request-response
The service receives a message and sends a response. The operation therefore has one input element, followed by one output element. To encapsulate errors, an optional fault element can also be specified.

Solicit-response
The service sends a message and receives a response. The operation therefore has one output element, followed by one input element. To encapsulate errors, an optional fault element can also be specified.

Notification
The service sends a message. The operation therefore has a single outputelement.

wsdl:message

The element describes the data being exchanged between the web service providers and the consumers.

Each Web Service has two messages: input and output.

The input describes the parameters for the web service and the output describes the return data from the web service.

Each message contains zero or more parameters, one for each parameter of the web service function.

Each parameter associates with a concrete type defined in the container element.

eg : In Our Service, there are four messages as follows.

	<wsdl:message name="AdditionRequest">
		<wsdl:part name="AdditionRQ" element="tns:AdditionRequest" />
	</wsdl:message>
	
	<wsdl:message name="AdditionResponse">
		<wsdl:part name="AdditionRS" element="tns:AdditionResponse" />
	</wsdl:message>

	<wsdl:message name="DevisionRequest">
		<wsdl:part name="DevisionRQ" element="tns:DevisionRequest" />
	</wsdl:message>
	
	<wsdl:message name="DevisionResponse">
		<wsdl:part name="DevisionRS" element="tns:DevisionResponse" />
	</wsdl:message>

wsdl:types

A web service needs to define its inputs and outputs and how they are mapped into and out of the services. WSDL element takes care of defining the data types that are used by the web service. Types are XML documents, or document parts.

– The types element describes all the data types used between the client and the server.
– WSDL is not tied exclusively to a specific typing system.
– WSDL uses the W3C XML Schema specification as its default choice to define data types.
– If the service uses only XML Schema built-in simple types, such as strings and integers, then types element is not required.
– WSDL allows the types to be defined in separate elements so that the types are reusable with multiple web services.

Types can be mentioned within the WSDL as follows

<types>
   <schema targetNamespace="http://example.com/stockquote.xsd" xmlns="http://www.w3.org/2000/10/XMLSchema">
			
      <element name="TradePrice">
         <complexType>
            <all>
               <element name="price" type="float"/>
            </all>
         </complexType>
      </element>
		
   </schema>
</types>

or can be imported via a XSD as follows.

	<wsdl:types>
		<xs:schema>
			<xs:import namespace="http://tempuri.org/" schemaLocation="xsd/Math.xsd" />
		</xs:schema>
	</wsdl:types>

 

wsdl:definitions

The element must be the root element of all WSDL documents. It defines the name of the web service.

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
 xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
 xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema"
 targetNamespace="http://tempuri.org/" name="GradeThreeMathService">

From the above example, we can conclude that definitions:

– is a container of all the other elements.
– specifies the name of the service. eg : MathService.
– specifies multiple namespaces such as targetNamespace attribute which is a convention of XML Schema that enables the WSDL document to refer to itself, default namespace that all elements without a namespace prefix, (such as message or portType), are therefore assumed to be a part of this and many custome namespaces.

NOTE: The namespace specification does not require the document to be present at the given location. The important point is that you specify a value that is unique, different from all other namespaces that are defined.

Based on the above information we have created a WSDL (GradeThreeMath.wsdl) as follows using the below mentioned XSD (Math.xsd).

GradeThreeMath.wsdl :

<?xml version="1.0" encoding="UTF-8"?>

<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://tempuri.org/" name="GradeThreeMathService">

	<wsdl:types>
		<xs:schema>
			<xs:import namespace="http://tempuri.org/" schemaLocation="xsd/Math.xsd" />
		</xs:schema>
	</wsdl:types>




	<!-- Define request and response messages -->
	
	<wsdl:message name="AdditionRequest">
		<wsdl:part name="AdditionRQ" element="tns:AdditionRequest" />
	</wsdl:message>
	
	<wsdl:message name="AdditionResponse">
		<wsdl:part name="AdditionRS" element="tns:AdditionResponse" />
	</wsdl:message>

	<wsdl:message name="DevisionRequest">
		<wsdl:part name="DevisionRQ" element="tns:DevisionRequest" />
	</wsdl:message>
	
	<wsdl:message name="DevisionResponse">
		<wsdl:part name="DevisionRS" element="tns:DevisionResponse" />
	</wsdl:message>




	<!-- Define operation and reference messages -->

	<wsdl:portType name="GradeThreeMathPortType">

		<wsdl:operation name="Addition">
			<wsdl:input message="tns:AdditionRequest" />
			<wsdl:output message="tns:AdditionResponse" />
		</wsdl:operation>

		<wsdl:operation name="Devision">
			<wsdl:input message="tns:DevisionRequest" />
			<wsdl:output message="tns:DevisionResponse" />
		</wsdl:operation>

	</wsdl:portType>


	<!-- Define SOAP binding -->

	<wsdl:binding name="GradeThreeMathBinding" type="tns:GradeThreeMathPortType">

		<!-- Use document style and not rpc -->
		<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />

		<!-- Use 'literal' to include OTA XML as-is -->
		<wsdl:operation name="Addition">
			<soap:operation soapAction="Addition" style="document" />
			<wsdl:input>
				<soap:body use="literal" />
			</wsdl:input>
			<wsdl:output>
				<soap:body use="literal" />
			</wsdl:output>
		</wsdl:operation>

		<wsdl:operation name="Devision">
			<soap:operation soapAction="Devision" style="document" />
			<wsdl:input>
				<soap:body use="literal" />
			</wsdl:input>
			<wsdl:output>
				<soap:body use="literal" />
			</wsdl:output>
		</wsdl:operation>

	</wsdl:binding>

	<wsdl:service name="GradeThreeMath">
		<wsdl:port name="GradeThreeMathPort" binding="tns:GradeThreeMathBinding">
			<soap:address location="http://localhost:8081/axis2/services/GradeThreeMath" />
		</wsdl:port>
	</wsdl:service>
</wsdl:definitions>

Math.xsd :

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns="http://tempuri.org/" targetNamespace="http://tempuri.org/" elementFormDefault="qualified" version="1.0" id="MathRQ">
	
	<xs:element name="AdditionRequest">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="operand1" type="xs:int" />
				<xs:element name="operand2" type="xs:int" />
				<!-- <xs:element name="decimalPlaces" type="xs:int" /> -->
			</xs:sequence>
		</xs:complexType>
	</xs:element>

	<xs:element name="AdditionResponse">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="result" type="xs:double" />
				<xs:element name="remarks" type="xs:string" />
			</xs:sequence>
		</xs:complexType>
	</xs:element>

	<xs:element name="DevisionRequest">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="operand1" type="xs:int" />
				<xs:element name="operand2" type="xs:int" />
				<!-- <xs:element name="decimalPlaces" type="xs:int" /> -->
			</xs:sequence>
		</xs:complexType>
	</xs:element>

	<xs:element name="DevisionResponse">
		<xs:complexType>
			<xs:sequence>
				<xs:element name="result" type="xs:double" />
				<xs:element name="remarks" type="xs:string" />
			</xs:sequence>
		</xs:complexType>
	</xs:element>
	
</xs:schema>

Written by Namal Fernando

October 25, 2016 at 7:57 am

Posted in WebServices

Tagged with , ,

How to send a SOAP Request using CXF JAX-WS

leave a comment »

1.Create a Maven Project
1

2. WSDL setups

Download the WSDL file and put to the resources folder (/src/main/resources/). You can use the wsdl URL also without downloading.
Sample WSDL : http://www.webservicex.net/stockquote.asmx?WSDL

3. pom.xml configuration

Properties :

<properties>
	<cxf.version>2.6.1</cxf.version>
</properties>	

Dependencies :

<dependency>
	<groupId>org.apache.cxf</groupId>
	<artifactId>cxf-rt-core</artifactId>
	<version>${cxf.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.cxf</groupId>
	<artifactId>cxf-rt-frontend-jaxws</artifactId>
	<version>${cxf.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.cxf</groupId>
	<artifactId>cxf-rt-transports-http</artifactId>
	<version>${cxf.version}</version>
</dependency>

cxf-codegen-plugin configuration

<build>
	<plugins>
		<plugin>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-codegen-plugin</artifactId>
			<version>${cxf.version}</version>
			<executions>
				<execution>
					<id>StockQuote</id>
					<phase>generate-sources</phase>
					<configuration>
						<sourceRoot>${basedir}/target/generated/src/main/java</sourceRoot>
						<wsdlOptions>
							<wsdlOption>
								<wsdl>${basedir}/src/main/resources/stockquote.wsdl</wsdl>
							</wsdlOption>
						</wsdlOptions>
					</configuration>
					<goals>
						<goal>wsdl2java</goal>
					</goals>
				</execution>
			</executions>
		</plugin>
	</plugins>
</build>

You can use the WSDL URL also instead of ${basedir}/src/main/resources/stockquote.wsdl.

Comment this cxf-codegen-plugin configuration part after you generated the code.

4. Generate the wsdl2java code.

Run pom.xml with clean install goals. This will generate the source for the WSDL in the location mentioned in (eg:${basedir}/target/generated/src/main/java)

Copy and Paste the generated packages to src/main/java folder.

2

5. Develop the service

Find the Adddress
This is mentioned in wsdl:service/wsdl:port/soap:address@location. (eg:http://www.webservicex.net/stockquote.asmx)

Find the ServiceClass.
This is mentioned in the wsdl:service/wsdl:port/@name (eg: StockQuoteSoap)

eg :

<wsdl:service name="StockQuote">
	<wsdl:port name="StockQuoteSoap" binding="tns:StockQuoteSoap">
  		<soap:address location="http://www.webservicex.net/stockquote.asmx" />
	</wsdl:port>
</wsdl:service>

Create client using address and the ServiceClass

protected StockQuoteSoap createCXFClient() {
    JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
    factory.setServiceClass(StockQuoteSoap.class);
    factory.setAddress("http://www.webservicex.net/stockquote.asmx");
    return (StockQuoteSoap) factory.create();
}

Find the Operation (meethod name), Requeest parameter(s) and Response type using the wsdl

<wsdl:portType name="StockQuoteSoap">
	<wsdl:operation name="GetQuote">
	  <wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Get Stock quote for a company Symbol</wsdl:documentation>
	  <wsdl:input message="tns:GetQuoteSoapIn" />
	  <wsdl:output message="tns:GetQuoteSoapOut" />
	</wsdl:operation>
</wsdl:portType>

<wsdl:message name="GetQuoteSoapIn">
	<wsdl:part name="parameters" element="tns:GetQuote" />
</wsdl:message>

<wsdl:message name="GetQuoteSoapOut">
	<wsdl:part name="parameters" element="tns:GetQuoteResponse" />
</wsdl:message>
  • Method name : wsdl:portType/wsdl:operation/@name relevanet to the wsdl:service/wsdl:port/@binding
  • Requeest Parameter(s) : wsdl:message/wsdl:part/@element relevant to wsdl:portType/wsdl:operation/wsdl:input@name
  • Response Type : wsdl:message/wsdl:part/@element relevant to wsdl:portType/wsdl:operation/wsdl:output@name

Invoke the operation (method) using the created client

private void invokeJaxWs() {
	StockQuoteSoap client = createCXFClient();
	String response = client.getQuote("test123");
	System.out.println(response);
}

DONE!

GIT URL : <demo-cxf-jax-ws.git>

Written by Namal Fernando

August 2, 2016 at 7:32 am

Posted in Uncategorized

Ruth's Reflections

Contemplations from quakey quirky Christchurch

TED Blog

The TED Blog shares interesting news about TED, TED Talks video, the TED Prize and more.

Ziplok

Learn and discover simple things

Meihta Dwiguna Saputra's Knowledge Base

~In learning you will teach and in teaching you will (re)learn~

The Java Blog

Thoughts, tips and tricks about the Java programming language

Sparkles

that were shone when I got tempered!