Saturday, October 24, 2009

Page Ranking Implemented in Java

Within the past few years, Google has become the far most utilized search engine worldwide. This success is because of the high quality results in comparison to other search engines. This high quality result is because of the Page Ranking feature that google is using.


Each document is assigned with a ranking while it is being indexed. when you search for a keyword, pages with higher page rank are displayed on top.


The page rank algorithm is found by Google founders Lawrence Page and Sergey Brin.


In this article we first go through the algorithm and then implement it in Java.


The article is available from http://www.javadev.org/files/Ranking.pdf

The source code is available from http://www.javadev.org/files/ranking.zip

Tuesday, November 25, 2008

How to Develop JAAS Security on JBoss AS ?

A few days ago I was proposed to develop an airline ticketing system using JavaEE platform. For this system I decided to use EJB3 and JSF running on JBoss application server.
As long as security is a vital concern in such applications, I decided to use JAAS (Java Authentication and Authorization Service) to implement authentication and authorization.
After searching for the required configurations to implement a JAAS based security on JBoss, I couldn’t find anything useful, even in the JBoss documents! (JavaEE developers are not very unfamiliar with this).
It took a while for me to find all the required settings and run my project under JAAS technology on the JBoss application server, so I decided to share my knowledge and document it, hope to be useful for somebody.

The printable version of this article is available at:
http://www.javadev.org/files/JAAS-JBoss.pdf

Tuesday, July 31, 2007

Hibernate Performance Tuning

Performance is one the most important issues in applications. Application Performance depends on a variety of parameters which must be mentioned carefully to prevent bottle nakes in the application.
Performance-tuning your application should first include the most obvious settings,such as the best fetching strategies and use of proxies.

This is an article about how to tune our hibernate settings to gain the best performance and prevent vulnerable problems.

You can view a printable version(PDF) of the article at:
http://www.javadev.org/files/Hibernate%20Performance%20Tuning.pdf

Saturday, July 28, 2007

How to REST?! - RESTing Without JAX-WS

During our example we used JAX-WS API to communicate with the web service. Although this is the best way, but there are other ways as well.One of these ways is using HttpURLConnection:

1. The client uses the URL.openConnection() method to create an instance of HttpURLConnection representing a connection to the Web service’s URL.

2. HttpURLConnection.connect() sends the HTTP GET request that has been configured using the Web service’s URL.

3. The Web service processes the request and writes the appropriate XML document to the HTTP response stream.

4. The HttpURLConnection’s InputStream is used to read the HTTP response’s XML document.

Exmaple of a non-JAX-WS Client

URL url = new URL(""); // the web service URL
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.connect();InputStream in = con.getInputStream();

byte[] b = new byte[1024]; // 1K buffer

int result = in.read(b);
while (result != -1) {
System.out.write(b,0,result);
result =in.read(b);
}
in.close();
con.disconnect();

Note that the in this case the web service does not return the XML message directly in the StreamSource format but it writes the StreamSource result to the response OutputStream.

How to REST?! - XML Transformation

In the previous sections, we sent and received XML messages to/from web service.In this communication the client and web service received the XML message in the formats that they were expecting. These formats were defined in the XML schema files. But sometimes we need to adapt ourselves with different formats of information. For example some services may use email instead of username to identify their customers. So we must provide a way for different XML formats to be acceptable by our RESTful web service.Here we need to transform the incoming xml message to an acceptable format. We can use XSLT for this reason.XSLT makes sense as the transformation tool of choice within SOA integration frameworks, because it is a universally accepted standard and the transformation engines that interpret XSLT to perform data transformations keep getting better and faster.

As an example assume that the authentication message came from the client is in the following format:
<?xml version="1.0"?>
<auth xmlns="http://www.javadev.org/mail" xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance" xsi:schemaLocation="http://www.javadev.org/mail
http://javadev.org/rest/auth/mail.xsd">
<email>foo</email>
<password>foo</password>
</auth>

As you can see <username> is replaced with <email> , for the authentication service there is no difference between username and email, because both of them are unique. But the main point of the consideration is that currently, when we are parsing the incoming xml document, we expect the <username> element but we are facing an <email> element.To transform the incoming XML document to the expected format we write an XSLT and use it in the JAXP API.The XSLT document is as bellow:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:mail=
http://www.javadev.org/mail>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="mail:auth">
<auth xmlns="http://www.javadev.org/auth" xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xsi:schemaLocation="http://www.javadev.org/auth
http://javadev.org/rest/auth/auth.xsd">
<xsl:apply-templates/>
</auth>
</xsl:template>
<xsl:template match="mail:email">
<xsl:apply-templates select="./mail:email"/>
</xsl:template>
<xsl:template match="mail:password">
<xsl:apply-templates select="./mail:password"/>
</xsl:template>
<xsl:template match="mail:email">
<username>
<xsl:value-of select="."/>
</username>
</xsl:template>
<xsl:template match="mail:password">
<password>
<xsl:value-of select="."/>
</password>
</xsl:template>
</xsl:stylesheet>


This XSLT transformer reads the source XML file and converts it to the destination XML format.After creating the XSLT file, we need to apply it to the incoming xml file before parsing it.

InputStream xslt = this.getClass().getResourceAsStream("mail_to_user.xslt");
try {
TransformerFactory.newInstance().newTransformer(new StreamSource(xslt))
.transform(src, res);
} catch (Exception e) {
e.printStackTrace();
}

The only difference is that we pass the XSLT document as an StreamSource object to the Transformer to use it before converting the incoming StreamSource object to the equivalent OutputStream.So we can convert any format of incoming messages to our desired format before extracting information.

How to REST?! - Authentication Client

We are using a simple java application as our client.The client is using the JAX-WS API to communicate with the web service.It first generates an XML message which contains information need to be authenticated.

info += "<?xml version=\"1.0\"?>";
info += "<auth xmlns=\"http://www.javadev.org/auth\" xmlns:xsi=\"
http://www.w3.org/2001/XMLSchema-instance\
"+
xsi:schemaLocation=\"
http://www.javadev.org/auth
\"+
http://www.javadev.org/rest/auth/auth.xsd >";
info += "<username>foo</username>";
info += "<password>foo</password>";
info += "</auth>";

As you can see, we are generating an XML message with the Username and Password which must be authenticated in the web service.

In the client, Service is used to create an instance of javax.xml.ws.Dispatch, which enables XML message-level interaction with the target Web service. Dispatch is the low-level JAX-WS 2.0 API that requires clients to construct messages by working directly with the XML, rather than with a higher- level binding such as JAXB 2.0 schema derived program elements. For many REST proponents, however, this is exactly the programming paradigm they want—direct access to the XML request and response messages.
The client uses the Service.addPort() method to create a port within the Service instance that can be used to access the RESTful web service.
Next, the Service.createDispatch() method is invoked to create an instance of Dispatch—a Dispatch instance that enables you to work with XML request/response messages as instances of javax.xml.transform.Source.
The Dispatch.invoke() method then packages the XML request—per the JAX-WS 2.0 HTTP Binding—and sends it to the RESTful service. The invoke() method waits for the response before returning.The service processes the HTTP GET and sends an HTTP response that includes the XML.The invoke() method returns the response XML message as an instance of Source.

// Create an InputStream with the authentication info
ByteArrayInputStream bais = new ByteArrayInputStream(info.getBytes());

QName svcQName = new QName("http://rest", "svc");
QName portQName = new QName("http://rest", "port");
Service svc = Service.create(svcQName);
svc.addPort(portQName, HTTPBinding.HTTP_BINDING, url);
Dispatch dis =
svc.createDispatch(portQName, Source.class, Service.Mode.PAYLOAD);
StreamSource result = (StreamSource) dis.invoke(new StreamSource(bais));

Notice that you have to create QName instances for the Service instance and the “port” that corresponds to the RESTful Web service. In a SOAP scenario, these qualified names would correspond to the WSDL definitions for the wsdl:service and wsdl:port. Since there is no WSDL when invoking a RESTful service, these QName instances are gratuitous. They are required by the API, but not used to invoke the RESTful service.
The URL used in the addPort method is the URL of your web service for example we used http://localhost:8080/auth/authService which:
localhost is the name/IP of your running application server.
8080 is the port port of your application server.
auth is the context path of your web service which in our example is defined.
authService is the value of serviceName attribute of the @WebServiceProvider annotation in the web service.As you can see the authentication result is returned as an Source object. So we should parse it and extract the message as we did in the web service.

How to REST?! - Authentication Web Service

Our web service class starts with three annotations:
@ServiceMode(value = Service.Mode.PAYLOAD)
@WebServiceProvider(serviceName = "authService")
@BindingType(value = HTTPBinding.HTTP_BINDING)


In the SOAP web services @ServiceMode is set to MESSAGE which indicates that you want to work with the entire SOAP envelop, but in the RESTful web services it is set to PAYLOAD to indicate that we just need the SOAP body of the message.

@WebServiceProvider annotation is required for deploying a RESTful web service and its serviceName attribute is used to deploy our web service with a desired name. This name is used in the client application to access the web service.

The @BindingType annotation (javax.xml.ws.BindingType) is also defined by the JAX-WS 2.0 specification and is used to specify the binding that should be employed when publishing an endpoint.
The property value indicates the actual binding. In this case, you can see that the value is specified as follow:
value=HTTPBinding.HTTP_BINDING
This indicates that the XML/HTTP binding should be used, rather than the default SOAP 1.1/HTTP. This is how REST endpoints are specified in JAX-WS 2.0—by setting the @BindingType. If one were to leave the @BindingType annotation off this example, the Java EE 5 container would deploy it as a service that expects to receive a SOAP envelope, rather than straight XML over HTTP.

The web service class should implement the javax.xml.ws.Provider.
This interface enables you to create a web service that works directly with the XML message as an instance of javax.xml.transform.Source.

The web service class receives the XML message as an instance of javax.xml.transform.Source. So the first step toward authentication is to convert this object to an XML document, then we can parse the XML document to extract our required information.
The transformation is done in the parse(Source src) method which get an Source object as input parameter and returns the parsed XML document.

ByteArrayOutputStream baos = new ByteArrayOutputStream();
StreamResult res = new StreamResult(baos);
try {
TransformerFactory.newInstance().newTransformer()
.transform(src, res);
} catch (Exception e) {
e.printStackTrace();
}

This code transforms the Source object to an OutputStream object. Then this OutputStream object is converted to an InputStream object and passed to the DomParser to be converted to the parsed XML document (I used the Apache Xerces-J 2 for XML parsing).
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());

try {
InputSource is = new InputSource(bais);

// Create a DOM Parser
DOMParser parser = new DOMParser();

// Parsing the incoming file
parser.parse(is);

// Obtain the document
doc = parser.getDocument();

} catch (IOException ioe) {

ioe.printStackTrace();

} catch (SAXException saxe) {

saxe.printStackTrace();
}


Once we have the parsed XML document, we can extract the required information needed for the authentication.

NodeList root = doc.getElementsByTagName("auth");
Element rootEL = (Element) root.item(0);
String username = getStringVal(rootEL, "username");
String password = getStringVal(rootEL, "password");

Now we have the passed in Username and Password which needs to be authenticated.
After authenticating Username and Password we must return the appropriate message. This message will be and XML message but as an StreamSource object (as the message passed into the web service).

if (auth(username, password)) {
String message = "";

// Write the authentication result to an XML message
message += "";
message += "<result>";
message += "<message>authenticated</message>";
message += "</result>";

// Create an InputStream with the authentication info
ByteArrayInputStream bais = new ByteArrayInputStream(message.getBytes());
return new StreamSource(bais);
} else {
String message = "";

// Write the authentication result to an XML message
message += "";
message += "<result>";
message += "<message>failed</message>";
message += "</result>";

// Create an InputStream with the authentication info
ByteArrayInputStream bais = new ByteArrayInputStream(message.getBytes());
return new StreamSource(bais);
}

The client will use the same transformation we did here to parse this XML message and find out the authentication result.

Deploying the Web Service
By using @WebServiceProvider annotation, deploying our web service is as easy as putting the .war file in the deploy directory of the application server. The application server detects it as a web service and deploys it automatically.