Thursday, August 2, 2012

MongoDB and Java

MongoDB and Java
In this article, I would explain what MongoDB is?, how to use it with java.
MongoDB is a NOSQL database. It’s time that all data in the database would be stored in Document Oriented Storage. MongoDB is scalable, high-performance, open source NoSql database.
MongoDB supports asynchronous replication of data between servers for failover and redundancy. Only one server (in the set/shard) is active for writes (the primary, or master) at a given time – this is to allow strong consistent (atomic) operations. One can optionally send read operations to the secondaries when eventual consistency semantics are acceptable.
Two forms of replication are available, Replica Sets and Master-Slave. Use Replica Sets – replica sets are a functional superset of master/slave and are handled by much newer, more robust code.

MongoDB scales horizontally via an auto-sharding (partitioning) architecture. MongoDB sharding provides:
·         Automatic balancing for changes in load and data distribution
·         Easy addition of new machines without down time
·         Scaling to one thousand nodes
·         No single points of failure
·         Automatic failover

Starting and working on MongoDB shell
Once you install MongoDB, execute the MongoD.exe file in the bin directory. And mongo.exe file in the same directory.
You need to use Shell prompt to work with MongoDB, all commands will be issued using the shell prompt.
Connecting to database:
MongoDB by default connect to ‘test’ db, and later if you want to create/change to new db you need to use the command ‘use dbname’. DB will be created lazily when data is inserted.

From Java we can connect to the db using the following code snippet. Before that you need to download java driver for mongodb from www. Mongodb.org.
   final Mongo mongo = new Mongo();

        // or
  Mongo m = new Mongo( "localhost" );
        // or
  Mongo m = new Mongo( "localhost" , 27017 );
        // or, to connect to a replica set, supply a seed list of members
  Mongo m = new Mongo(Arrays.asList(new ServerAddress("localhost", 27017),
                                    new ServerAddress("localhost", 27018),
                                    new ServerAddress("localhost", 27019)));
  final DB db = mongo.getDB("test");

Creating a collection in MongoDB:
In mongoDB semantics a table will be referred to as collection. To create a collection we will use the following command
1.       You can directly insert a object to a collection, so that if the collection is not available MongoDB will create one.
2.       Else you can go for explicit creation of collection by

Here capped refers to capped collection, meaning fixed sized collections that have a very high performance auto-FIFO age-out feature (age out is based on insertion order). They are a bit like the "RRD" concept if you are familiar with that.
In addition, capped collections automatically, with high performance, maintain insertion order for the documents in the collection; this is very powerful for certain use cases such as logging.
Capped collections are not shard-able.

From java collection can be created by
DBObject options = BasicDBObjectBuilder.start().add("capped", true).add("size", 2000000000l).get();
        collection = db.createCollection("mytestcoll ", options);

db.getCollection("mytestcoll")

Inserting data in MongoDB:
To insert and save data , we need to use the following command in mongo shell
Db.collectionName.save(“data”);

To retrieve/find the inserted data , use the following command
Db.collectionname.find();


From java the same can by achieved using the following code snippets

  final DB db = mongo.getDB("sampledb");
        final DBCollection coll = db.getCollection("mytestcoll");
        Integer age = 27;
        String sex = "m";
        final BasicDBObject doc = new BasicDBObject();
        doc.put("name", "MongoDB");
        doc.put("age", age);
        doc.put("sex", sex);
        coll.insert(doc);

To retrieve data
  final DB db = mongo.getDB("sampledb");
  final DBCollection coll = db.getCollection("mytestcoll");
        final DBCursor results = coll.find();
        while (results.hasNext()) {
            final DBObject dbObject = results.next();
            final Object name = dbObject.get("name");
            final Object type = dbObject.get("type");
            System.out.println(name + "  :  " + type);
        }

Updating and deleteing a record from collection:
Updating a record:

To update a record in collection, you can fetch a record and assign to a variable in Javascript style and do the update as below

db.collection.update( criteria, objNew, upsert, multi )
Arguments:
criteria - query which selects the record to update;
objNew - updated object or $ operators (e.g., $inc) which manipulate the object
upsert - if this should be an "upsert" operation; that is, if the record(s) do not exist, insert one. Upsert only inserts a single document.
multi - indicates if all documents matching criteria should be updated rather than just one. Can be useful with the $ operators below.

Using java

BasicDBObject updateQuery = new BasicDBObject().append("$set",
                new BasicDBObject().append("type", "db serve"));
        
                //multi default to false
coll.update(new BasicDBObject().append("name", "mongo"), updateQuery);

To delete a record:

db.things.remove({name:”mongo”});

In java:

final BasicDBObject bdo = new BasicDBObject();
        bdo.put("name", "mongodb");
        coll.remove(coll.findOne());

MapReduce function:

Apart from this, MongoDB supports MapReduce functions, you can specify the mapper and reduce functions as string format and do the mapreduce process in MongoDb.

public class MongoMap {

    public static void main(final String[] args) throws UnknownHostException,
            MongoException {
        final Mongo mongo = new Mongo();

        final DB db = mongo.getDB("test");

        final DBCollection coll = db.getCollection("mapr");

        final String m =
                "function m() {" + "key = this.age ;"
                        + "emit( key, { count: 1 } ) ;" + "}";

        final String r =
                "function r( year, values ) { " + "var n = { count: 0}; "
                        + "for ( var i = 0; i < values.length; i++ ){"
                        + "n.count += values[i].count;" + "} " + "return n;"
                        + "}";

        final String f =
                "function f( year, value ){"
                        + "value.avg = value.sum / value.count;"
                        + "return value;" + "}";

        final MapReduceOutput out =
                coll.mapReduce(m, r, null, MapReduceCommand.OutputType.INLINE,
                        null);

        for (final DBObject obj : out.results()) {
            System.out.println(obj);
        }

    }
}

Thursday, February 16, 2012

Oracle Writing multi lingual characters with Oracle file IO

If you have multi lingual characters like chinese to be written in a file or excel sheet from tables, using orcale file IO, It requires UTF-8 conversion. Just convert the character to UTF8 and write it. I tried using the utl_file.put raw, but i failed. When i used the below, it was working fine for me.
 l_file_handle:= utl_file.fopen('D:\',test.csv','W');
utl_file.put_line(l_file_handle,convert(l_str_head1,'UTF8'),TRUE);

Oracle - Alternative to between operator

When your query has joins to multiple table, and also you need a date operation to be carried with between operator. Hope you need to compromise on the query performance. An alternative way is to use subquery and in operator instead. Consider the below query with between operator
select A.a,A.a1,A.a2,B.b3,B.b4,C.c5 from TableA A
inner join TableB B on A.a1=B.a1
inner join Table C on c.c1=B.c1
where A.a3 between '10-May-01' AND '10-May-05'.
The above query takes around 65 seconds in my Sql explorer. An alternative to the query above is shown below
select A.a,A.a1,A.a2,B.b3,B.b4,C.c5 from TableA A
inner join TableB B on A.a1=B.a1
inner join Table C on c.c1=B.c1
where A.a3 in (select A.a3 from TABLEA where A.a3 between '10-May-01' AND '10-May-05')
Just a change in the where clause with sub query improves the query performance, and the query took just 1.14 secs.
I faced this situation and thought it will be of help to share it. Execuse me if I am wrong or if it is worthless to take your time. I am just a starter with oracle database. :)

Clustering and Load Balancing of JBoss 4.2

JBoss Clustering
As you all might be knowing how to cluster JBoss, by surfing various sites and blogs. This article doesn’t make difference in briefing you about JBoss clustering and Apache Load balancing.

Let me start of with explaining cluster.
Cluster: A cluster is a set of nodes. In Jboss each node is Jboss server instance. Multiple Jboss instances on same machine and different machine in same network forms a cluster.
There might be different clusters, differentiated by the name across same network.

To start the Jboss in cluster mode you need to use the following command

run –c “all”

We can specify each jboss instance to join a specific cluster by  specifying the name in /server/all/deploy/cluster-service.xml file. The default name will be of default partition.

When you run multiple instances of Jboss in same machine, then you might get the port conflict(like port already in use). Its not recommended to use multiple instance of Jboss in same machine. But if required we can run multiple instance of Jboss in same machine by resolving the port conflict either manually changing all the conflicting ports or by configuring the sample-binding.xml file.

You can get all the ports of Jboss which run independently, in the sample-binding.xml file. Here each set of ports will be defined under server name (port-default,port-01), you can use this server name in /server/all/conf/jboss-service.xml of each jboss server instance , by either changing the port number or using default port numbers in the sample-binding.xml file. Before that to enable this feature you need to uncomment the following piece of code in /server/all/conf/jboss-service.xml

   <mbean code="org.jboss.services.binding.ServiceBindingManager"
    >
     <attribute>ports-01</attribute>
     <attribute>${jboss.home.url}/docs/examples/binding-manager/sample-bindings.xml</attribute>
     <attribute>
       org.jboss.services.binding.XMLServicesStoreFactory
     </attribute>
   </mbean>

You can even change the name and location of sample-binding.xml file.

Now let us start two Jboss server instances in same machine, to form a cluster automatically. For example,
http://localhost:8080/
http://localhost:8180/
Apache Load Balancing
After clustering Jboss we need to balance the load, and we need direct request to a jboss server with less load. (Also we need to have a common URL , instead exposing the clustered Joss servers url) . Here comes in picture, Apache web server.

In architecture, the apache web server will be placed in front of the Jboss server. Like the one shown in figure,



Now to configure the apache server,  for the cluster which we have created with 2 nodes in same machine. First download and install apache2.2.x. It will get installed in
/apache software foundation/apache2.2.x/.

First open the httpd.conf file under conf directory in your apache installation path and uncomment the following, which acts as connector between your webserver and Jboss application server.

LoadModule proxy_module modules/mod_proxy.soLoadModule proxy_balancer_module modules/mod_proxy_balancer.soLoadModule proxy_http_module modules/mod_proxy_http.so
Next add the following lines in your httpd.conf file. Which says the webserver about the nodes that form the cluster and its url. And what is the URL to the webserver that will pass the request to application deployed in Jboss server instance.

<Proxy balancer://mycluster>       Order deny,allow       Allow from all       BalancerMember http://localhost:8080/test route=node1       BalancerMember http://localhost:8180/test route=node2</Proxy>      ProxyPass /jmx-console balancer://mycluster stickysession=JSESSIONID lbmethod=bytraffic nofailover=Off  ProxyPassReverse /test  http://localhost:8080/testProxyPassReverse /test  http://localhost:8180/test  You need to use the sticky session attribute to make the request available to both the Jboss server , to server request even during failover of other server. To be simple maintaining or duplication of session created in one server on the other server.

Whenever you need change your httpd.conf file, remember to restart your apache webserver service also.

Now to use Sticky session in Jboss make change to your Jboss instance server.xml file, like the following

<Engine defaultHost="localhost" jvmRoute="node1">..
..
..
</Engine>

Atlast we need to tell the Jboss web to add the jvm route to the incoming sessions, by making the usejk attribute to true, in jboss-service.xml under /deploy/jboss-webdeployer.war/META-INF

<attribute>true</attribute>
Now start both of your jboss server instances in same machine. And restart the Apache webserver.

Hope you find this article useful.
 

Ajax - Using Ajax Tags

You might have heard of Auto complete in many applications and web sites, where you need to select a option instead from combo box. A simple example is of Airline site where you will select your Destination airport and origin airport.



From developer’s perspective, the implementation of Auto complete option was being made easy day by day. And now by the use of Ajaxtags, the auto complete option was made much easier than the easiest.



Ajaxtags is open source, which can be downloaded from http://ajaxtags.sourceforge.net/.



With the use of Ajaxtags, we can perform the following Ajax operations just by using a simple tag.

•AutoComplete
•Callout
•Tree
•Update
•Tab Panel/Tab
•Toggle
•Select Dropdown.


In this article will explain you Autocomplete tag.



To implement autocomplete option for a text field using Ajax tags, you just need to write a small piece of code in the server side either using servlet or using struts action class, and call the server side action using the Autocomplete tag.



Following are some of the attributes that are must for Ajax autocomplete tag, for complete reference of tag attributes please refer http://ajaxtags.sourceforge.net/usage.html.




Attribute
Required
Detail

baseUrl
yes
Url of server side action class or servlet that gives the list of values.

Source
Yes
Text field where the user enters the search string

Target
Yes
Text field where the autocomplete selection will be populated

Parameters
Yes
List of comma separated parameters that will be passed to the server side.









First we need to design a form which has a text field and we will implement auto complete option for it.



Following is the JSP page that contains a form having a text field and Ajax Autocomplete tag. Make sure to add the autocomplete tag outside the form tag.

<%@ taglib uri="http://ajaxtags.sourceforge.net/tags/ajaxtags" prefix="ajax" %>












































ajax:autocomplete example




















You can see a list of script file imported at the top of the JSP page. You can get those script file when you download ajaxtags. Make sure that the script files are imported in the following order else, you will get script error. Next we will write a servlet code that serves as the value for the autcomplete options.



import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;



import net.sourceforge.ajaxtags.servlets.BaseAjaxServlet;

import net.sourceforge.ajaxtags.xml.AjaxXmlBuilder;



public class Ajaxservlet extends BaseAjaxServlet{





public String getXmlContent(HttpServletRequest request,

HttpServletResponse response) throws Exception {

System.out.println("Inside Base ajax Servlet");

System.out.println("Request: "+request.getParameter("country"));

AjaxXmlBuilder temp=new AjaxXmlBuilder();

temp.addItem("Angola", "angola");

temp.addItem("Angola1", "UK");

temp.addItem("Angola2", "USA");

String country=temp.toString();

return country;

}



}



Here in this servlet we are adding the value in name value pair, to ajaxxmlbuilder. When the servlet is called , the response of this servlet will be in XML format.



Make this as a war file and deploy it in a web container. You can see the autcomplete working for the text field defined.

EJB3 and JAAS Security

In this article, we will see how to implement JAAS security for a EJB3 Bean with JBOSS application sever, and how a stand alone client access the EJB in a secured manner. Here we will have a stateless session bean , configured in a secured domain named Trng. In the application server we need to configure a login module and the domain settings corresponding to the name. In the client side we will just configure login module, which will just pass the credentials to the server security domain. Below is the piece of code for bean class and remote interface.
@Stateless
@SecurityDomain("Trng")
@Remote(TestEjb.class)

public class TestEjbBean implements TestEjb{//,TimedObject{

@Resource
private SessionContext ctx;
@RolesAllowed(value="admin")
public String getMessage(String message) {
System.out.println("Message from client:: "+message+":");
System.out.println("CALLER IDENTITY"+ctx.getCallerPrincipal());
return "Hello "+message;
}
}
@Remote
public interface TestEjb extends java.rmi.Remote{
public String getMessage(String message);
}
In the above piece of code we have a method getMessage() which is secured and it can accessed only by the client having role admin. And you can notice how the security domain is configured for the bean. Using the @SecurityDomain("TRNG") it tells the bean that it belongs to the particular security domain. The security domain can be configured to use any loging module that the App server provides or the custom one which the user can write. In this example I am using a simple uersroleslogin module. Its configured within JBOSS_HOME/server/default/conf/login-config.xml. Following shows the configuration of the domain named Trng.
<application-policy name="Trng">
      <authentication>
        <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
          flag="required">
          <module-option name="usersProperties">props/users.properties</module-option>
          <module-option name="rolesProperties">props/roles.properties</module-option>
          <module-option name="unauthenticatedIdentity">anonymous</module-option>
        </login-module>
      </authentication>
    </application-policy>
Next we will create a standalone client , which will access the secured bean in a secured manner. For that we need to have a loginmodule in the client side, as dicussed earlier this login module should pass the credentials to the server side login module. Following is the configuration of loginmodule in the client side with file name auth.conf
clientlogin{org.jboss.security.ClientLoginModule required;
 };
Name of the login module is clientlogin. This has the login module ClientLoginModule passing the credentials to the server.
Following is the piece of code for the client that access the secured bean in seured manner.
public static void main(String[] args) throws NamingException, LoginException {
String authFile="D:/ui_rds1/temp/src/auth.conf";System.setProperty("java.security.auth.login.config", authFile);
LoginCallBackHandler lc=new LoginCallBackHandler("admin","admin");LoginContext loginContext=
new LoginContext("clientlogin",lc);
loginContext.login();
System.out.println("Logged In");
Properties p=new Properties();p.setProperty(
"java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory" );
p.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces" );p.setProperty(
"java.naming.provider.url", "hostname:jnpport" );
InitialContext ic=new InitialContext(p);System.
out.println("Inititial context created");
TestEjb testEjb=(TestEjb) ic.lookup("TestEjbBean/remote");System.
out.println("Got the reference of Remote Interface");
System.out.println("Resulte from EJB::->"+testEjb.getMessage("Meiyappan"));
loginContext.logout();
testEjb.getMessage("sdfdsf");
}
In the above client set the system property to have the value of the location of conf file, which contains the loginmodule. Then we need to have a callback handler in which we will pass the username and password to the LoginContext. Following is a simplecall back handler class.
public class LoginCallBackHandler implements CallbackHandler{
private String username;
/**
* Password which will be set in the PasswordCallback, when PasswordCallback is handled
*/ private String password;
/**
* Constructor
* @param username The username
* @param password The password
*/
public LoginCallBackHandler(String username, String password) {
this.username = username;
this.password = password;
}
/**
* @param callbacks Instances of Callbacks
* @throws IOException IOException
* @throws UnsupportedCallbackException If Callback is other than NameCallback or PasswordCallback
*/ public void handle(Callback callbacks[]) throws IOException, UnsupportedCallbackException {
for(int i = 0; i < callbacks.length; i++) {
if(callbacks[i] instanceof NameCallback) {
NameCallback nc = (NameCallback)callbacks[i];
nc.setName(username);
System.out.println("USER NAME:: "+username);}
else if(callbacks[i] instanceof PasswordCallback) {
PasswordCallback pc = (PasswordCallback)callbacks[i];
pc.setPassword(password.toCharArray());
System.out.println("PASSWORD:: "+password);}
else { throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
}
}
}
}
Then we will create a logincontext with a name of the loginmodule which we gave in the .conf file and with the callbakhandler class instance, with the credentials set in the handler class. Now login using the login context. Next proceed with the normal lookup and access the method.For the specified username and password , we have the role admin defined in the roles.properties and users.properties file have this username and password. So the client will get the result from the bean. The logout from the logincontext and try to access the bean method again , you will be thrown with a EJBAcessException.
I hope this article is useful.