Setting up Google OAuth2 with Java

For all of you who are trying to figure out how to integrate with Google’s single sign-on functionality (like I’ve done for my own startup at tripgather.com), this article I published on ocpsoft.org might be for you. I’ve taken the liberty of condensing all of the actual logic required to perform OAuth Google login, and provided it as a class and a JSP. In order to follow along better, I suggest cloning the example GitHub repository, and deploying to the application to your server of choice.

please find this article here

openstreetmap json geolocation using java

A viable free alternative to google’s geolocation api is openstreetmap’s nominatim functionality. The service recommends restricting the frequency of requests to 1 per second, so if nothing else, this is a viable failover alternative to google’s geolocation api.

The code below may be used to query openstreetmap’s nominatim database for latitude/longitude information. It uses the jackson library for json parsing.

If you are using maven, add:

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-jaxrs</artifactId>
    <version>1.9.4</version>
</dependency>

to your pom.xml file’s dependencies to satisfy the import statements in the class below.

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.codehaus.jackson.map.ObjectMapper;

public class OpenStreetMapGeoCodeJacksonParser {

    private static final String LATITUDE = "lat";
    private static final String LONGITUDE = "lon";

    public LatLng parse(final InputStream jsonStream) {
        LatLng coordinate = null;
        final ObjectMapper mapper = new ObjectMapper();
        try {
            final List<Object> dealData = mapper.readValue(jsonStream, List.class);
            if (dealData != null && dealData.size() == 1) {
                final Map< String, Object > locationMap = (Map< String, Object >) dealData.get(0);
                if (locationMap != null && locationMap.containsKey(LATITUDE) && locationMap.containsKey(LONGITUDE)) {
                    final double lat = Double.parseDouble(locationMap.get(LATITUDE).toString());
                    final double lng = Double.parseDouble(locationMap.get(LONGITUDE).toString());
                    coordinate = new LatLng(lat, lng);
                 }
             } else {
                 Logger.getLogger(OpenStreetMapGeoCodeJacksonParser.class.getName()).log(Level.SEVERE, "NO RESULTS", "NO RESULTS");
             }
         } catch (Exception ex) {
             Logger.getLogger(OpenStreetMapGeoCodeJacksonParser.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
         }
    return coordinate;
    }

    public LatLng parse(String rawAddress) {
        InputStream is = null;
        LatLng coords = null;

        if (rawAddress != null && rawAddress.length() > 0 ) {
            try {
                String address = URLEncoder.encode(rawAddress, "utf-8");
                String geocodeURL = "http://nominatim.openstreetmap.org/search?format=json&limit=1&polygon=0&addressdetails=0&email=contact@EMAIL.ME&countrycodes=us&q=";
                //query google geocode api
                String formattedUrl = geocodeURL + address;
                URL geocodeUrl = new URL(formattedUrl);
                is = geocodeUrl.openStream();
                coords = parse(is);
            } catch (IOException ex) {
                Logger.getLogger(OpenStreetMapGeoCodeJacksonParser.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                try {
                    is.close();
                } catch (IOException ex) {
                    Logger.getLogger(OpenStreetMapGeoCodeJacksonParser.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        return coords;
    }

    public static void main(final String[] args) {
        final String rawAddress = "Los Angeles, CA";
        System.out.println(new OpenStreetMapGeoCodeJacksonParser().parse(rawAddress));
    }
}

Please make sure to substitute a valid email address into the geocodeURL’s email GET parameter.

Finally, the LatLng.java class holds the latitude-longitude information.

import java.io.Serializable;

/**
 *
 * @author mdanter
 */
public class LatLng implements Serializable{

    private static final long serialVersionUID = 16549987563L;

    private double lat;
    private double lng;

    public LatLng(final double lat, final double lng) {
        this.lat = lat;
        this.lng = lng;
    }

    public double getLat() {
        return lat;
    }

    public void setLat(final double lat) {
        this.lat = lat;
    }

    public double getLng() {
        return lng;
    }

    public void setLng(final double lng) {
        this.lng = lng;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final LatLng other = (LatLng) obj;
        if (Double.doubleToLongBits(this.lat) != Double.doubleToLongBits(other.lat)) {
            return false;
        }
        if (Double.doubleToLongBits(this.lng) != Double.doubleToLongBits(other.lng)) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 53 * hash + (int) (Double.doubleToLongBits(this.lat) ^ (Double.doubleToLongBits(this.lat) >>> 32));
        hash = 53 * hash + (int) (Double.doubleToLongBits(this.lng) ^ (Double.doubleToLongBits(this.lng) >>> 32));
        return hash;
    }

}

Oracle Glassfish 3.x issue in EJB 3.1 with @Asynchronous methods

Recently, as a pet project, I’ve been working on an application that uses the @Asynchronous method level annotation in a Singleton EJB as per the EJB 3.1 specification. The application consisted of a call to a restful URI, to capture an xml representation of an object, converting this into a POJO (Serializable) then sending it to a MessageQueue as an ObjectMessage. Each datum was independent, and there was a high volume of data to process, I decided to implement the new method level @Asynchronous annotation, the fire-and-forget way. I also built an MDB as a consumer of the Queue, that is however irrelevant to the issue.

Of course this EJB 3.1 application had to be load tested for large volumes of sample data. I’ve made up a test sample that was representative of the projected volume of data, and set the @Asynchronous method’s Thread.sleep() for 5 seconds. The reason for this was to estimate a worst case scenario for the Request-Response lifecycle. The app was deployed into Oracle Glassfish 3.1.1 with tuned EJB and MDB pools, and a somewhat starved 768MB max heap.

While watching the log output, I noticed that the @Asynchronous threads were spawned by bunches of 16. I tried to further tune EJB Thread pools inside of Glassfish — with no luck.

I found the issue on the Glassfish website after checking out the current stable codebase from their subversion repository. In Oracle Glassfish 3.1.1, according to the EjbAsyncInvocationManager.java class in com.sun.ejb.containers the 16 thread limit is hard-coded.

public EjbAsyncInvocationManager() {
   //TODO get the paramters from ejb-container config
   super(16, 32, 60, TimeUnit.SECONDS, new LinkedBlockingQueue());
   super.setThreadFactory(new EjbAsyncThreadFactory());
}

I’ve checked out the latest stable glassfish (Maven is great, isn’t it?) project, then as a duck tape solution, increased this number to satisfy my application’s needs. As soon as I have time to devote to this issue, I’ll investigate what the best way to fix this would be. I think the least impact to the codebase would be to include the settings for min-max thread-pool size and timeout values in glassfish-ejb-jar.xml somehow nested in the definition for an EJB.

Serving up Glassfish 3.x from port 80/443 via NAT

After a good amount of load testing and tinkering, I’ve found that mod_jk does not play too well with oracle glassfish 3, at least not in the environment/configuration I’m using. After about 30% of requests timing out in a web app which was using JSF 2 (facelets core, tomahawk, and primefaces) / EJB 3.1 / JPA 2 on top of oracle 11g db (tuned caching, native queries, etc…), the culprit turned out to be mod_jk misbehaving. After diagnosing the issue, I’ve decided to leave the httpd< -->mod_jk< -->glassfish setup behind, and KISS.

I’ve turned off httpd, forwarded all requests using NAT in iptables (just tcp, didn’t need udp, but NAT-ing udp as well doesn’t hurt anything) from port 80 to the port I’ve configured the glassfish http listener to listen on (standard is 8080, probably not a bad idea to change this and NAT to that port). Of course, the glassfish http listener’s port had to be configured to accept connections via iptables.

Glassfish uses grizzly as an http server (impl. uses java NIO under the hood), after performance testing and tuning this a bit… viola, timed out requests gone. With a bit more tuning, of JVM params, resource pool sizes, listener threads, application profiling/monitoring, etc., the app server became much snappier at serving requests. ) you may run two separate domains for glassfish with a more imaginative listener configuration.

Sample commands to achieve NAT using iptables for CentOS/RHEL 5.x:

# iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
# iptables -A PREROUTING -t nat -i eth0 -p udp --dport 80 -j REDIRECT --to-port 8080

# service iptables save
# vi /etc/sysconfig/iptables
-A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 8080 -j ACCEPT
# service iptables restart

Similarly, you may replace 80 with 443 and 8080 with 8181 to NAT https.