Wednesday, 16 July 2014

Mule Cron Job : Job Name Can Not be Empty Error

Writing cron job is very easy in mule.You might get error like this in mule application start up :
Caused by: org.mule.api.lifecycle.LifecycleException: Failed to start inbound endpoint "endpoint.quartz.test.job"
 at org.mule.endpoint.DefaultInboundEndpoint.start(DefaultInboundEndpoint.java:122)
 at org.mule.construct.AbstractFlowConstruct.startIfStartable(AbstractFlowConstruct.java:317)
 at org.mule.construct.AbstractPipeline.doStart(AbstractPipeline.java:302)
 at org.mule.construct.AbstractFlowConstruct$2.onTransition(AbstractFlowConstruct.java:143)
 at org.mule.construct.AbstractFlowConstruct$2.onTransition(AbstractFlowConstruct.java:139)
 at org.mule.lifecycle.AbstractLifecycleManager.invokePhase(AbstractLifecycleManager.java:141)
 at org.mule.construct.FlowConstructLifecycleManager.fireStartPhase(FlowConstructLifecycleManager.java:95)
 at org.mule.construct.AbstractFlowConstruct.start(AbstractFlowConstruct.java:138)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:601)
 at org.mule.lifecycle.phases.DefaultLifecyclePhase.applyLifecycle(DefaultLifecyclePhase.java:225)
 at org.mule.lifecycle.RegistryLifecycleManager$RegistryLifecycleCallback.onTransition(RegistryLifecycleManager.java:276)
 at org.mule.lifecycle.RegistryLifecycleManager.invokePhase(RegistryLifecycleManager.java:155)
 at org.mule.lifecycle.RegistryLifecycleManager.fireLifecycle(RegistryLifecycleManager.java:126)
 at org.mule.registry.AbstractRegistryBroker.fireLifecycle(AbstractRegistryBroker.java:80)
 at org.mule.registry.MuleRegistryHelper.fireLifecycle(MuleRegistryHelper.java:120)
 at org.mule.lifecycle.MuleContextLifecycleManager$MuleContextLifecycleCallback.onTransition(MuleContextLifecycleManager.java:94)
 at org.mule.lifecycle.MuleContextLifecycleManager$MuleContextLifecycleCallback.onTransition(MuleContextLifecycleManager.java:90)
 at org.mule.lifecycle.MuleContextLifecycleManager.invokePhase(MuleContextLifecycleManager.java:72)
 at org.mule.lifecycle.MuleContextLifecycleManager.fireLifecycle(MuleContextLifecycleManager.java:64)
 at org.mule.DefaultMuleContext.start(DefaultMuleContext.java:250)
 at org.mule.module.launcher.application.DefaultMuleApplication.start(DefaultMuleApplication.java:151)
 ... 4 more
Caused by: org.mule.api.lifecycle.LifecycleException: Failed to start Quartz receiver
 at org.mule.lifecycle.AbstractLifecycleManager.invokePhase(AbstractLifecycleManager.java:156)
 at org.mule.transport.ConnectableLifecycleManager.fireStartPhase(ConnectableLifecycleManager.java:51)
 at org.mule.transport.AbstractTransportMessageHandler.start(AbstractTransportMessageHandler.java:318)
 at org.mule.transport.AbstractConnector.registerListener(AbstractConnector.java:1259)
 at org.mule.endpoint.DefaultInboundEndpoint.start(DefaultInboundEndpoint.java:108)
 ... 27 more
Caused by: org.mule.api.endpoint.EndpointException: Failed to start Quartz receiver
 at org.mule.transport.quartz.QuartzMessageReceiver.doStart(QuartzMessageReceiver.java:195)
 at org.mule.transport.AbstractMessageReceiver.doStartHandler(AbstractMessageReceiver.java:484)
 at org.mule.transport.AbstractTransportMessageHandler$3.onTransition(AbstractTransportMessageHandler.java:322)
 at org.mule.lifecycle.AbstractLifecycleManager.invokePhase(AbstractLifecycleManager.java:141)
 ... 31 more
Caused by: java.lang.IllegalArgumentException: Job name cannot be empty.
 at org.quartz.JobDetail.setName(JobDetail.java:192)
 at org.mule.transport.quartz.QuartzMessageReceiver.doStart(QuartzMessageReceiver.java:95)
 ... 34 more

Here's the xml file :
<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:quartz="http://www.mulesoft.org/schema/mule/quartz" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:spring="http://www.springframework.org/schema/beans" version="CE-3.3.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/quartz http://www.mulesoft.org/schema/mule/quartz/current/mule-quartz.xsd 
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd 
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd ">
    <flow name="crontestFlow1" doc:name="crontestFlow1">
        <quartz:inbound-endpoint jobName="test_job" cronExpression="0 0/100 * * * ?" responseTimeout="10000" doc:name="Price File Report Quartz Job" >
   <quartz:event-generator-job>
   </quartz:event-generator-job>
  </quartz:inbound-endpoint>
        <logger level="INFO" doc:name="Logger"/>
    </flow>
</mule>

Notice that your jobName is not empty . The issue is with underscore . you can not have underscore in jobName property. Just remove underscore from jobName and it will run fine.You can not have white space characters in job name either

Here's the bug.

Post Comments And Suggestions !!

Wednesday, 25 June 2014

Mule File Inbound And Threads

Requirement : File inbound endpoint should pick only limited number of files , once these files are processed then only file inbound should pick other files in the directory .


For this situation , we can use processing strategy as synchronous in our flow . This strategy will pick only one file at a time which is not good .

If we set receiver threading profile on file inbound , it also does not work because file poller keeps acquiring the files after the time period, while some files are still being processed . The other solution is to use fork and join pattern of mule which is explained below .

First we create a custom file component which will give us the list of required number of files .Number of files will be configurable.
package com.javaroots;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.mule.api.MuleEventContext;
import org.mule.api.lifecycle.Callable;


public class FilePollerComponent implements Callable
{

 private String pollDir ;
 
 private int numberOfFiles;
 
 public String getPollDir()
 {
  return pollDir;
 }

 public void setPollDir(String pollDir)
 {
  this.pollDir = pollDir;
 }
 
 

 public int getNumberOfFiles()
 {
  return numberOfFiles;
 }

 public void setNumberOfFiles(int numberOfFiles)
 {
  if(numberOfFiles < 1 )
   throw new RuntimeException("Number of files can not be less than 1");
  this.numberOfFiles = numberOfFiles;
 }

 @Override
 public Object onCall(MuleEventContext eventContext) throws Exception
 {
  File f = new File(pollDir);
  List filesToReturn = new ArrayList(numberOfFiles);
  if(f.isDirectory())
  {
   File[] files = f.listFiles();
   int i = 0;
   for(File file : files)
   {
    if(i==numberOfFiles)
     break ;
    if(file.isFile())
    {
     filesToReturn.add(file);
     i++;
    }
   }
  }
  else
  {
   throw new Exception("Invalid Directory");
  }
  return filesToReturn;
 }

}
And the flow will be like this :
<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
 xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:spring="http://www.springframework.org/schema/beans" version="CE-3.3.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd 
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd 
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd ">

<spring:beans>
<spring:bean id="filePoller" class="com.javaroots.FilePollerComponent">
<spring:property name="pollDir" value="E:/fileTest"></spring:property>
<spring:property name="numberOfFiles" value="3"></spring:property>


</spring:bean>

</spring:beans>

<flow name="fileInboundTestFlow" doc:name="fileInboundTestFlow" processingStrategy="synchronous">
     <poll frequency="200000">
      <component doc:name="File Poller">
       <spring-object bean="filePoller"/>
      </component>
     </poll>
     <logger message="Size of payload is : #[message.payload.size()]" level="INFO"/>
       <choice doc:name="Choice"> 
                <when expression="#[message.payload.size() &gt; 0]"> 
       <request-reply >
      <vm:outbound-endpoint path="out" >
        <collection-splitter />
      </vm:outbound-endpoint>
      <vm:inbound-endpoint path="response">
       <message-properties-transformer>
        <add-message-property key="MULE_CORRELATION_GROUP_SIZE" value="3" />
       </message-properties-transformer>
      <collection-aggregator/>
      </vm:inbound-endpoint>      
    </request-reply>
   </when>
   <otherwise>
     <logger />
   </otherwise>
  </choice>
    </flow>
    
    <flow name="processor" >
     <vm:inbound-endpoint path="out"/>
      <component class="com.javaroots.SleepComponent" doc:name="sleep"/>
      <vm:outbound-endpoint path="response"/>
    </flow>

</mule>


In the flow , first we put our custom file poller component which will give us list of files not more than 3 . Then we create request reply which will process this list , and it will wait untill all three files are processed . The actual processing of each individual file will happen in another flow , where i have put a sleep component .Request reply passes each payload to vm outbound and at the same vm , the other flow will listen .

Once the flow completes its processing , it returns the response to request reply flow . Collection aggregator blocks untill response from all the three files comes back .So in this way we can control number of files to be processed .

make sure that MULE_CORRELATION_GROUP_SIZE is equal to numberOfFiles which we want to be processed concurrently.

This solution is provided by David Dossot on my stack overflow question

You can see the full source code here

Post Comments and Suggestions !!!

Thursday, 19 June 2014

Validate Xml Against XSD from ClassPath

I have described how to validate xml against schema in another post. Now if you have schema files in your classpath , and if one schema is dependent on other , then you have to do following things to validate it.

Create a custom ResourceResolver like this .The prefix is for those schema files which are not in root of classpath . suppose your schema files contained in a folder named schemas in classpath , then provide prefix as /schema.
package com.acs.plum.web.service.util.xml.validator;
import java.io.InputStream;

import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSResourceResolver;

public class ResourceResolver  implements LSResourceResolver {

private String prefix ; 
public LSInput resolveResource(String type, String namespaceURI,
        String publicId, String systemId, String baseURI) {
 
 systemId = prefix +"/" + systemId; 
    InputStream resourceAsStream = this.getClass().getResourceAsStream(systemId);
    return new CustomLSInput(publicId, systemId, resourceAsStream);
}
/**
 * @return the prefix
 */
public String getPrefix() {
 return prefix;
}
/**
 * @param prefix the prefix to set
 */
public void setPrefix(String prefix) {
 this.prefix = prefix;
}



}

Create CustomLSInput class .
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;

import org.w3c.dom.ls.LSInput;

public class MyCustomLSInput implements LSInput {

private String publicId;

private String systemId;

public String getPublicId() {
    return publicId;
}

public void setPublicId(String publicId) {
    this.publicId = publicId;
}

public String getBaseURI() {
    return null;
}

public InputStream getByteStream() {
    return null;
}

public boolean getCertifiedText() {
    return false;
}

public Reader getCharacterStream() {
    return null;
}

public String getEncoding() {
    return null;
}

public String getStringData() {
    synchronized (inputStream) {
        try {
            byte[] input = new byte[inputStream.available()];
            inputStream.read(input);
            String contents = new String(input);
            return contents;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null ;
    }
}

public void setBaseURI(String baseURI) {
}

public void setByteStream(InputStream byteStream) {
}

public void setCertifiedText(boolean certifiedText) {
}

public void setCharacterStream(Reader characterStream) {
}

public void setEncoding(String encoding) {
}

public void setStringData(String stringData) {
}

public String getSystemId() {
    return systemId;
}

public void setSystemId(String systemId) {
    this.systemId = systemId;
}

public BufferedInputStream getInputStream() {
    return inputStream;
}

public void setInputStream(BufferedInputStream inputStream) {
    this.inputStream = inputStream;
}

private BufferedInputStream inputStream;

public MyCustomLSInput(String publicId, String sysId, InputStream input) {
    this.publicId = publicId;
    this.systemId = sysId;
    this.inputStream = new BufferedInputStream(input);
    
}
}
Now in your main class set resource resolver with proper prefix.

import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.xml.sax.SAXException;


public class XmlValidator
{
 public static void main(String[] args)
 {
  try {
      String schemaLang = "http://www.w3.org/2001/XMLSchema";

      SchemaFactory factory = SchemaFactory.newInstance(schemaLang);
      
      
       ResourceResolver resolver = new ResourceResolver();
       resolver.setPrefix("/javaroots");//set prefix if your schema is not in the root of classpath

      factory.setResourceResolver(new ResourceResolver());
      
      Schema schema = factory.newSchema(new StreamSource(XmlValidator.class.getResourceAsStream("/MarketLive.xsd")));
      Validator validator = schema.newValidator();

      validator.validate(new StreamSource("D:\\sportschalet\\SchemaNSamples-5.9.8\\test\\sample_300189_3038341.xml"));
      
      System.out.println("Successfully validated");

  } catch (SAXException e) {
      e.printStackTrace();
  } catch (Exception ex) {
      ex.printStackTrace();
  }
  
  
 }
}
Thats it !! now you do not need to copy schemas in a separate folder . You can have them in your classpath .

Post comments and Suggestions !!!
StackOverFlow Ref

Thursday, 12 June 2014

Git : How to add commit in between old commits

I have a Git repository and need to rewrite my local history by inserting a new commit in between old commits.

More specifically my sitatution is like this:
  AB—BC—CD—EF   MASTER
and I wanted to come up with something like this:
  AB—BC—SA—CD—EF   MASTER
Where SA is my new commit i.e to be inserted b/w commit BC & CD.

Well, it isn’t actually an extreme or difficult case.It’s actually a very simple procedure to follow:
$ git checkout master
$ git checkout -b temp BC 
$ git add
$ git commit # your changes that will be SA
Now your Repo will look like this :
  AB—BC—SA  temp
      \
      CD—EF MASTER
After this repository layout it’s rather simple to transform it into a single sequence of commits:
 $ git rebase temp master
You may get few conflicts that you need to resolve .

  Now you are all Done !!!

TAGGING COMMITS


You will notice that your SHA keys are modified and tag doesn't appear above commit BC to make sure your tags are in line follow the steps:
 $ git tag -l #to list all your tags.
For each tag type the following command,
 $ git show TAG_NAME
to see the details of the old commit.

Make note of the subject line, date, and hash of the old commit.
Page through git log looking for that subject line and date. Make note of the hash of the new commit when you find it.
 $ git tag --force TAG_NAME NEW_COMMIT_HASH #to update the tag.
Hope that you have not mistaken one commit for another with a similar subject line and date.

Thanks to Santosh Mohanty for writing this post .

Post Comments And Suggestions !!!

Mule File Inbound Infinite loop

Mule file inbound end point is going in to infinite loop if we use custom queued-asynchronous-processing-strategy . It keeps on acquiring the lock on the same file and does nothing . I am using mule version 3.3.1 . Here's the mule xml file :
<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:spring="http://www.springframework.org/schema/beans" version="CE-3.3.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd 
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd 
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd 
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd ">
 <file:connector name="myFileConnector" doc:name="File">
 <!-- <service-overrides messageReceiver="InputFileMessageReceiver"/> --> 
 </file:connector>
 
 <queued-asynchronous-processing-strategy name="allow2Threads" maxThreads="2"/>

    <flow name="fileInboundTestFlow1" doc:name="fileInboundTestFlow1" processingStrategy="allow2Threads">
        <file:inbound-endpoint path="E:/fileTest" responseTimeout="10000" doc:name="File" pollingFrequency="50" connector-ref="myFileConnector" >
        </file:inbound-endpoint>
        <byte-array-to-object-transformer doc:name="Byte Array to Object"/>
        <component class="SleepComponent" doc:name="sleep"/>
    </flow>
   
</mule>


Is it a bug ?

Wednesday, 11 June 2014

How Ruby Source Code Gets Executed

Programming languages, such as Ruby, are natural and elegant. But to achieve this elegance, things have to happen under the hood.

Let's see how does a ruby code is compiled and interpreted.

Before moving forward lets see the structure(cross-section) of ruby and its world.















90% of work is done on the surface, so that we focus on developing business value .

The following code will be split into tokens by ruby lexer
 puts 'Welcome to Ruby World'
Tokenized Representation :
 [“puts”,” ”,”'”,”Welcome to Ruby World”,”'”]
Lexed Representation :
Lexer Format:
 [[line number,column],type,token]
 [[1,0]:on_ident,”puts”],
  [1,4]:on_sp,” ”]
  [1,5]:on_t_string_beg,”'”]
  [1,6]:on_t_string_content,”Welcome to Ruby World”]
  [1,28]:on_t_string_end,”'”]]
Once the code generates token & is lexed , now the parser will start its job by taking the lexed representation and create a Abstract syntax tree.


AST:
 [:program,
   [[:command,
    [:@ident, ”puts” , [1,0] ],
     [:args_add_block,
      [[:string_literal,
       [:string_content],[:@string_content, “Welcome to Ruby World”,[1,6]]]]],
 false]]]
Once AST finishes the job the compiler will convert to byte code, Now it is executed/interpreted by VM

This is Implemented in MRI. Ruby uses lex(Lexer) & bison(parser generator).
Implementation of Above code in CLI/Ruby Program :
 require “ripper”
 require “pp”
 src= “puts 'Welcome to Ruby World'”
 puts “source: #{src}”
 puts “tokenized:”
 pp Ripper.tokenize(src)
 puts “lexed:”
 pp Ripper.lex(src)
 puts “parsed:”
 pp Ripper.sexp(src)
Refer Confreaks
Njoy Coding in Ruby !!

Thanks to Santosh Mohanty for writing this post .

Monday, 9 June 2014

Validate XML against XSD in Java

Here's the sample java program which will validate xml file against a particular schema file .

import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.xml.sax.SAXException;


public class XmlValidator
{
 public static void main(String[] args)
 {
  try {
      

      SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");

      Schema sch= schemaFactory .newSchema(new StreamSource("D:\\example.xsd"));
      Validator validator = sch.newValidator();

      validator.validate(new StreamSource("D:\\example.xml"));
      
      System.out.println("Successfully validated");

  } catch (Exception e) {
      e.printStackTrace();
  } 
  
  
 }
}