Sunday, 10 February 2008

Spring Framework; pooling target sources

Spring Framework gives you ability to create beans for any POJOs and use them in IoC as your application needs.
Spring Framework supports more than one scope for its bean:
  1. Singleton: Scopes a single bean definition to a single object instance per Spring IoC container.

  2. Prototype: Scopes a single bean definition to any number of object instances.

And other three scopes if you work with Spring Framework version 2.5.
You must take care while dealing with some of these scopes, specially the prototype/request ones that creates new bean instance for every request. That can harm your web application server as your requests increase and consumes your server memory and resources.

Resource pooling is the best handling for this situation. It is general concept of having a pool or resources with fixed size (can be configurable) and have your resource handler pool out one resource from this pool for every resource request and returns it again in the pool after the request finished. If your pool is empty, then the requested entity will queue until one resource is available for its request in the pool.

By that way you can tune your resources usage based on their types. Some of resource types have more requests to them; you can increase their pool size. Others have less usage; you can decrease their pool size to the proper value.

Spring Framework gives you this ability of resource pooling while creating your POJOs beans. Spring pooling can be applied to any POJO. Spring provides out-of-the-box support for Jakarta Commons Pool, which provides a fairly efficient pooling implementation. You'll need the commons-pool Jar on your application's classpath to use this feature.

Sample configuration is shown below:

... properties omitted
</bean>

<bean id="poolTargetSource"
class="org.springframework.aop.target.CommonsPoolTargetSource">
<property name="targetBeanName" value="businessObjectTarget"/>
<property name="maxSize" value="25"/>
</bean>

<bean id="businessObject"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource" ref="poolTargetSource"/>
</bean>


Note that the target object--"businessObjectTarget" in the example--must be a prototype. This allows the PoolingTargetSource implementation to create new instances of the target to grow the pool as necessary.

Reference:
Spring Framework Documentation, Chapter 7, section 7.10.2

Wednesday, 6 February 2008

Restlet framework integration with Spring

While I am working in my project (Android/weNear), we decided to expose our server side functionality using web-service interface such that we can easily build web-based consol for weNear beside the Android handset client one.

After our eSpace sessions for the REST architecture, I see that REST architecture is more lighter and flexible in use than SOAP one for web-services (check small comparison Giving SOAP a REST). Just to remember, REST architecture is based on http protocol and commands only. No extra data or handling needed to call your REST web-service (as in SOAP protocol). Just use http connection and enjoy dealing with any data formats you want as supported by the REST server (XML, JSON, etc).

Restlet framework is one from a lot of REST web-service frameworks. It is great and lightweight REST framework for java. The problem is that it lakes of documentation.

The good point is that it has extension for integration with Spring framework (the one we are using in weNear server). Next I will elaborate how you can integrate RESTlet framework with Spring framework.

  1. Add the following libs to your application classpath:
    org.restlet-<VERSION>.jar
    org.restlet.ext.spring-<VERSION>.jar
    com.noelios.restlet-<VERSION>.jar
    com.noelios.restlet.ext.servlet-<VERSION>.jar

  2. You need to create two basic java classes (I attached them to the post)

    1. final class RestApplication extends org.restlet.Application
      This is the main starting point for RESTlet framework to be loaded with your web-application. You will override the method “createRoot()” that starts to load your spring context and initialize your REST manager bean with basic router (refer to RESTlet documentation).

    2. final class RestManager
      This classes will contain your resource mapping. Every map entry will contain resource URL as key and Restlet implementation class as value for this key. This Retlet implementation class is the one who will handle the call to this resource URL.


  3. You need to add some configuration in your web.xml for your RESTlet framework to start.

    • Your restlet application context parameter :

      <context-param>
      <param-name>org.restlet.application</param-name>
      <param-value>
      <RESTLET_APPLICATION_CLASS_PATH>
      </param-value>
      </context-param>

    • Your Restlet servlet and its mapping :

      <servlet>
      <servlet-name>RestServlet</servlet-name>
      <servlet-class>
      com.noelios.restlet.ext.servlet.ServerServlet
      </servlet-class>
      </servlet>

      <servlet-mapping>
      <servlet-name>RestServlet</servlet-name>
      <url-pattern>/rest/*</url-pattern>
      </servlet-mapping>


  4. The final point is creating your Restlet manager bean that will hold your resource/restlet mapping. In your applicationContext.xml you will create the next bean:

    <bean id="manager" class="<RESTLET_MANAGER_CLASS_PATH>">
    <property name="resourceMappings">
    <bean class="java.util.HashMap">
    <constructor-arg>
    <map>
    <entry key="<RESOURCE_URL>">
    <ref local="<RESTLET_BEAN>"/>
    </entry>
    </map>
    </constructor-arg>
    </bean>
    </property>
    </bean>
    Notice that
    <RESOURCE_URL> is your resource URL that will be requested by the client to invoke <RESTLET_BEAN> class, e.g. “/user/1”
    <RESTLET_BEAN> is spring bean for the class that extends org.restlet.Restlet and will handle the call for the given RESOURCE_URL.

Now, you have Restlet framework integrated with Spring. All you need to do for adding more rest resources is creating bean for your restlet implementation and create entry in your RestletManager bean that maps your resource URL to your Restlet implementation bean.

Attachments:
RESTlet and Spring

Tuesday, 5 February 2008

Locate Me Using GSM Information and Yahoo Services

Some mobile devices contains GPS (Global Positioning System) hardware using it you can acquire your location on earth in the form of longitude and latitude.

Additionally, most GSM cell towers have fixed locations (some of the towers are mobile ones) and have its own longitude and latitude location defined on it. So, depending on GSM network for acquiring handset location (longitude/latitude) is obvious solution instead of GPS hardware.

Yahoo provides two services API using them you can get GPS location (latitude and longitude) and use it in any maps service (google, yahoo, etc) from GSM network information.

1) ZoneTag. The cell location web service allows you to access the ZoneTag Location Services and get the best known location (address) for a given GSM cell tower ID.
All you need to do is requesting this service API by sending your GSM information in its URL as parameters. Response will be location address for the given cell information. ZoneTag learns about real world cell locations from users.
The required GSM information for the service API is; cell id, mcc (Mobile Country Code), mnc (Mobile Network Code) and lac (Location Area Code).

2) Geocoding API. The Geocoding Web Service allows you to find the specific latitude and longitude for an address. All you need is sending your address (country, city, state, street and zip code) in the request URL and then you will get XML response contains the GPS information.

Example:
Given the following cell information: cell id=48627, lac=201, mnc=15, mcc=234, request URL is:
http://zonetag.research.yahooapis.com/services/rest/V1/cellLookup.php?ap...
Response XML will be :


<rsp stat="ok">
<Location>
<Country cell="current" source="user">United Kingdom
</Location>
<Location>
<Country cell="current" source="generic">United Kingdom
<City cell="current" source="generic">Hammersmith
</Location>
<Location>
<Country cell="current" source="GPS">United Kingdom
<City cell="current" source="GPS">London
<Zipcode cell="current" source="GPS">W6 8
</Location>
</rsp>

From the given address you can request Geocoding service API to get GPS location:
http://local.yahooapis.com/MapsService/V1/geocode?appid=YahooDemo&countr...
Response XML will be:

<ResultSet xsi:schemaLocation="urn:yahoo:maps http://api.local.yahoo.com/MapsService/V1/GeocodeResponse.xsd">
<Result precision="zip">
<Latitude>51.506325
<Longitude>-0.127144
<Address/>
<City>London
<State>United Kingdom
<Zip/>
<Country>GB
</Result>
</ResultSet>
http://local.yahooapis.com/MapsService/V1/geocode?appid=YahooDemo&countr...

I found that the returned GPS location is (long=29.889870, lat=31.192240). I think it is the marked point by Yahoo for Alexandria in Yahoo maps.
For anyone interested to test this services in Egypt, Vodafone mcc=602 and mnc=02 as example.