Friday, October 24, 2014

Swagger integation with Rest.

Swagger this name is getting bigger and bolder day by day.

Integrating swagger with camel cxfrs is two step process:


1) Creating Json file (based on Swagger annotations)
2) Using Swagger UI for exposing your rest services.

1) Creating Json file (based on Swagger annotations) 

------------------------------------------------------
A) pom.xml    -- describing only swagger related stuff

  <!-- swagger dependecny ->
       <dependency>
            <groupId>com.wordnik</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.3.7</version>
        </dependency>
 <!-- Cross Origin dependency -->  <!--This is required so that you can make call to your application from swagger ui -->
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-security-cors</artifactId>
            <version>3.0.0</version>
        </dependency>



<!--Swagger plugin--> <-- Change the setting as per your requirment -->
<!--This pluing is used to generate Json file -->

            <plugin>
                <groupId>com.github.kongchen</groupId>
                <artifactId>swagger-maven-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <apiSources>
                        <apiSource>
                            <!--Required parameters BEGIN-->
                            <locations>com.rest.resources;com.rest.model;</locations>
                            <apiVersion>1.0</apiVersion>
                            <basePath>rest/v1</basePath>
                            <!--Required parameters END-->

                            <!--Optional parameters BEGIN-->
                            <!---General parameters BEGIN-->
                            <apiInfo>
                                <title>REST API Docs</title>
                                <description>REST api documentation</description>
                                <termsOfServiceUrl>http://www.github.com/kongchen/swagger-maven-plugin</termsOfServiceUrl>
                                <contact></contact>
                                <license>Apache 2.0</license>
                                <licenseUrl>http://www.apache.org/licenses/LICENSE-2.0.html</licenseUrl>
                            </apiInfo>
                            <!--<overridingModels>/swagger-overriding-models.json</overridingModels>-->
                            <swaggerInternalFilter>com.wordnik.swagger.config.DefaultSpecFilter</swaggerInternalFilter>
                            <!--General parameters END-->

                            <!---Document generation parameters BEGIN-->
                            <!--                    <outputTemplate>
                                                     strapdown.html.mustache
                                                 </outputTemplate>
                                                 <mustacheFileRoot>${basedir}/src/main/resources/</mustacheFileRoot>
                                                     <outputPath>${basedir}/generated/document.html</outputPath>
                            -->                        
                            <!---Document generation parameters END-->

                            <!---Swagger JSON parameters BEGIN-->
                            <swaggerDirectory>target/classes/swagger</swaggerDirectory>
                            <swaggerUIDocBasePath>http://localhost:8083/swagger</swaggerUIDocBasePath>
                            <useOutputFlatStructure>false</useOutputFlatStructure>
                            <!---Swagger JSON parameters END-->
                            <!--Optional parameters END-->
                        </apiSource>
                    </apiSources>
                </configuration>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>generate</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

---------------------------------------------------------

B) Anotating your class with Swagger annotations.

Check the below link for detail. 

annotate-your-resources
annotate-your-methods
annotate-your-models

C) Creating your Camel Rest end point Server:

cxf-server.xml
--------------------
<cxf:rsServer id="camelRESTServer" address="${api.base.path}">
        <cxf:serviceBeans>
            <ref bean="camelResource"/> <!-- some resouce ->
        </cxf:serviceBeans>
        <cxf:providers>
            <ref bean="jacksonJaxbJsonProvider"/>
            <ref bean="cros"/>  <!-- this is important else it will cause issue when calling your rest end point from swagger ui -->
        </cxf:providers>
    </cxf:rsServer>

<bean id="jacksonJaxbJsonProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider"/>
<bean id="cros" class="org.apache.cxf.rs.security.cors.CrossOriginResourceSharingFilter"/>
-------------------

Same configuration in Java:

CxfServletConfiguration.java
--------------------
 @Bean(name = "camelRESTServer")
    JAXRSServerFactoryBean camelRESTServer() {
        SpringJAXRSServerFactoryBean sf = new SpringJAXRSServerFactoryBean();
        sf.setServiceBean(Arrays.asList(camelResources)); //some resource
        sf.setAddress("api.base.path");
        JacksonJaxbJsonProvider jacksonJaxbJsonProvider= new JacksonJaxbJsonProvider();
        jacksonJaxbJsonProvider.setMapper(new ObjectMapper());
        sf.setProviders(Arrays.asList(jacksonJaxbJsonProvider,
                new CrossOriginResourceSharingFilter())); /*this is important else it will cause issue when calling your rest end point from swagger ui */

        return sf;
    }
--------------------


D) Define your Camel route to cater the rest request.

see : cxfrs

F) Creating a servlet which serve the JSON file created by the pluging which we have described above. This servlet will be called from Swagger UI.

------configuration ----
   @Bean
    public ServletRegistrationBean swaggerServletRegistrationBean() {
         Swagger swaggerServlet = new Swagger();
         ServletRegistrationBean swaggerServletRegistrationBean = new ServletRegistrationBean(swaggerServlet, "/swagger/*");
         return swaggerServletRegistrationBean;
    }
---------------------
Swagger.java

public class Swagger extends HttpServlet {
   
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
   
    response.setContentType("application/json");
     
    //allow Swagger on other servers to read JSON     
    response.addHeader("Access-Control-Allow-Origin", "*");
   
    //get end of the address browser asks for
    String jsonFile=request.getRequestURI();
   
    //lets us point at just /swagger instead of service.json, which is prettier
    if (request.getRequestURI().equals("/swagger"))
    {
        jsonFile = jsonFile +"/service.json";
    }
   
    //gets file location of generated JSON
    URL resource = getClass().getResource(jsonFile);
   
    //populates a String with JSON
    String fileContent = FileUtils.getFileContent(resource.toString().substring(6));     
   
    //prints String to page served
    PrintWriter out = response.getWriter();
    out.print(fileContent);

     
  }
}
-------------------------------------------------


That is end of step 1. Build your application and Run it.

2) Using Swagger UI for exposing your rest services.

Download the  Swagger UI from swagger-ui
To launch the Swagger UI you can copy the dist folder and put it into tomcat webapps folder.
Rename dist to swagger.
Run your tomcat. and launch http://localhost:<port>/swagger
Above step will launch swagger ui, now give the url which will be served by your application Swagger servlet.

At this point your should be able to see your exposed REST services.






Wednesday, October 22, 2014

Simple Java Scheduler using Quartz.

Quartz is one of the technology with can be used for scheduling jobs i.e to run or execute something are certain specific time.
Many technology use Quartz implictly for job scheduling, so the chances are very high that you have written a job scheduling program and implicitly used Quartz.
Here I am going to explain how to use Quartz with Java.
Quartz scheduling has two part :
1) The job to be performed
2) The schedule when it wll be performed.
Creaing the Job:
Creating a job which you want to execute. For this you have to create a class which implements
Job interface from Quartz
.
    public class SchedulerJob implements Job {
    // you have to override this method and write the code which act as Job you want to excute .
    @Override    
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        // my job is to print hello world message
        // you job may be to sftp some files to  server or to generate some reports etc.
        System.out.println("Hello World");
    }
}
Part two, creating a Schedule for this job.
  public class SchedulerJobImpl {
  public void scheduleJob(){

  JobKey jobKey = new JobKey("RouteSchedulerJob", "RouteSchedulerGroup");

  // Creating Job and link to our Job class      JobDetail job = JobBuilder.newJob(SchedulerJob.class).withIdentity(jobKey).build();
 // Creating cron schedule time with trigger
 Trigger trigger = newTrigger().withIdentity("RouteScheduler")
            .withIdentity("RouteSchedulerTrigger", "RouteSchedulerGroup")
            .withSchedule(cronSchedule("0 0/10 * ? * *")).build(); // adding the cron shedule

    // Creating scheduler factory and scheduler
    SchedulerFactory sf = new StdSchedulerFactory();
    Scheduler sched;
    try {
        sched = sf.getScheduler();
        sched.scheduleJob(job, trigger); // adding job and trigger to schedule
        sched.start(); // starting the schedule
    } catch (SchedulerException e) {
        log.error("Error occurred while starting the Quartz Cron Job for Scheduling the Job.");
        e.printStackTrace();
        log.error("Exiting .......");
        System.exit(1);
    }

}
}
Now final class to start and test
    Applicaiton.java

    public class Application {
    public static void main (String [] args){
           SchedulerJobImpl schedulerJobImpl = new SchedulerJobImpl();              
           schedulerJobImp.scheduleJob(); // this is do the job . That is it ,now your job is scheduled   
                                                                //to run at time defined.
         }
}

Tuesday, October 21, 2014

Transaction in Camel

Transaction => it’s all or nothing

Transaction represent sequence of step to be performed and either all the steps will be completed successfully or none.  Transactions conform to ACID  properties


By default, the JMS consumer uses auto-acknowledge mode, which means the client acknowledges the message when it’s received (i.e consumed by consumer), and the message is dequeued from the JMS broker.

But JMS consumer can use transacted acknowledge mode. which means the client acknowledges the message when it’s is able to succefully consume it, and only then the message is dequeued from the JMS broker.


In transacted acknowledge mode when a message has been consumed from the queue and fed into the Camel application, Camel issues a begin signal to the JmsTransactionManager. Depending on whether the Camel route completes consuming the message with success or failure  the JmsTransactionManager will ensure the JMS broker commits or rolls back(i.e dequeue or keep the message).


When you specify <transacted/> in a route, Camel uses transactions for that particular
route. Under the hood, Camel looks up the Spring transaction manager and leverages
it. This is the convention over configuration kicking in.

NOTE : When using transacted() in the Java DSL, you must add it right
after from() to ensure that the route is properly configured to use transactions.
This isn’t enforced in the DSL because the DSL is loosely defined to
make it easy to maintain and develop Camel. There are a few tradeoffs such
as this.


Example of correct transacted route:
   from("jms:test:queue")
         .transacted()
          //other operation
         .end();

Incorrect transacted route:
     from("jms:test:queue")
          .routeId("testRoute") // this will casue issue  as transacted() should be added right after from()
         .transacted()
          //other operation
         .end();





Refer : Chapter 9 "Using Transaction" in "Camel in Action"
Refer : transactional-client.html

Wednesday, October 15, 2014

Mokito Useful tips



Mocking a class:  (This will mock the whole class and all the methods in it.)

 A aMock = Mockito.mock(A.class);
 
Mockito.when(aMock.method()).thenReturn(5l);
 
 
To mock-a-single-method-in-java use Mockito Spy


A a = new A();  ( where  Class A  has two method - method1() and method2() ) 
A aSpy = Mockito.spy(a);
Mockito.when(aSpy.method1()).thenReturn(5l);
call to  aSpy.method2()  will be actual method call to method2 without any mock effect.
Refer : how-to-mock-a-single-method-in-java
 
 NOTE: When you are mocking a class make sure you use/inject the mock version only.
 
Mockito provide simple way to pass parameter to a mocked class method:
e.g : aSpy.method(anyInt(), anyString()
this is mock for -> a.method(int i, String stg) 
MOCKITO LIMITATION: 
Mockito has a few limitations worth remembering. They are generally technical restrictions, but Mockito authors believe using hacks to work around them would encourage people to write poorly testable code. Mockito cannot:
  • mock final classes
  • mock enums
  • mock final methods
  • mock static methods
  • mock private methods
  • mock hashCode() and equals()
 
 
 

Tuesday, October 14, 2014

Camel Quartz Explained

There are two ways in which you can use Quartz in Camel.

1) When you want to execute a job at certain specific time of day or month or year etc.

2) When you want to consume from some endpoint (jms, file, sftp etc) at specific time of day. months yeart etc.

For First :

from("quartz2://myGroup/myTimerName?trigger.repeatInterval=2&trigger.repeatCount=1")
.routeId("myRoute")
// add here all operation which you want to do.
.end();

Note: Here myGroup and myTimerName are name of the group to which this quartz schedule belong and name is what  you want this quartz schedule to be called.

Refer : Camel quartz2

For second :

CronScheduledRoutePolicy startPolicy = new CronScheduledRoutePolicy();
startPolicy.setRouteStartTime("*/3 * * * * ?");
                 
from("file://inbox?preMove=inprogress&move=.done")
    .routeId("testRoute").routePolicy(startPolicy).noAutoStartup()
  // add here all the operation you want to do.
    .to("mock:success");


Refer : Camel cronscheduledroutepolicy

Thursday, September 25, 2014

Maven tips 2 : Comman maven commands and their usage



Using a Custom POM or Custom Settings File
-f pom-conf.xml 

In this -f option is used to select specific pom.xml file if you have many pom file. 
If you dont use -f option then defaul value of pom.xml will be used to build .

Running in Offline Mode
 In case you dont have internet connection and dont want maven to try connecting to internet.
 -o --offline

Skipping Test 

-Dmaven.test.skip=true to skip the

Deploying the build on production or some artifactory

maven deploy

Other common useful commands:
 
clean install  -- clean the target directory and generate the output files.

install -- simply generate the files in the target directory. Does not clean the target directry only override the file if it part of the output.



Refer  maven options

Wednesday, September 24, 2014

Spring commanly used annotation and their usage.

@Configuration

Refer :stackoverflow.com and theserverside.com

@Configuration is the heart of the Java-based configuration mechanism that was introduced in Spring 3. It provides an alternative to XML-based configuration.
So the 2 following snippets are identical:
<beans ...>
    <context:component-scan base-package="my.base.package"/>
    ... other configuration ...
</beans>
and:
@Configuration
@ComponentScan(basePackages = "my.base.package")
public class RootConfig {
    ... other configuration ...
}
In both cases Spring will scan in my.base.package and below for classes annotated with @Component or one of the other annotations that are meta-annotated with @Component such as @Service.


@Import 

Refer : Spring @Import
Indicates one or more @Configuration classes to import.
Provides functionality equivalent to the <import/> element in Spring XML. Only supported for classes annotated with @Configuration or declaring at least one @Bean method, as well as ImportSelector and ImportBeanDefinitionRegistrarimplementations.
@Bean definitions declared in imported @Configuration classes should be accessed by using @Autowired injection. Either the bean itself can be autowired, or the configuration class instance declaring the bean can be autowired. The latter approach allows for explicit, IDE-friendly navigation between @Configuration class methods.


@Bean

Refer : Spring @Bean
Indicates that a method produces a bean to be managed by the Spring container.
 


@Value

Refer :  Spring @Value but you can fine better explanation on other place..

This annotation is basically used to get the value defined  properties file on the basis of key value pair.

In order for @Value annotations to work PropertySourcesPlaceholderConfigurer should be registered. It is done automatically when using <context:property-placeholder> in XML, but should be registered as a static @Bean when using @Configuration.


@Value can be used in three different ways:  

1)
@Value ("${test.at.value}")
String atValue;
2)
@Value ("${test.at.value}") 
public void testATValue(String atValue){
                  println("value of atValue : " atValue);
 }
 3)
public  void testAtValue(@Value ("${test.at.value}")  String atValue) {
                  println("value of atValue : " atValue);
 }

@Profile

Refer : Spring @Profile 

This annotation is used basically used to activate or run a piece of code when certain profile is active.
Can act as filter for conditional loading or importing of stuff.


Condition loading of bean example : depending upon what is the current active profile corresponding bean will be loded

@Bean
@Profile("TestUser")
public User loadTestUser()  {
               return new TestUser();
}

@Bean
@Profile("NormalUser")
public User loadNormalUser()  {
               return new NormalUser();
}

A profile is a named logical grouping that may be activated programmatically via ConfigurableEnvironment.setActiveProfiles(java.lang.String...) or declaratively through setting the spring.profiles.active property, usually through JVM system properties, as an environment variable, or for web applications as a Servlet context parameter in web.xml.


Hope this helps.