Thursday, June 7, 2012

Mongodb Paging Item Reader


Here, is a sample..

package org.zero.index.batch.read;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.item.database.AbstractPagingItemReader;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.util.Assert;

public class MongodbPagingItemReader<T> extends AbstractPagingItemReader<T> {
  private MongoOperations mongoOperations;
  private QueryContext<T> queryContext;
  private boolean strict;

  private static final Logger LOG = LoggerFactory
      .getLogger(MongodbPagingItemReader.class);

  @Override
  protected void doReadPage() {
    if (results == null) {
      results = new CopyOnWriteArrayList<T>();
    } else {
      results.clear();
    }
    final List<T> result = mongoOperations.find(
        queryContext.getQuery().limit(getPageSize()).skip(getPage()),
        queryContext.getEntityClassName(), queryContext.getCollectionName());
    if ((getPage() == 0) && result.isEmpty()) {
      if (strict) {
        throw new IllegalStateException(
            "No matching documents found (reader is in 'strict' mode)");
      }
      LOG.warn("No matching documents found");
      return;
    }
    results.addAll(result);
  }

  @Override
  protected void doJumpToPage(final int itemIndex) {
    // do nothing
  }

  /**
   * @param mongoOperations
   *          the mongoOperations to set
   */
  public void setMongoOperations(final MongoOperations mongoOperations) {
    this.mongoOperations = mongoOperations;
  }

  /**
   * @param queryContext
   *          the queryContext to set
   */
  public void setQueryContext(final QueryContext<T> queryContext) {
    this.queryContext = queryContext;
  }

  /**
   * @param strict
   */
  public void setStrict(final boolean strict) {
    this.strict = strict;
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    super.afterPropertiesSet();
    Assert.notNull(mongoOperations, "mongoOperations is null");
    Assert.notNull(queryContext, "queryContext is null");
  }
}

Monday, April 2, 2012

Hausla Buland

जैसे कंधे पे इक दोस्त का हाथ हो 
जैसे  लफ्ज़ो पे दिल की हर एक बात हो
जैसे आखोँ से चिंता की चिलमन हटे
जैसे मिट जाए हर ग़म कुछ इतना घटे
जैसे राहोँ में सपनो की कलियाँ खिले
जैसे दिल में उजालो के दरिया बहे
जैसे तन-मन कोई गीत गाने लगे
जैसे सोई हुई हिम्मत अंगडाई ले
जैसे जीना ख़ुशी की कहानी लगे
जैसे खुल जाए रस्ते अब तक थे बंद

हौसला हो बुलंद
हौसला हो बुलंद
हौसला हो बुलंद
हौसला जैसे आस्मां से हो बुलंद
हौसला हो बुलंद
हौसला हो बुलंद
हौसला हो बुलंद
हौसला जैसे आस्मां से हो बुलंद
हौसला हो बुलंद
हौसला हो बुलंद
हौसला हो बुलंद

हो बुलंद.....

कवि -- श्री जावेद अख्तर 



You like to grab your own copy here

Sunday, April 1, 2012

Spring Managed DI for Quartz Jobs With Dependencies

Problem Statement:

Quartz scheduler (v 2.1.3) triggers a job which has its own dependencies which needs to be managed using Spring (3.1.1.RELEASE+)

Solution:

The Job

public class HttpDealsDownloadJob implements Job {
// NO DEPENDENCIES HERE
  @Override
  public void execute(final JobExecutionContext context)
      throws JobExecutionException {
    final JobDataMap jdm = context.getJobDetail().getJobDataMap();
// EXTRACT YOUR DEPENDENCY FROM JOB DATA MAP
    final HttpFileDownloader delegate = (HttpFileDownloader) jdm
        .get("job.delegate");
    delegate.apply(context.getJobDetail().getJobDataMap().getWrappedMap());
  }

}

Spring Context

<bean id="mySchedulerFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="configLocation" value="file:quartz.properties" />
<property name="jobFactory" ref="springBeanJobFactory" />
<property name="triggers">
<list>
<ref bean="myCronTriggerFactoryBean" />
</list>
</property>
</bean>
<bean id="springBeanJobFactory"
class="org.springframework.scheduling.quartz.SpringBeanJobFactory" />
<bean id="myCronTriggerFactoryBean"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="cronExpression" value="${my.cron.expression}" />
<property name="jobDetail" ref="myJobDetailFactoryBean" />
</bean>
<bean id="myJobDetailFactoryBean"
class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobDataAsMap">
<map>
<entry key="source.url" value="${my.deals.url}" />
<entry key="job.delegate" value-ref="httpFileDownloader" />
</map>
</property>
<property name="jobClass"
value="org.zero.gb.acequia.scheduler.HttpDealsDownloadJob" />
<!-- INJECT APPLICATION CONTEXT -->
<property name="applicationContextJobDataKey" value="appicationContext" />
</bean>
<!-- THIS IS THE CLASS WHICH ACTUALLY DOES THE WORK -->
<bean id="httpFileDownloader" class="org.zero.acequia.integration.http.HttpFileDownloader">
             <!-- your dependencies here -->
     </bean>

Wannabe Architect 101

I feel fortunate to be a professional Software Engineer as no other career option would have given me the luxury to contribute in myriad different ways and power to change them for good. But, with power comes responsibility and to conduct one self in graceful manners in adverse situations. Today, I'm going to share some of my first hand experiences working in technical leadership role;
  • you do not have authority - get this straight into your head, as it sets the foundation for our discussion.
  • you have to sell/evangelize your ideas - as you are not a manager you cannot (should not) try to force your ideas/opinions. However, you can evangelize the choice framework/ technology/ language options by providing a working proof of concept (be ready to trash it, if it doesn't works though!). Make note to address people's concerns like difficulty to comprehend the "new" thing or may be to help them appreciate the concerns you have about the existing thing. Remember, any change forces people to come out of their comfort areas. The change you are trying to accommodate must not be intimidating for PEOPLE
  • assert without being blunt - although i have no right to preach this but people who have worked with me be known that I'm very working aggressively on ways to put things in improved context.   Although, I still favor shared objectivity as it helps me focus on task at hand.
  • invest in your relationship - "If someone is strongly disliked, it’s almost irrelevant whether or not she is competent; people won’t want to work with her anyway. By contrast, if someone is liked, his colleagues will seek out every little bit of competence he has to offer."
  • people have short impression and long term memory - use it in your favor - it is never too late to start afresh lead by example, people will copy "as it works" and chances are some of them will eventually appreciate the concepts. You want your team to write unit tests, show them how you have written for some of the components in the current project and then tell them how it helped being productive, rather than the other way around. If you go gaga about DIs and AOPs and FPs  or any other alphabet soup and tell the benefits chances are people won't practice it however if you just do it and others in the team start identifying the improved productivity the smarter ones will copy. Be ready to help them without being preachy or The Guru.. you have created your community of users!!

Top it all be stateless! like one of those web-services which you might design yourself. Do not carry the emotional backlog you created with working with people you cannot stand or plain incompetent. Start afresh, it helps to travel lite.

Sunday, September 4, 2011

Learning Resources for n00bs: Coding & Problem Solving

Although a quick search would fetch you tonnes of learning resources. Here, are the recommended for absolute beginners like me, into the realms of problem solving;

The best part about both these online resources is that they are sorted in the increasing order of difficulties which is key to learning incrementally at one's own pace. 

Also, codechef.com runs a monthly code competition which looks really interesting.

Do share your feedback/suggestions.

Saturday, September 3, 2011

Cosmic Link


Now that free lunch is over the onus now lies on us (read Software Engineers) to gainfully utilize the computing resources available to us. It is now therefore imperative for us to develop and hone our fundamental skill sets and may be stop(OK, pause)  running after the next 'big' thing (read technology/framework).

For those of you who have not yet hit the 'dead-end' be warned. It would help you to develop your skills on;

  • Problem Solving because no matter what 'flashy' thing you know there will always be some thing new hitting you every now and then. Learning to solve problems not only makes you more employable but also makes you more confident and inspirational for others (think thought leadership)
  • The choice of Data Structures and Algorithm you employ in your applications may be all that you need to optimize their non-functional needs and nothing is more satisfying than making your application perform better.
  • While argumentatively speaking I do agree that frameworks are making us dumb but that is largely because we are always in a hurry to just complete the task without really understanding the framework internals. In not so distant past, I found it difficult to solve a bug which creeped into my code because of my incorrect understanding of java.lang.String#split(String regex) method. The problem was later identified and was mixed in matter of few seconds by merely reading (after everything else failed, and I decided to raise a bug!! ) the associated javadocs and saved myself from the embarrassment. 
  • Writing concurrent code is both error prone and difficult and till recently I didn't really face a performance issue, may be the free lunch was still available to me... but no more. Work on it.

The above piece is not only relevant to java developers for us all. Think about it knowing your DB internals(say join algorithm) will help you optimize your queries or may be if you write shell scripts knowing the correct order of filtering might put your script on steroids...

Please do not get offended by reading the above, the tone might sound prescriptive.. but is really a result of my reflections on my recent mis-adventures and is put to public notice lest you repeat them yourself.

Sunday, June 26, 2011

Just dance

Yes, I'm watching the screening rounds on Star Plus.. the candidates are from as diverse a background as one might only imagine.. their energy and sheer enthuthiasm is infectious. I don't have words to express my feelings, however, that's not the point of this piece... but the fact that it is important to be an artist in your profession be it dancing or software engineering.. practice your craft

Monday, March 28, 2011

Leveling the Threat Matrix

Almost serendipitously, I discovered some simple sentences which when put together does makes sense to me...
  • Initiative and Responsibility: Very few of us take initiative, while this is an important trait of young, energetic people and should be highly appreciated. More often than not the same people lack responsibility or step back when an avalanche of things start coming one's way.
  • Action and Control: Now is better than never, although never is almost always better than "now". One needs to be in control of things... evolutionary, step-by-step improvements keeps one in control and can help steer the direction of future coarse of actions in a more informed manner.
Simply put one of the reasons we come under stress for all the wrong reasons after all the right intentions is the eerie feeling og the lack of control... I told you, some times the universe conspires to help me discover the effective habits... it was only this time I thought it could be useful to you too...

Friday, January 14, 2011

Few observations on my blog readers

... ho ho ho the big brother is watching you!! well not really, but yes as a trained statistician and a practicing software engineer I love to observe "things", a collection of things... and try to create an empirical model of their behavior pattern.. a blue print.. and study them to put them into my knowledge stack that may or may not be used immediately.


My findings;
  • It adds to your credibility if you provide references in your write ups at proper places. It only proves that the write has done his/her home work.
  • However, merely providing the hyper-link.. like to learn more read here will not necessary be followed by your reader because
    • that may break his train of thought
    • you might risk to loose your audience
The way I see it is that it would serve the reader as well as the writer by providing the central idea around the hyper-link for the more inquisitive reader to follow without loosing his focus.

My two cents. Get leaner!!

Sunday, January 9, 2011

Innovation - Generating Ideas: The monkey's view

Not again ..not another hyperbolic session on INNOVATION but these days almost every one in my social circle at least hints about innovation. Not so surprisingly it is a constant endeavour of our species to be introspective and improve continuously, so much so that historians have even classified our cultural heritage in terms of the innovations that have distinguished them viz: the stone age, iron age.. Similarly, the role of innovation at enterprises is pretty much tied with their sustainability and even existence.
 
The dictionary defines the term in a rather half baked manner (blasphemous?!!) while it does appreciates creating the "new thing" it safely discounts the efforts gone into continuous improvement of existing "thing". Sadly the incremental or the continuous improvements made with the existing "things" meets the same fate and goes unnoticed at our enterprises.  

Also, we tend to focus more on the fruits of innovation, that is, the "product" itself and do tend to take the process part for granted and much worse "a necessary evil" at least in my software industry. It is only timely that much work of art is already published (think continuous delivery) but they are yet to make to the mainstream howsoever "agile" the enterprises may like to call themselves.

I understand by now must have already read my mind and must be wondering if I'm really going to add any value... some of the ways I think can make a good start can be summarized as under;
  • Become a producer of content.. in my limited scope of understanding I feel most of us do not write or express ourselves or take stand for the fear of being judged. Let's change that and start putting our thoughts in black and white here on blogs, comment on others blogs.. connect. Not many of our experienced leaders write. Writing is such a powerful medium that one can reach out to whole bunch of people at one time which is boon for our time-pressed industry leaders.
  • In one of my earlier post I discussed the challenges I faced to share knowledge. Some of the ways sharing knowledge can help is to come out of our stove pipe modes and satiate our higher needs of self actualization. There is this nice article which covers the subject in greater depth and also provides the relevant background knowledge. You will do good to read it for yourself.
  • Management determines the organizational climate. It can send a clear message through rewards, mentor employees to participate in open source software products, participation at technical conferences, taking engineers to customer meetings, sales team to participate in test cycles...
  • The above mentioned set of activities create and encourage the cross-pollination of ideas which can create magical results.. you never know when that bulb glows in someone's head, the EUREKA moment!!
  • Support innovators as per Seth Godin if you don't support and nurture them it simply puts spanner into the innovation engine even before it gained any considerable momentum.
 Innovation is critical to our growth and generating ideas is critical to innovation itself while thinkers must understand their responsibilities have just begun. Here I made an attempt to showcase some of the problems which should be addressed to create value added services to serve our society.

Tuesday, November 30, 2010

Parallel Search

Problem:
Write a Java class that allows parallel search in an array of integer. It provides the following static method:
public static int parallelSearch(int[ ] a , int numThreads)
This method creates as many threads as specified by numThreads, divides the array a into that many parts, and gives each thread a part of the array to search for sequentially. If any thread finds x, then it returns an index i such that A [ i ] = x. Otherwise, the method returns -1.
Solution:


package org.zero.concurrent.chap01;

import java.util.Arrays;

public class ParallelSearch {
    private static int index = -1;

    public static int parallelSearch(int search, int[] in, int numThreads) {
        // partition
        int partitionSize = in.length / numThreads;
        Thread[] threads = new Thread[numThreads];
        int end = 0;
        int begin = 0;
        // search
        for (int i = 0; i < numThreads; i++) {
            end = begin + partitionSize;
            if (i == numThreads - 1 || end > in.length) {
                end = in.length;
            }
            Search target = new Search(begin, end, in, search);
            System.out.println(target);
            threads[i] = new Thread(target);
            threads[i].start();
            System.out.println(threads[i].getName());
            begin = end;
        }
        return index;
    }

    public static void main(String[] args) {
        int[] a = new int[100];
        for (int i = 0; i < a.length; i++) {
            a[i] = (int) (Math.random() * 10);
        }
        int parallelSearch = parallelSearch(2, a, 7);
        if (-1 == parallelSearch) {
            System.out.println("not found");
        } else {
            System.out.println("found at: " + parallelSearch);
        }
    }

    private static class Search implements Runnable {
        int begin;
        int end;
        int[] a;
        int x;

        public Search(int begin, int end, int[] a, int x) {
            super();
            if (end < begin) {
                throw new IllegalStateException();
            }
            this.begin = begin;
            this.end = end;
            this.a = a;
            this.x = x;
        }

        @Override
        public void run() {
            for (int i = begin; i < end; i++) {
                if (x == a[i]) {
                    index = i;
                    System.out.println(i + " "
                            + Thread.currentThread().getName());
                    // break;
                }
            }
        }

        @Override
        public String toString() {
            return "Search [a=" + Arrays.toString(a) + ", length=" + a.length
                    + ", begin=" + begin + ", end=" + end + ", x=" + x + "]";
        }

    }
}
P.S: Any suggestion to improve the code is welcome.

Saturday, November 27, 2010

Product Versioning: Embedding packaging information

Almost serendipitously, I discovered the Java Package class today. One must wonder how possibly this is going to make a difference (aka increase their geek quotient or coolness factor). Well the beauty lies in the details.

Problem Statement: You commit your code to the cvs and after going through the complete lifecycle experience your code finally sees the light of the day, much to your chagrin that the users discovered some bug, even after all those unit testing and that pragmatic ranting ;) But, then you are the rock star developer who had already discovered the problem and fixed it :D but how do you know if user is not using some older version of your package???


Solution: You can embed the information in the manifest file at build time which could be read by exploding the jar, simple!! NO, most of your users wouldn't (shouldn't) know it.It would be really nice if you can print this star-studded information at the beginning of the code execution. You can make this as the first line of your log file or may be a separate file which could be used for bug reporting, options are open.. How do you do it?

Step 1: Create an annotation.

package org.zero;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.PACKAGE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyVersionAnnotation {

    String version();

    String revision();

    String date();

    String user();

    String url();
}

Step 2: Generate a class package-info.java
@MyVersionAnnotation(date = "2010-11-26", revision = "11", url = "http://onjava.com/pub/a/onjava/2004/04/21/declarative.html?page=3", user = "nitin", version = "123")
package org.zero;

Step 3: Create a class to access this information;



/**
 * This class finds the package info for mypackage and the MyVersionAnnotation
 * information.
 */
public class PackageDemo {
    private static Package myPackage;
    private static MyVersionAnnotation version;

    static {
        myPackage = MyVersionAnnotation.class.getPackage();
        version = myPackage.getAnnotation(MyVersionAnnotation.class);
    }

    /**
     * Get the meta-data for the mypackage package.
     *
     * @return
     */
    static Package getPackage() {
        return myPackage;
    }

    /**
     * Get the mypackage version.
     *
     * @return the mypackage version string, eg. "0.6.3-dev"
     */
    public static String getVersion() {
        return version != null ? version.version() : "Unknown";
    }

    /**
     * Get the subversion revision number for the root directory
     *
     * @return the revision number, eg. "451451"
     */
    public static String getRevision() {
        return version != null ? version.revision() : "Unknown";
    }

    /**
     * The date that mypackage was compiled.
     *
     * @return the compilation date in unix date format
     */
    public static String getDate() {
        return version != null ? version.date() : "Unknown";
    }

    /**
     * The user that compiled mypackage.
     *
     * @return the username of the user
     */
    public static String getUser() {
        return version != null ? version.user() : "Unknown";
    }

    /**
     * Get the subversion URL for the root mypackage directory.
     */
    public static String getUrl() {
        return version != null ? version.url() : "Unknown";
    }

    /**
     * Returns the buildVersion which includes version, revision, user and date.
     */
    public static String getBuildVersion() {
        return PackageDemo.getVersion() + " from " + PackageDemo.getRevision()
                + " by " + PackageDemo.getUser() + " on "
                + PackageDemo.getDate();
    }

    public static void main(String[] args) {
        System.out.println("mypackage " + getVersion());
        System.out.println("Subversion " + getUrl() + " -r " + getRevision());
        System.out.println("Compiled by " + getUser() + " on " + getDate());
    }
}
PS: Source code courtesy org.apache.hadoop.util.VersionInfo

Friday, September 24, 2010

Race etiquettes

Read some them here,
http://runnersforlife.com/page/race-etiquette