Wednesday, April 6, 2016

Spring Data Cassandra 1.3.4, Cassandra 3.0, Datastax Driver

I faced lot of issues when trying to integrate Spring Data Cassandra with Cassandra 3.0. By default Spring supports Cassandra 2.x, however, when trying to use the same with Cassandra 3.x results in lot of issues.

You need to perform few changes in Spring classes to get it working with Cassandra 3.x

I have listed down below the changes required, hope this helps others who might be struggling with the same issue

POM.xml


    <dependencies>
             <dependency>
          <groupId>org.springframework.data</groupId>
   <artifactId>spring-data-cassandra</artifactId>
   <version>1.3.4.RELEASE</version>
   <exclusions>
       <exclusion>
           <artifactId>cassandra-driver-core</artifactId>
           <groupId>com.datastax.cassandra</groupId>
       </exclusion>
       <exclusion>
           <artifactId>cassandra-driver-dse</artifactId>
    <groupId>com.datastax.cassandra</groupId>
       </exclusion>
   </exclusions>
  </dependency>

  <dependency>
   <groupId>com.datastax.cassandra</groupId>
   <artifactId>cassandra-driver-core</artifactId>
   <version>3.0.0</version>
  </dependency>
 </dependencies>


Spring Changes
  • package - org.springframework.data.cassandra.convert
  • class - ColumnReader
  • method - public Object get(int i)
Search for line
return row.getMap(i, collectionTypes.get(0).asJavaClass(), collectionTypes.get(1).asJavaClass());
Replace it with
return row.getMap(i, cr.codecFor(collectionTypes.get(0)).getJavaType().getRawType(), cr.codecFor(collectionTypes.get(1)).getJavaType().getRawType());

Search for line
return row.getList(i, collectionTypes.get(0).asJavaClass());
Replace it with
return row.getList(i, cr.codecFor(collectionTypes.get(0)).getJavaType().getRawType());

Search for line
return row.getSet(i, collectionTypes.get(0).asJavaClass());
Replace it with
return row.getSet(i, cr.codecFor(collectionTypes.get(0)).getJavaType().getRawType());
  • package - org.springframework.data.cassandra.mapping
  • class - CassandraSimpleTypeHolder
  • method - static block (no method)
Search for line
Class javaClass = dataType.asJavaClass();
Replace it with
Class javaClass = cr.codecFor(dataType).getJavaType().getRawType();
  • package - org.springframework.data.cassandra.repository.query
  • class - StringBasedCassandraQuery
  • method - private String replacePlaceholders(String input, CassandraParameterAccessor accessor)
Search for line
stringValue = "'" + CqlStringUtils.escapeSingle(value) + "'";
Replace it with
stringValue = "\"" + CqlStringUtils.escapeSingle(value) + "\"";

That's it, after these changes you should be able to use Spring with Cassandra 3.x

Do leave a reply if there are any issues / discrepancies.

Tuesday, December 6, 2011

Retrieving Client IP Address from Request

This post is relevant for Tomcat users who want to retrieve the IP Address of the client from which the request intiated. To be more specific this post is more suitable to users using Tomcat version 6.0.24 or higher.

The method getRemoteAddr() defined in HttpServletRequest class does not return the correct IP Address of the client. The only way to get the correct value of client IP Address was to write code to handle the header "X-FORWARDED-FOR". This header contains the list of all IP addresses (separated by commas) of all the proxies/hops through which the request passes before reaching the server.

However, the catch here is; there can be header spoofing which may result in incorrect value being returned by this Header.

The best option available to strip the messy code handling for "X-FORWARDED-FOR" and get the correct value of client IP Address is using the "RemoteIPValve". This valve can be configured in Tomcat (server.xml) and this results in getRemoteAddr() method returning the correct IP.

To configure the valve, add the below line in server.xml:

(<)Valve className="org.apache.catalina.valves.RemoteIpValve" /(>)

If in case your server is behind a load balancer, then you need to add the IP Address of the load balancer into the internal Proxies list

(<)Valve className="org.apache.catalina.valves.RemoteIpValve" internalProxies = "127\.0\.0\.1"/(>)

Always remember to escape the dot (.) with a slash (\), as it expects a regular expression for internalProxies.

Hope this help others as well!! 

Tuesday, November 2, 2010

The Mystery behind Thread (Un)Safety of Format Classes

Various Formatters like (DateFormat, MessageFormat, SimpleDateFormat, so on and so forth) are very commonly used classes in Java based applications. A very simplistic approach that I have been following for using these classes has been:

class MyFormatter {
  private static SimpleDateFormat sdf = new SimpleDateFormat();
  public static String formatDate(Date inputDate) {
     return sdf.format(inputDate);
  }
}

My reasons for using such an approach was to prevent multiple creation of expensive SimpleDateFormat objects. However, few days back I came across a post that said that the above implementation is thread un-safe. At first I was taken by surprise, and couldn't find a reason for this being un-safe, as the format operation is happening on the local variable (stored on stack).

Then I thought of opening the Java Source Code and understanding the reasons behind this being thread un-safe. The culprit was a class level variable of type Calendar, which is used by the SimpleDateFormat class. Whenever a call to format is invoked, the input date passed is set into this calender object, and then all the operations are performed on this calendar object.

So, if there are 2 threads that are sharing the same SDF object and are running concurrently, the operations will NOT be thread safe and unexpected results can occur.

To resolve this problem, one of the way can be to create a new SDF object everytime in the formatDate method. See below:

class MyFormatter {
  public static String formatDate(Date inputDate) {
    SimpleDateFormat sdf = new SimpleDateFormat();
     return sdf.format(inputDate);
  }
}

This will result into the expensive SDF object to be created on every invocation of the formatDate method, however, this is completely thread safe. The even better answer is to use the thread-safe Joda time libraries, instead.

Hoping this helps others as well!!

Thursday, March 4, 2010

Java & Axis - Calendar & Date problems

Recently, I was working on SOAP based Web-services in Java, where the web-service client was sending Calendar object as a part of the request.

I am writing this post keeping in mind that the reader has basic understanding about web-services, Java Calendar and Date Classes.

Moving further, my client was running on a machine in a different timezone and the actual web-service was deployed on a different server, running in a different timezone. The problem that I faced was, the date entered by the user, and the date that was received at the Web-service end were different.

At the web-service end, the date was 1 day less than the actual date entered by the user. Initially I thought this might be a coding issue, however, I wasn't able to find any coding flaws. Then I serialized the SOAP request to see the XML that was floating between the client and the server.

To my surprise the XML on the client side had the date as 1 day less. On further investigation, I found that, the culprit is actually the way how Java creates Date Object from Calendar Object and vice-a-versa.

We can set the timezone of the Calendar object, and then we think that if we do "getTime()" on that Calendar object, the Date object will also have the same timezone, as was for the Calendar. Unfortunately, this is not the case and this is by design.

Let's get deeper into this by example: Suppose I have a Calendar Object (with no time quotient attached to it i.e. the time is midnight), and I set the timezone of the Calendar object as "GMT". To add another assumption, let the machine be running in "CST" timezone. Now, if you would do Calendar object.getTime(), it will return you a Date Object. This Date object will NOT be in GMT timezone, rather it will be in CST timezone.

This is where the problem lies, and results in the date getting shorter by 1 day. Now, the bigger question, how to solve this problem. Java has got very good utility class by the name SimpleDateFormat. SimpleDateFormat allows you to set the timezone in which you require the Date. So, the better way is to create a SimpleDateFormat object, set the timezone on that object, and then create a Date Object using the Calendar Object.

This solved the problem @ the client side. On server side too, I had to do the same thing when retrieving the Date Object from the Calendar Object and all was done.

Hope this helps others as well.

Do feel free to post your views and suggestions.

Thursday, November 6, 2008

Indian IT Slowdown - Are we a scapegoat!!

Well you mite be wondering about the context in which "we" has been used in the Title. I would like to keep this open across all the layers (a.k.a hierarchy) that follows in an organization. This seems to be a very common theme these days, for everyone, but I feel who matters the most are those who live with this uncertainty.

Just a mark before proceeding : There are as many opinions and perceptions in this world as the number of brains, and mine (opinion meant) is just one of them. So, do come up with your comments and experiences and share if you have felt the heat too.

It is that time of the evening when I swipe out of my office and say "Thanks" to the almighty, as I know, I have my workplace sound and I will get the salary till date. I know I have to follow my daily schedule tomorrow as well, but somewhere underneath my heart, I have this fear that says "Will tomorrow be the same as today?". Every individual who's involved in this *not withstanding* industry has felt this fright some day or the other.

Regrettably, many have faced this bad music and have tasted the flavor of so-called "pink-slips", which have not only affected them alone, but the complete aura around them. The negativity that pours into the mind and the helplessness that hurts the confidence, shakes up the complete soul.

Not only this, I feel more "dejected" when I see the plights of the people around that mortal. Today you may not be affected by it, but "who knows who's next". I would like to quote here " We all are in a rat race, Even if we win the race now; we still will remain a rat."

I agree that companies are facing a global slowdown, due to enormous reasons, and there are times when they (companies) need to keep a check on the expenditures and cost-saving mechanisms; but the argument is "Is Pink-Slip the only solution?" We all believe that "Make hay (employees referred) when the sun shines", but we all should also know that "There comes a time when the sun sets too.."

Companies have a tendency to hire people for projects that they *for-see* and when those projects do not materialize, the axe falls on the people who were hired to make that a success. There is a need for bench strength, but there is a need for stringent actions that can set up the guidelines for maintaining the bench strength. A company hires a professional when it's fully convinced the professional, and the professional joins an organization with the conviction that this might be another step on the ladder of success.

I have heard that many organizations set the benchmarks of profit so "High" without even considering the market scenarios, and once they are not able to meet those (Please Note: the profits are fine but still less), the we community takes the hitting.

As the title says "Are we a scapegoat!!", I think we are, because the penultimate thing for any working individual would be receiving a *Termination of Services* letter, without being at wrong end. There should be certain guidelines set that will help an organization grow professionally as well as ethically and I wish there will come a time when we all will go home with peace in mind.

Tuesday, November 4, 2008

A Big Brand - Is it a requisite for sucess?

The modern world constructs stress too much on brands, be it a social gathering, a job change, a matrimonial invite or a fast food juncture. The list is endless and the culprits are "we". Restricting this discussion to the "IT Sector", lets just decipher how important "Brand Name" is in deciding the fate of an individual.

People whether aware of the "hot & in" IT Industry or not, usually have a pre-conceived notion: "The Bigger the Brand -
  1. More the Opportunities
  2. More the Calibre and Excellence
  3. More the stability..... so on and so forth"
But I have a question for all such people who "lack" subtlety and insight: Was Big always Big? It's a hard truth that every starter may not result into a "successful" big marque, but its also true that every big brand was at once a starter. I think it's the vision and aspirations of individual(s) that can bring a transition from small to big.

One of my personal experience made me feel feeble when I realized the mind-set of so called "Recruitment Teams". My friend was clinched with a pretty small company for over 2 years and then needed a job change. It was that time when the IT job market was flying high, but it wasn't the case with him. He didn't even get the chance of moving to the technical rounds, just because he was turned-down after knowing about his present employer.

The goons of an organization, often scan resumes looking for an imprint of a self-aggrandizing name. The simplistic theory of "choosing the brand and snubbing the worth" is cultivated in many of the organizations these days, just because of the belief that the brand creates your worth. However in the actual sense, it's the other way around.

I would like to support the fact that "now-a-days", a big brand has become as a major requisite for success, but would also like to oppose the thinking itself. I think, it's good to be associated with a big organization; but it should not be a curse if you have a knot tied with a not so known company. Individuals should be gauged on their skill set and not on the brands that they have in their kitty.

Your views are always welcome....