Archive for December, 2011

Some mvn tips

Posted: December 22, 2011 in maven

Hi all, as you may know TurmericSOA has a multi-module project structure, as example take a look at Rate Limiter module under turmeric-security project:

turmeric-security/ratelimiter
|
|---RateLimiterService
|---RateLimiterProvider
|---RateLimiterCounterProvider
|---RateLimiterServiceConsumer
|---RateLimiterServiceImpl
|---RateLimiterErrorLibrary
|---RateLimiterCounterMapProviderImpl
|---RateLimiterCounterCassandraProviderImpl
|---RateLimiterProviderImpl
|readme.txt
|pom.xml

a simple mvn clean package process takes about 9 minutes…no so bad, it could be worst, for example if you build the entire security project….please be patient 🙂

For those kind of projects here I recall you some useful tips building with maven…

  • Use the maven reactor plugin: in short terms it allows to resume your build process where last fails has placed or simlply from where you specify:

In my case I pasted the RateLimiter module structure based on its dependencies, not alphabetically… Now assume you’ve got a fail at RateLimiterCounterMapProviderImpl module, if you run a simple “mvn clean install” you are running a complete rate limiter project build, instead of that try: –resume-from  or -rf

mvn clean package –rf RateLimiterCounterMapProviderImpl

That command just runs RateLimiterCounterMapProviderImpl, RateLimiterCounterCassandraProviderImpl and RateLimiterProviderImpl.

__________________________________________________

Also you can specify a particular module or project to run with the use of –projects or -pl

mvn clean package –pl RateLimiterCounterMapProviderImpl

That build just the indicated project. You can specifiy one or more projects separated by comma.

__________________________________________________

Another option could be, build my project and its dependencies: –also-make or -am

mvn clean package –pl RateLimiterCounterMapProviderImpl -am

That builds RateLimiterService, RateLimiterCounterProvider and RateLimiterCounterMapProviderImpl
__________________________________________________

Or build my project and its dependants: –also-make-dependents or -amd

mvn clean package -pl RateLimiterCounterMapProviderImpl -amd

That builds RateLimiterCounterMapProviderImpl and RateLimiterProviderImpl

__________________________________________________

  • An easy one, working in offline mode: –offline or -o
mvn clean package -o RateLimiterCounterMapProviderImpl

That will not try to download the artifacts from remote repos, you’re an isolated developer 🙂

__________________________________________________

Sometimes I use my own Nexus repo (see Continuous Integration in Local post), so I need to change some
configurations in my maven setting files, to be honest I use two files: –settings or -s

mvn -s ~/.m2/settingsnexus.xml clean package

__________________________________________________
If you are familiar with maven I’m pretty sure you’ve hit your head on the table more than once and you finally decided to manually delete the your .m2 repo. The –update-snapshots or -U option could helps in those annoying times

mvn -U clean package

This will force to download the artifacts despite mvn does not consider them obsoletes.
__________________________________________________

  • Dependencies and versions
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.8.5</version>
<scope>test</scope>
</dependency>

That is a common dependency section in a pom.xml file. But you can specify the version in different ways:
1.8.5 => “Soft” requirement on 1.8.5 as a recommendation
[1.8.5] => “Hard” requirement on 1.8.5
[1.8.1,1.8.5] => Any between 1.8.1 and 1.8.5
[1.8.1,1.8.5) => Any between 1.8.1 and 1.8.4.99….
[1.8.5,) => Any above or equals to 1.8.5
(,1.8.1],[1.8.5,)=> Any below or equals to 1.8.1 OR any above or equals 1.8.5.
__________________________________________________

  • What-if fails

By default maven works with –fail-fast or -ff option. That is the multi-module build stops as soon a module fails.

mvn clean package       -> -ff option by default

…the output:

[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] turmeric-ratelimiter-parent ....................... SUCCESS [2.177s]
[INFO] Rate Limiter :: Rate Limiter Service .............. SUCCESS [17.947s]
[INFO] Rate Limiter :: Rate Limiter Provider :: Interface  FAILURE [0.361s]
[INFO] Rate Limiter :: Rate Limiter CounterMap Provider :: Interface  SKIPPED
[INFO] Rate Limiter :: Error Library ..................... SKIPPED
[INFO] Rate Limiter :: Rate Limiter Service :: Consumer .. SKIPPED
[INFO] Rate Limiter :: Rate Limiter Service :: Impl ...... SKIPPED
[INFO] Rate Limiter :: Rate Limiter CounterMap Provider :: Impl  SKIPPED
[INFO] Rate Limiter :: Rate Limiter CounterCassandra Provider :: Impl  SKIPPED
[INFO] Rate Limiter :: Rate Limiter Provider :: Impl ..... SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------

__________________________________________________________
You can use the –fail-at-end or -fae option to continue the build despite some modules has failed.

mvn -fae clean package -Dmaven.test.skip=true   -> just to avoid my tests during the build process

…the output:

[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] turmeric-ratelimiter-parent ....................... SUCCESS [1.959s]
[INFO] Rate Limiter :: Rate Limiter Service .............. SUCCESS [29.078s]
[INFO] Rate Limiter :: Rate Limiter Provider :: Interface  FAILURE [0.309s]
[INFO] Rate Limiter :: Rate Limiter CounterMap Provider :: Interface  SUCCESS [13.085s]
[INFO] Rate Limiter :: Error Library ..................... SUCCESS [6.886s]
[INFO] Rate Limiter :: Rate Limiter Service :: Consumer .. SUCCESS [5.550s]
[INFO] Rate Limiter :: Rate Limiter Service :: Impl ...... SKIPPED
[INFO] Rate Limiter :: Rate Limiter CounterMap Provider :: Impl  SUCCESS [7.367s]
[INFO] Rate Limiter :: Rate Limiter CounterCassandra Provider :: Impl  SUCCESS [8.224s]
[INFO] Rate Limiter :: Rate Limiter Provider :: Impl ..... SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------

__________________________________________________________
…and finally the preferred tool for dishonest developers 🙂
–fail-never or -fn

mvn -fn clean package -Dmaven.test.skip=true   -> just to avoid my tests during the build process

…the output:

[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] turmeric-ratelimiter-parent ....................... SUCCESS [1.959s]
[INFO] Rate Limiter :: Rate Limiter Service .............. SUCCESS [29.078s]
[INFO] Rate Limiter :: Rate Limiter Provider :: Interface  FAILURE [0.309s]
[INFO] Rate Limiter :: Rate Limiter CounterMap Provider :: Interface  SUCCESS [13.085s]
[INFO] Rate Limiter :: Error Library ..................... SUCCESS [6.886s]
[INFO] Rate Limiter :: Rate Limiter Service :: Consumer .. SUCCESS [5.550s]
[INFO] Rate Limiter :: Rate Limiter Service :: Impl ...... SKIPPED
[INFO] Rate Limiter :: Rate Limiter CounterMap Provider :: Impl  SUCCESS [7.367s]
[INFO] Rate Limiter :: Rate Limiter CounterCassandra Provider :: Impl  SUCCESS [8.224s]
[INFO] Rate Limiter :: Rate Limiter Provider :: Impl ..... SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO]  + Ignoring failures
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

draw your own conclusions based on the outputs and your needs….

Now enjoy your new free time with the use of these tips….

RESTful requests with TurmericSOA

Posted: December 12, 2011 in REST, SOA, Turmeric

This time I’m gonna write about how to play in Turmeric with RESTful requests.

First of all we need a deployed service, any, in our Web Server, in my case Jetty 7, indeed, I use jetty-turmeric , this is a customized Jetty for running our Turmeric engine and deploying services in one or two simple steps…basically for simple but comprehensive tests.

The service I use is a sample EchoService, already included under the Turmeric Runtime module. So, under our WebServer/webapp folder we have a folder called example-echoservice. example-echoservice


|----META-INF
|----WEB-INF
        |-----classes
        |-----lib
               |-----ExampleEchoServiceV1-1.0.1.0-SNAPSHOT.jar
               |-----ExampleEchoServiceV1Impl-1.0.1.0-SNAPSHOT.jar
        |-----web.xml
|----index.html

Our web.xml deployment file should look like this:


<web-app
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd"
metadata-complete="false"
version="2.5">
<display-name>Spfservlet Test</display-name>
<servlet>
<description>ExampleEchoServiceV1</description>
<display-name>ExampleEchoServiceV1</display-name>
<servlet-name>ExampleEchoServiceV1</servlet-name>
<servlet-class>org.ebayopensource.turmeric.runtime.spf.pipeline.SPFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<init-param>
<param-name>SOA_SERVICE_NAME</param-name>
<param-value>ExampleEchoServiceV1</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ExampleEchoServiceV1</servlet-name>
<url-pattern>/ExampleEchoServiceV1</url-pattern>
</servlet-mapping>
</web-app>

The included Echo sample is ready to be deployed, so after copy/paste this project under our jetty-turmeric, the service could be achieved through: http://localhost:8080/example-echoservice/ExampleEchoServiceV1?echo&echoText=Hello and the response should be similar as:

<echoResponse>
<ack>Success</ack>
<output>HelloGuest</output>
</echoResponse>

Now, let’s review the main config file in this scenario, that is the ServiceConfig.xml under the ExampleEchoServiceV1Impl.jar By default it comes with a very simple an basic turmeric configuration:


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<service-config xmlns="http://www.ebayopensource.org/turmeric/common/config">
<service-impl-class-name>org.ebayopensource.turmeric.example.v1.services.echoservice.impl.ExampleEchoServiceV1Impl</service-impl-class-name>
<service-interface-class-name>org.ebayopensource.turmeric.example.v1.services.echoservice.ExampleEchoServiceV1</service-interface-class-name>
<service-instance-config>
<provider-options>
<header-mapping-options>
<option name="X-TURMERIC-OPERATION-NAME">queryop</option>
<option name="X-TURMERIC-RESPONSE-DATA-FORMAT">query[format]</option>
</header-mapping-options>
</provider-options>

<protocol-processor version="1.1" name="SOAP11">
<indicator>
<transport-header name="X-TURMERIC-MESSAGE-PROTOCOL">SOAP11</transport-header>
</indicator>
<class-name>org.ebayopensource.turmeric.runtime.spf.impl.protocolprocessor.soap.ServerSOAPProtocolProcessor</class-name>
</protocol-processor>
<protocol-processor version="1.2" name="SOAP12">
<indicator>
<transport-header name="X-TURMERIC-MESSAGE-PROTOCOL">SOAP12</transport-header>
</indicator>
<class-name>org.ebayopensource.turmeric.runtime.spf.impl.protocolprocessor.soap.ServerSOAPProtocolProcessor</class-name>
</protocol-processor>
</service-instance-config>
</service-config>
<pre>

We have three main tag blocks here, lets forget the protocol-processor for now, they are SOAP related protocols, not usefull in our REST scenario…

Then, according this Turmeric wiki page, there some required parameters when we make a service call, but if we recall our endpoint (http://localhost:8080/example-echoservice/ExampleEchoServiceV1?echo&echoText=Hello) seems we forgot the X-TURMERIC-OPERATION-NAME. That is the purpose of queryop value in header-mapping-options, it automatically retrieves the first request parameter as the operation name, so we could replace an original and longer URL request http://localhost:8080/example-echoservice/ExampleEchoServiceV1?X-TURMERIC-OPERATION-NAME=echo&echoText=Hello by http://localhost:8080/example-echoservice/ExampleEchoServiceV1?echo&echoText=Hello.

In addition, one of our followers wants to achieve the service through this endpoint instead: http://localhost:8080/example-echoservice/ExampleEchoServiceV1/echo/Hello                <— pay attention, there is no question mark to specify the parameters

So, there are two simple steps you want to perform, first of all you need to update your deployment descriptor file for a propper intrepretation of your new URL, that is adding a wild card in your Servlet Mapping:

<servlet-mapping>
<servlet-name>ExampleEchoServiceV1</servlet-name>
<url-pattern>/ExampleEchoServiceV1/*</url-pattern>
</servlet-mapping>

Next step is to update the ServiceConfig.xml in order to read the latest word in our URL word as the echoText parameter, this tag section must be added following the header-mapping-options


<request-params-mapping>
<operation name="echo">
<option name="echoText">path[3]</option>
</operation>
</request-params-mapping>

That will read the 3rd expression in our URL

Please surf here for more info about URL mapping under REST request.

Also you can specify a pipeline process into the ServiceConfig.xml to provide Authentication, Rate Limiter capabilities or maybe custom handler to improve your service governance, but this  deserves another post 🙂