Thursday, 18 December 2014

How to Check For Null Payload in Mule XML

If we want to check in our flow , weather payload is null or not , we can do it using MULE Expression Language .
#[payload == null]
This was not working in MULE 3.1.1 , so we can try another expression like this :
#[payload is NullPayload]
But , this condition also threw and Exception like this :
org.mule.api.MessagingException: Execution of the expression "payload is NullPayload" failed. (org.mule.api.expression.ExpressionRuntimeException). Message payload is of type: NullPayload
 at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:35)
 at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:43)
 at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:43)
 at org.mule.processor.chain.DefaultMessageProcessorChain.doProcess(DefaultMessageProcessorChain.java:93)
 at org.mule.processor.chain.AbstractMessageProcessorChain.process(AbstractMessageProcessorChain.java:66)
 at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
 at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:43)
 at org.mule.processor.AbstractInterceptingMessageProcessorBase.processNext(AbstractInterceptingMessageProcessorBase.java:105)
 at org.mule.interceptor.AbstractEnvelopeInterceptor.process(AbstractEnvelopeInterceptor.java:55)
 at org.mule.processor.AsyncInterceptingMessageProcessor.processNextTimed(AsyncInterceptingMessageProcessor.java:118)
 at org.mule.processor.AsyncInterceptingMessageProcessor$AsyncMessageProcessorWorker$1.process(AsyncInterceptingMessageProcessor.java:186)
 at org.mule.processor.AsyncInterceptingMessageProcessor$AsyncMessageProcessorWorker$1.process(AsyncInterceptingMessageProcessor.java:179)
 at org.mule.execution.ExecuteCallbackInterceptor.execute(ExecuteCallbackInterceptor.java:20)
 at org.mule.execution.HandleExceptionInterceptor.execute(HandleExceptionInterceptor.java:34)
 at org.mule.execution.HandleExceptionInterceptor.execute(HandleExceptionInterceptor.java:18)
 at org.mule.execution.BeginAndResolveTransactionInterceptor.execute(BeginAndResolveTransactionInterceptor.java:58)
 at org.mule.execution.ResolvePreviousTransactionInterceptor.execute(ResolvePreviousTransactionInterceptor.java:48)
 at org.mule.execution.SuspendXaTransactionInterceptor.execute(SuspendXaTransactionInterceptor.java:54)
 at org.mule.execution.ValidateTransactionalStateInterceptor.execute(ValidateTransactionalStateInterceptor.java:44)
 at org.mule.execution.IsolateCurrentTransactionInterceptor.execute(IsolateCurrentTransactionInterceptor.java:44)
 at org.mule.execution.ExternalTransactionInterceptor.execute(ExternalTransactionInterceptor.java:52)
 at org.mule.execution.RethrowExceptionInterceptor.execute(RethrowExceptionInterceptor.java:32)
 at org.mule.execution.RethrowExceptionInterceptor.execute(RethrowExceptionInterceptor.java:17)
 at org.mule.execution.TransactionalErrorHandlingExecutionTemplate.execute(TransactionalErrorHandlingExecutionTemplate.java:113)
 at org.mule.execution.TransactionalErrorHandlingExecutionTemplate.execute(TransactionalErrorHandlingExecutionTemplate.java:34)
 at org.mule.processor.AsyncInterceptingMessageProcessor$AsyncMessageProcessorWorker.doRun(AsyncInterceptingMessageProcessor.java:178)
 at org.mule.work.AbstractMuleEventWork.run(AbstractMuleEventWork.java:43)
 at org.mule.work.WorkerContext.run(WorkerContext.java:311)
 at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
 at java.lang.Thread.run(Unknown Source)
Caused by: org.mule.api.expression.ExpressionRuntimeException: Execution of the expression "payload is NullPayload" failed.
 at org.mule.el.mvel.MVELExpressionLanguage.evaluateInternal(MVELExpressionLanguage.java:208)
 at org.mule.el.mvel.MVELExpressionLanguage.evaluate(MVELExpressionLanguage.java:169)
 at org.mule.expression.DefaultExpressionManager.evaluate(DefaultExpressionManager.java:234)
 at org.mule.expression.DefaultExpressionManager.evaluateBoolean(DefaultExpressionManager.java:361)
 at org.mule.routing.filters.ExpressionFilter.accept(ExpressionFilter.java:127)
 at org.mule.routing.ChoiceRouter.selectProcessors(ChoiceRouter.java:35)
 at org.mule.routing.AbstractSelectiveRouter.process(AbstractSelectiveRouter.java:194)
 at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
 at org.mule.execution.MessageProcessorNotificationExecutionInterceptor.execute(MessageProcessorNotificationExecutionInterceptor.java:43)
 at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:43)
 at org.mule.execution.ExceptionToMessagingExceptionExecutionInterceptor.execute(ExceptionToMessagingExceptionExecutionInterceptor.java:27)
 at org.mule.execution.MessageProcessorExecutionTemplate.execute(MessageProcessorExecutionTemplate.java:43)
 ... 23 more
Caused by: [Error: could not access: NullPayload; in class: null]
[Near : {... Unknown ....}]
             ^
[Line: 1, Column: 0]
 at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getBeanProperty(ReflectiveAccessorOptimizer.java:611)
 at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.getBeanPropertyAO(ReflectiveAccessorOptimizer.java:439)
 at org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer.compileGetChain(ReflectiveAccessorOptimizer.java:353)
To resolve this , you have to tweak the expression a little bit like this :
#[payload is org.mule.transport.NullPayload]
Post Comments And Suggestions !!

MULE EXPRESSION LANGUAGE REF




Thursday, 20 November 2014

How To Get Client Operating System Name IN ROR

In the world of increasing web sites in a fast pace , at times we need to get the clients OS details to execute some script in clients machine, or know what is the OS/Web browser/Client Details used by client.


When ever a client accesses your website and makes a request, Browser sends the details of the client in as an WEBHTTP OBJECT.


HTTP_USER_AGENT request header contains the information about client .


To get this information in rails we need to write following code .


we create a around filter/action to and paste it in application controller so that it keeps the track of every request.


def get_operating_system
  if request.env['HTTP_USER_AGENT'].downcase.match(/mac/i)
    "Mac"
  elsif request.env['HTTP_USER_AGENT'].downcase.match(/windows/i)
    "Windows"
  elsif request.env['HTTP_USER_AGENT'].downcase.match(/linux/i)
    "Linux"
  elsif request.env['HTTP_USER_AGENT'].downcase.match(/unix/i)
    "Unix"
  else
    "Unknown"
  end
end
Thanks to Santosh for writing this post .



Monday, 17 November 2014

How to Use ActiveMQ in Rails App

Active MQ is one of the most popular messaging server . In this post we will list out the steps on how to use it in rails application.

Installation ActiveMQ procedure for Ubuntu 14.04

Download ActiveMQ 5.4.2 from http://activemq.apache.org/download.html or you can install it from console by writing following command .
sudo apt-get install activemq
Now start the server by writing following command :
$ ./activemq start
Now , for connecting activeMQ server , we can use Stomp Gem .

So for sending message , open IRB prompt and write following command :
$ irb req1.9.3-p362 :001 > require "stomp"=> true 
1.9.3-p362 :002 > client = Stomp::Client.new("admin", "admin", "localhost", 61613)
You might get error like this :
Errno::ECONNREFUSED: Connection refused - connect(2)
 from /home/usermac44/.rvm/gems/ruby-1.9.3-p362/gems/stomp-1.3.3/lib/connection/netio.rb:203:in `initialize'
We have to configure stomp protocol on our activemq server like this : Add the following line to the configuration file:
  <transportConnectors>
    <transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&amp;wireformat.maxFrameSize=104857600"/>
  </transportConnectors>
Now restart activemq , initiate the client and send message like this :
client = Stomp::Client.new("admin", "admin", "localhost", 61613)
 => #"0,0", 
"session"=>"ID:ACSMAC05-63136-1415951184416-2:1", "server"=>"ActiveMQ/5.8.0", "version"=>"1.0"} ......#>


client.publish {|msg|  puts msg }
It will work now . You can see the active mq console at http://localhost:8161/admin .


Thanks to santosh for writing this post .

Thursday, 30 October 2014

How to Upload Images to DropBox In Java

This Tutorial explains how to upload images to drop box and get the public url of uploaded image .
First of all we have to create a DropBox API app using app console. Once you create the app , you can get App key and secret key in the app properties .

Now add following dependency in your pom file .
<dependency>
 <groupId>com.dropbox.core</groupId>
 <artifactId>dropbox-core-sdk</artifactId>
 <version>1.7.7</version>
</dependency>
Now this java program will do the rest . Replace your app ket and secret key in program . Run this java program from command line and it will ask for the code , you will get the code by following the url printed on the console.

For getting the public url , we just need to use createShareableUrl of the dropboxClient class.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Locale;

import com.dropbox.core.DbxAppInfo;
import com.dropbox.core.DbxAuthFinish;
import com.dropbox.core.DbxClient;
import com.dropbox.core.DbxEntry;
import com.dropbox.core.DbxException;
import com.dropbox.core.DbxRequestConfig;
import com.dropbox.core.DbxWebAuthNoRedirect;
import com.dropbox.core.DbxWriteMode;


public class UploadImages
{
 public static void main(String[] args) throws IOException, DbxException
 {
  final String DROP_BOX_APP_KEY = "APPKEY";
        final String DROP_BOX_APP_SECRET = "SECRETKEY";
        
        String rootDir = "C:\\Users\\Downloads\\";

        DbxAppInfo dbxAppInfo = new DbxAppInfo(DROP_BOX_APP_KEY, DROP_BOX_APP_SECRET);

        DbxRequestConfig reqConfig = new DbxRequestConfig("javarootsDropbox/1.0",
            Locale.getDefault().toString());
        DbxWebAuthNoRedirect webAuth = new DbxWebAuthNoRedirect(reqConfig, dbxAppInfo);

        
        String authorizeUrl = webAuth.start();
        System.out.println("1. Go to this URL : " + authorizeUrl);
        System.out.println("2. Click \"Allow\" (you might have to log in first)");
        System.out.println("3. Copy the authorization code and paste here ");
        String code = new BufferedReader(new InputStreamReader(System.in)).readLine().trim();

        
        
        DbxAuthFinish authFinish = webAuth.finish(code);
        String accessToken = authFinish.accessToken;

        DbxClient client = new DbxClient(reqConfig, accessToken);

        System.out.println("account name is : " + client.getAccountInfo().displayName);

        
        
        File inputFile = new File(rootDir +"images\\"+ "javaroots.jpg");
        FileInputStream inputStream = new FileInputStream(inputFile);
        try {
         
            DbxEntry.File uploadedFile = client.uploadFile("/javaroots.jpg",
                DbxWriteMode.add(), inputFile.length(), inputStream);
            String sharedUrl = client.createShareableUrl("/javaroots.jpg");
            System.out.println("Uploaded: " + uploadedFile.toString() + " URL " + sharedUrl);
        } finally {
            inputStream.close();
        }
 }
}
Take reference from the this official drop box link.

You can download the full project from this link . Post Comments and Suggestions !!


How To Configure SSL with NGINX IN RAILS

In our previous post,we have learnt how to use ssl in a rails application by modifiying application server and application configurations.

In this post we will be configuring/bypassing Proxy for using ssl in an web server.

We will be using Nginx for our configuration.

To configure an HTTPS server, the ssl parameter must be enabled on listening sockets in the server block, and the locations of the server certificate and private key files should be specified.

Generate your ssl keys using the previous post and copy over the files to nginx directory.








Download the nginx.conf file , take back up of your existing configuration and replace it .

Steps to follow:
1. Add the number of worker process you need by default it should be 1. e.g worker_processes 4;
2. Make sure that path of ssl_certificate & ssl_certificate_key are correct.
3. Create dir/entry for access_log & error_log.
4. In the upstream section you can configure your server address with port for https, like this
 
   upstream proxy_pass_server {
            server 127.0.0.1:3000 fail_timeout=0;
      }
Here I am pointing to localhost port 3000 and added server_name 127.0.0.1 in Server Section of configuration

Now , Start your rails server independent of application server in 3000 port and type https://localhost

Your application Now runs on HTTPS .

Thanks to Santosh for writing this post .

REFER NGINX For more Details

Monday, 13 October 2014

Social Media Authentication On Rails- Part 2

In the last post , we have discussed how to get api keys and access for multiple social media platform .In this post we will to setup rails to integrate these applications .

Code SetUp:

Now its Time to Set Up Rails Application with MongoDB , Rails & Omniauth Gem(s).
we will be using “ruby 2.1.1p76” with “Rails 4.1.0” for our application.

Step 1:
In Gem file add the following Gems:
gem 'rails', '4.1.0'
gem 'mongoid', git: 'https://github.com/mongoid/mongoid.git'
gem 'devise'
gem 'bson_ext'
gem 'omniauth'
gem 'omniauth-facebook'
gem 'omniauth-linkedin' 
gem 'omniauth-twitter' 
gem "omniauth-google-oauth2"
gem 'twitter'
gem "linkedin"
gem 'oauth2'
Step 2:
Follow the link and install devise gem to your application.
For Omniauth with devise follow the link which will be usefull for development and debugging your application.
Step 3:
Include required Gems in your initializers/devise.rb file and add your API KEYS with API Secret.
require 'devise/orm/mongoid'
require 'omniauth-twitter'
require 'omniauth-google-oauth2'
require 'omniauth-linkedin'
require 'omniauth-facebook'
require 'omniauth-github'

Configuring API Keys:
config.omniauth :twitter, "API KEY", "API SECRET"
config.omniauth :linkedin, "API KEY", "API SECRET", :scope => 'r_basicprofile r_emailaddress rw_nus'
config.omniauth :facebook, 'API KEY', 'API SECRET'
config.omniauth :google_oauth2, 'API KEY', 'API SECRET'

Add the following links to devise registrations/new or shared/_links.html.erb









Open Up Your User Model and Configure it as described below , fields for mongo db can be configured as per your requirement :
class User
  include Mongoid::Document
  devise :omniauthable, :omniauth_providers => [:facebook,:twitter,:linkedin,:google_oauth2]
  embeds_one :user_linkedin_connection, :class_name => 'User::LinkedinConnection'
  embeds_one :user_twitter_connection, :class_name => 'User::TwitterConnection'
  # Configured for Getting mongo key from Session in rails 4 (Mongoid)
  class << self
    def serialize_from_session(key, salt)
      record = to_adapter.get(key.first["$oid"]) if key.present? # to_adapter.get(key.to_s)
      record if record && record.authenticatable_salt == salt
    end
  end
  def self.connect_to_linkedin(auth)
    self.provider = auth.provider
    self.uid = auth.uid
    self.user_linkedin_connection = User::LinkedinConnection.new(:token => auth["extra"]["access_token"].token, :secret => auth["extra"]["access_token"].secret)
    unless self.save
      return false
    end
    true
  end
  def self.disconnect_from_linkedin!
    self.provider = nil
    self.uid = nil
    self.user_linkedin_connection = nil
    self.save!
  end
  def self.find_for_linkedin_oauth(auth, signed_in_resource=nil)
    @user = User.where(:provider => auth.provider, :uid => auth.uid).first
    if @user
      @user.connect_to_linkedin(request.env["omniauth.auth"])
      sign_in_and_redirect @user, :event => :authentication
      set_flash_message(:notice, :success, :kind => "LinkedIn") if is_navigational_format?
    else
      flash[:notice] = "Couldn't find a user connected to your LinkedIn account. Please sign in and then connect your account to LinkedIn."
      redirect_to new_user_session_url
    end
  end
  def self.find_for_facebook_oauth(auth)
   where(auth.slice(:provider, :uid)).first_or_create do |user|
     user.provider = auth.provider
     user.uid = auth.uid
     user.email = auth.info.email
     user.password = Devise.friendly_token[0,20]
     user.name = auth.info.name   # assuming the user model has a name
   end
  end
  def self.find_for_google_oauth2(access_token, signed_in_resource=nil)
    data = access_token.info
    user = User.where(:email => data["email"],:provider => "Google").first
    unless user
      user = User.create( name: data["name"],email: data["email"],provider: "Google", password: Devise.friendly_token[0,20]  )
    end
    user
  end
  def self.find_for_github_oauth(auth)
    record = where(provider: auth.provider, uid: auth.uid.to_s).first
    record || create(provider: auth.provider, uid: auth.uid, email: auth.info.email, password: Devise.friendly_token[0,20], name: auth.info.name )
  end
end
Create two More files named linkedin_connection.rb and twitter_connection.rb inside app/models/user/ which will contain the token and secret provided from provider.

linkedin_connection.rb:
class User::LinkedinConnection
  include Mongoid::Document
  include Mongoid::Timestamps
  embedded_in :user
  field :token
  field :secret
end 
twitter_connection.rb:
class User::TwitterConnection
  include Mongoid::Document           field :token
  include Mongoid::Timestamps         field :secret
  embedded_in :user
   end
Once we get a Success request from Provider , response moves on to omniauth call_back controller where we need to store the response and maintain the session.

Create a omniauth_callback controller and paste the code as provided below:

class OmniauthCallbacksController < Devise::OmniauthCallbacksController
  before_filter :authenticate_user!
  # Linkedin authentication
  def linkedin
    @user = User.where(:provider => request.env["omniauth.auth"].provider, :uid => request.env["omniauth.auth"].uid).first
    if @user.present?
      sign_in_and_redirect @user, :event => :authentication
      set_flash_message(:notice, :success, :kind => "LinkedIn") if is_navigational_format?
    else
      auth = request.env["omniauth.auth"]
      @user = User.new #create new user to save in the database
      @user.email=  auth.info.email #save user email
      @user.provider = auth.provider
      @user.uid = auth.uid
      @user.user_linkedin_connection = User::LinkedinConnection.new(:token => auth["extra"]["access_token"].token, :secret => auth["extra"]["access_token"].secret)
      @user.save(:validate => false) #password for the linkdin to be stored
      sign_in_and_redirect @user, :event => :authentication
      set_flash_message(:notice, :success, :kind => "LinkedIn") if is_navigational_format?
    end
  end

# Facebook authentication
def facebook
    # You need to implement the method below in your model (e.g. app/models/user.rb)
    @user = User.find_for_facebook_oauth(request.env["omniauth.auth"])
    if @user.persisted?
      sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
      set_flash_message(:notice, :success, :kind => "Facebook") if is_navigational_format?
    else
      session["devise.facebook_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end

# Twitter authentication
def twitter
    @user = User.where(:provider => request.env["omniauth.auth"].provider, :uid => request.env["omniauth.auth"].uid).first
    if @user.present?
      sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
      set_flash_message(:notice, :success, :kind => "Twitter") if is_navigational_format?
    else
      auth = request.env["omniauth.auth"] # contains all the information about the user login profile.
      @user = User.create(name: auth.extra.raw_info.name,
                  provider: auth.provider,
                  uid: auth.uid,
                  email: auth.uid+"@twitter.com", #create user email
                  password: Devise.friendly_token[0,20],
                  user_twitter_connection: User::TwitterConnection.new(:token => auth.credentials.token, :secret => auth.credentials.secret )
      )
      sign_in_and_redirect @user, :event => :authentication
      set_flash_message(:notice, :success, :kind => "Twitter") if is_navigational_format?
    end
  end

 # Google authentication
  def google_oauth2
    # You need to implement the method below in your model (e.g. app/models/user.rb)
    @user = User.find_for_google_oauth2(request.env["omniauth.auth"])
    if @user.persisted?
      sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
      set_flash_message(:notice, :success, :kind => "Google") if is_navigational_format?
      # flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
      # sign_in_and_redirect @user, :event => :authentication #this will throw if @user is not activated
    else
      session["devise.google_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end
end
Now we are Good to Go ahead and start authenticating with social websites in our Rails app.

Note:
• Application status in Provider Settings should be live
• Call back URL should match your application routes
• It is Good to go with Storing session in DB as sometimes cookie_store fails when a logged in user fetches request from provider.


Thanks to Santosh for wroting this post .


Social Media Authentication On Rails- Part 1

This Post is intended to provide an overview of the installation of social authentication plugins like Twitter/Github/Facebook & Google using Rails version 4 with devise(authentication plugin),omniauth(API Plugin for Social websites) & Mongo DB as underlying Database.


Before Proceeding towards installation/building a rails application that allows authentication with social websites we need to get API/Client Keys & API/Client Secret.


Here are the urls from where you can create an App and get the keys:


Facebook:

URL: Facebook Link











Twitter:>

URL: Twitter































Settings: Enter call back url as : http://127.0.0.1:3000/auth/twitter/callback/ under settings tab once you create an application














Google:

URL: Google URL










Settings: Go to API Access and enter redirect url as http://localhost:3000/users/auth/google_oauth2/callback



LinkedIn:>

URL: LinkedIn URL

Linked In Api Doesnot require any call back URI. Application URL is Enough for Linked in api as Omniauth-linked Has its method defined in Gem.













In the next post , the ROR code will be explained to integrate these social applications .