Wednesday, August 29, 2012

OAuth2.0 Implementation for Google API in JAVA or PHP

Using OAuth2.0 authenticating your web application with Google API is very easy.  This will help your applications to maintain sing user repository from Google logging, and no need to maintain any password at your application side.  Here the idea is to give an idea of complete Web Server flow (Oauth2 web server side dance ) and understand it completely with complete open source technologies.

First step is go to Google API Console and register a project then create a Web Application  userid and secret key.  (Make sure that the registering URL will have your application's context path).
Note: Modify the userid/secretkeys as per your settings.

Create a web project ( say TestProject) and then create a servlet as shown below:


package com.test.oauth;

import java.io.BufferedReader;
import java.io.IOException;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.io.IOUtils;

public class OAuthTwoCallBackServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

private static String client_id = "895498929378-4uohdps8sb5v6jp8saf0rea73c0h87nr.apps.googleusercontent.com";
private static String client_secret = "LsIy_r4-S22jGwGJkbNeYQ1H";
private static String redirectURL = "http://localhost:8080/TestProject/callback";
private String auth_code = null;

public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {

System.out.println("Callback to URI that is configured in Google API Console");
resp.setContentType("text/html");
resp.getWriter().println(" OAuth2.0 example in Web Server Flow");
resp.getWriter().println(" ");
resp.getWriter().println("
");


if (req.getParameter("code") == null) {

if (req.getParameter("error") != null) {
resp.getWriter().println("Hello, " + req.getParameter("error"));
} else {

resp.getWriter().println("");
resp.getWriter().println("");
resp.getWriter().println("
"); resp.getWriter().println("");
resp.getWriter().println("

Hello

");
resp.getWriter().println("To login with Google Account click here ");
resp.getWriter().println("");
resp.getWriter().println(" resp.getWriter().println(" alt='Powered by Google App Engine' />");
resp.getWriter().println("
"); resp.getWriter().println("
"); }
} else {
resp.getWriter().println("

Code

");
resp.getWriter().println("Authentication Code = " + req.getParameter("code"));
this.auth_code = req.getParameter("code");

// Exchange the code for token
HttpClient httpclient = new HttpClient();
BufferedReader bufferedreader = null;
PostMethod postmethod = new PostMethod(
"https://accounts.google.com/o/oauth2/token");
postmethod.addParameter("code", auth_code);
postmethod.addParameter("client_id", client_id);
postmethod.addParameter("client_secret", client_secret);
postmethod.addParameter("redirect_uri", redirectURL);
postmethod.addParameter("grant_type", "authorization_code");
String access_token = null;
String token_type = null;
int expires_in = 0;
String id_token = null;
try {

int rCode = httpclient.executeMethod(postmethod);
System.out.println("HTTP POST for Token rCode is" + rCode);

if (rCode == HttpStatus.SC_NOT_IMPLEMENTED) {
System.err.println("The Post postmethod is not implemented by this URI");
postmethod.getResponseBodyAsString();
} else if (rCode == HttpStatus.SC_NOT_ACCEPTABLE) {
System.out.println(postmethod.getResponseBodyAsString());
} else {

String jsonTxt = IOUtils.toString(postmethod
.getResponseBodyAsStream());

JSONObject json = (JSONObject) JSONSerializer
.toJSON(jsonTxt);

access_token = json.getString("access_token");
token_type = json.getString("token_type");
expires_in = json.getInt("expires_in");
id_token = json.getString("id_token");
System.out.println("======== TOKEN INFO ========");
System.out.println("access_token: " + access_token);
System.out.println("token_type: " + token_type);
System.out.println("expires_in: " + expires_in);
System.out.println("id_token: " + id_token);
System.out.println("=========================");
resp.getWriter().println("

Token & Refresh

");
resp.getWriter().println("Access Token = " + access_token);
resp.getWriter().println("Refresh Token = " + id_token);
resp.getWriter().println("Expire Time (Seconds) = " + expires_in);
resp.getWriter().println("Token Type = " + token_type);
}
} catch (Exception e) {
System.err.println(e);
} finally {
postmethod.releaseConnection();
if (bufferedreader != null)
try {
bufferedreader.close();
} catch (Exception fe) {
fe.printStackTrace();
}
}

//Calling Google account info API
User user = null;
httpclient = new HttpClient();
bufferedreader = null;
GetMethod getmethod = new GetMethod("https://www.googleapis.com/oauth2/v1/userinfo?access_token=" + access_token);
try {
int rCode = httpclient.executeMethod(getmethod);
System.out.println("HTTP GET for User rCode is" + rCode);

if (rCode == HttpStatus.SC_NOT_IMPLEMENTED) {
System.err
.println("The Get method is not implemented by this URI");
getmethod.getResponseBodyAsString();
} else if (rCode == HttpStatus.SC_NOT_ACCEPTABLE) {
System.out.println(getmethod.getResponseBodyAsString());
} else {

String jsonTxt = IOUtils.toString(getmethod
.getResponseBodyAsStream());
JSONObject json = (JSONObject) JSONSerializer
.toJSON(jsonTxt);

user = new User();
user.id = json.getString("id");
user.name = json.getString("name");
user.email = json.getString("email");
user.picture = json.getString("picture");
user.gender = json.getString("gender");
user.locale = json.getString("locale");

System.out.println("============ TOKEN INFO ===============");
System.out.println("id: " + user.id);
System.out.println("name: " + user.name);
System.out.println("Gender: " + user.gender);
System.out.println("email: " + user.email);
System.out.println("pictureURL: " + user.picture);
System.out.println("Locale: " + user.locale);
System.out.println("====================================");
}
} catch (Exception e) {
System.err.println(e);
} finally {
postmethod.releaseConnection();
if (bufferedreader != null)
try {
bufferedreader.close();
} catch (Exception fe) {
fe.printStackTrace();
}
}

// Get User Information
//resp.setContentType("text/html");
resp.getWriter().println("

User Information

");
resp.getWriter().println("
");
Property  Data

resp.getWriter().println("
Id
" + user.getId()+ "
");
resp.getWriter().println("
Name
" + user.getName()+ "
");
resp.getWriter().println("
Email
" + user.getEmail()+ "
");
resp.getWriter().println("
Gender
" + user.getGender()+ "
");
resp.getWriter().println("
Image

");
resp.getWriter().println("
Locale
" + user.getLocale()+ "
");
resp.getWriter().println("
");
}
}

public class User {
public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPicture() {
return picture;
}

public void setPicture(String picture) {
this.picture = picture;
}

public String getGender() {
return gender;
}

public void setGender(String gender) {
this.gender = gender;
}

public String getLocale() {
return locale;
}

public void setLocale(String locale) {
this.locale = locale;
}

String id;
String email;
String name;
String picture;
String gender;
String locale;

@Override
public String toString() {
return String.format("id:%s,name:%s,email:%s,gender:%d,locale:%s",
id, name, email, gender, locale);
}
}

public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
System.out.println("This is never called");
}
}

The web.xml file should have the following as well.

  TestProject
  
    
ServletName: OAuth2Callback
Servlet calssname: com.test.oauth.OAuthTwoCallBackServlet
Servlet Mapping: OAuth2Callback
Servlet Mapping Name /callback
     

Similarly for PHP I have create a Test project and Home.php file nothing else is required.
The Home.php :




OAuth2.0 Implementatin in PHP by Khaleel



if(!isset($_GET["code"]) || $_GET["code"] ==""){

?>

 Please click on Login button to lonon Google Apps using OAuth2.0 and get the Google Aaacount Details














}else{

$userProfile = array(
'id' => '',
'name' => '',
'gender' => '',
'email' => '',
'picture' => '',
'locale' => ''
);

$userProfile = authValidateUser($_GET["code"]);

if(isset($userProfile["email"]) && $userProfile["email"] != ""){
?>
User Property Data

Name    
Email  
Gender
ID      
Picture
Locale  



}else{

?>

Unable to get User Data, Please try Again !!!




}

}


function authValidateUser($code)
{
$OAuth = array(
'oauth_uri' => 'https://accounts.google.com/o/oauth2/auth',
'client_id' => '284443344502-do31sm7eo7nogdcn5m0dmlgb0841r8j2.apps.googleusercontent.com',
'client_secret' => 'abUpKB-rqoBOx0DJv2fhJ44S',
'redirect_uri' => 'http://localhost/Test/Home.php',
'oauth_token_uri' => 'https://accounts.google.com/o/oauth2/token'
);

$token = array(
'access_token' => '',
'token_type' => '',
'expires_in' => '',
'refresh_token' => ''
);

$userinfo = array(
'id' => '',
'name' => '',
'gender' => '',
'email' => '',
'picture' => '',
'locale' => ''
);


if(isset($code) && $code != ""){

// now exchange Authorization code for access token and refresh token
$token_response = _get_auth_token($OAuth, $code);
$json_obj = json_decode($token_response);
$token["access_token"] = $json_obj->access_token;
$token["token_type"] = $json_obj->token_type;
$token["expires_in"] = $json_obj->expires_in;
$token["refresh_token"] = $json_obj->refresh_token;
}

if(isset($token["access_token"]) && $token["access_token"] != ""){
//Exchange Authorization code for access token and refresh token
$userinfo_response = _get_user_info($token["access_token"]);
$json_obj = json_decode($userinfo_response);
$userinfo["id"] = $json_obj->id;
$userinfo["name"] = $json_obj->name;
$userinfo["gender"] = $json_obj->gender;
$userinfo["email"] = $json_obj->email;
$userinfo["picture"] = $json_obj->picture;
$userinfo["locale"] = $json_obj->locale;
}

return $userinfo;
}

function _get_auth_token($params, $code)
{
$url = $params['oauth_token_uri'];

$fields = array(
'code' => $code,
'client_id' => $params['client_id'],
'client_secret' => $params['client_secret'],
'redirect_uri' => $params['redirect_uri'],
'grant_type' => 'authorization_code'
);

$response = _do_post($url, $fields);
return $response;
}

function _get_refresh_token($params, $code)
{
$url = $params['oauth_token_uri'];

$fields = array(
'code' => $code,
'client_id' => $params['client_id'],
'client_secret' => $params['client_secret'],
'refresh_token' => $token['refresh_token'],
'grant_type' => 'refresh_token'
);

$response = _do_post($url, $fields);
return $response;
}

function _do_post($url, $fields)
{
$fields_string = "";

foreach ($fields as $key => $value)
{
$fields_string .= $key . "=" . $value . "&";
}
$fields_string = rtrim($fields_string, "&");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
$response = curl_exec($ch);
curl_close($ch);

return $response;
}


function _get_user_info($AuthToken){
$url = "https://www.googleapis.com/oauth2/v1/userinfo";
$fields = array('access_token' => $AuthToken );
$response = _do_get($url, $fields);

//$response = logoutOauthTwoUser($AuthToken);
return $response;
}

function _do_get($url, $fields)
{
$fields_string = "";

foreach ($fields as $key => $value)
{
$fields_string .= $key . "=" . $value . "&";
}
$fields_string = rtrim($fields_string, "&");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url."?".$fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPGET, TRUE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
$response = curl_exec($ch);
curl_close($ch);

return $response;
}

?>
               






                        -- END ---

Friday, July 13, 2012

Invoking from Web application to a JBPM5 process


How to invoke a JBPM process from a Servlet/JSP page?  All the examples talks about the API, but the example expecting is where to mention the HOST, PORT , and the PATH to connect the JBPM Flow?

However If there are two developers one is working on JBPM5 process and deploys to server  A. and nother developer is working on Web application he deploys his web application on server B?
Now how to submit the request (or invokes the JBPM Process) from server B ?


The steps are:
1.  Build your Process in Eclipse.
2.  Register this process with Drools repository  (see how to do it in the Chapter 16 http://docs.jboss.org/jbpm/v5.3/userguide/ch.process-repository.html ).
          (Right click on   your  Evaluation.bpmn process choose  Guvnor and then add   (provide the host and port and authentication credentials.)
3. Now you can browse the to see your deployed process at  bpmn-console  http://localhost:8080/jbpm-console/
4. Also you can see the same process in the govnor  http://localhost:8080/drools-guvnor
5. Invoke the process from the Web application Copy all the process  in some folder say  html-public/jbpmflows/   (you can copy all others flows here)
6. Use the following code with the URL that you can point to the process file as a simple static file

     private static KnowledgeBase readKnowledgeBase() throws Exception {
                    KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
                    //kbuilder.add(ResourceFactory.newClassPathResource("Evaluation.bpmn"), ResourceType.BPMN2);
                    //kbuilder.add(ResourceFactory.newUrlResource("file:///D:/Evaluation.bpmn"), ResourceType.BPMN2);
                    kbuilder.add(ResourceFactory.newUrlResource(new java.net.URL("http://:8080/webcontextroot/jbpm/Evaluation.bpmn")),         ResourceType.BPMN2);
                    return kbuilder.newKnowledgeBase();
          }
7. submit your flow request to the host system where your flows were registered

      private static StatefulKnowledgeSession createKnowledgeSession(KnowledgeBase kbase) {
                    StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
                    HornetQHTWorkItemHandler humanTaskHandler = new HornetQHTWorkItemHandler(ksession);
                    humanTaskHandler.setIpAddress("127.0.0.1");  //govnor host
                    humanTaskHandler.setPort(5445); //govnor port
                    ksession.getWorkItemManager().registerWorkItemHandler("Human Task", humanTaskHandler);
                    return ksession;
          }

--More details are welcome.

Monday, June 25, 2012

Deploy SOA 11g components using ANT scripts - REUSABLE CODE

        1.  Download the zip file from   http://sourceforge.net/projects/ant-contrib/files/ant-contrib/1.0b3/ant-contrib-1.0b3-bin.zip/download  and copy the ant-contrib-1.0b3.jar into the  JDEVELOPER/ant/lib  directory.


      2.     Copy the   build.xml, build.properties,   Test_RepairApp_build.properties,  TESTRMASOADEPLOY.bat in the directory where there the  Test_RepairApp workspace folder exist.
     (Create these files using the following content)


3.     Don’t do any changes to the build.xml  file

4.     Change the values in the TESTRMASOADEPLOY.CMD that suites to your system, If required make this as a .sh file accordingly change the paths to support on Unix systems.

5.     In the build.properties change the following things
a.     deployment.plan.environment=dev    (based on the environment change the value)
b.    Change all the paths
                                          i.    wn.bea.home=D:/JDeveloper11115
                                         ii.    java.passed.home=${wn.bea.home}/jdk160_24
                                        iii.    oracle.home=${wn.bea.home}/jdeveloper
                                        iv.    wl_home=${wn.bea.home}/wlserver_10.3
                                         v.    # temp
                                        vi.    tmp.output.dir=D:/temp
                                       vii.    junit.output.dir=junitout
                                      viii.    # my settings 
                                        ix.    applications.home=../myWorkspace

c.     Set the SOA server details
                                          i.    # dev deployment server weblogic
                                         ii.    dev.serverURL=http://localhost:7001
                                        iii.    dev.overwrite=true
                                        iv.    dev.user=weblogic
                                         v.    dev.password=welcome123
                                        vi.    dev.forceDefault=true
                                       vii.    dev.server=localhost
                                      viii.    dev.port=8001

6.     Change the partition name in the from TEST_Rep_Offshore to the required partition in the Test_RepairApp_build.properties  file.

a.     All all the Project names with comma separation
b.    All the properties for each project with projectname prefixed as shown in below example
                                          i.    TEST_Rpr_Inbound_EBS.revision=1.0
                                         ii.    TEST_Rpr_Inbound_EBS.enabled=true
                                        iii.    TEST_Rpr_Inbound_EBS.partition=TEST_Rep_Offshore

7.     Create three configuration plans for each project with _cfgplan.xml

8.     In each projects change the configuration plan xml files with right URL that points to the correspoing environment’s XSD, WSDLs.


Note: Similarly we need to check all other projects. 

    TESTSOADEPLOY .BAT
=====================
set ORACLE_HOME=D:/JDeveloper11115
set ANT_HOME=%ORACLE_HOME%/jdeveloper/ant
set PATH=%ANT_HOME%/bin;%PATH%
set JAVA_HOME=%ORACLE_HOME%/jdk160_24
   
set CURRENT_FOLDER=D:/myWorkspace
D:
CD D:/myWorkspace  
ant -f build.xml deployAll


   build.properties
======================
# demo = true , then no soa scripts will be called.
demo.mode=false

#Vaues are dev, test, or prod
deployment.plan.environment=dev


# global
wn.bea.home=D:/JDeveloper11115
java.passed.home=${wn.bea.home}/jdk160_24
oracle.home=${wn.bea.home}/jdeveloper
wl_home=${wn.bea.home}/wlserver_10.3

# temp
tmp.output.dir=D:/temp
junit.output.dir=junitout

# my settings  
applications.home=../myWorkspace
applications=Test_RepairApp



# my settings
mds.repository=${oracle.home}/integration/seed/apps/
mds.applications=CommonSchemas

#demo applications
#applications.home=workspaces
#applications=wrkspc1,wrkspc2

#demo mds locations 
#mds.repository=mds/seed/apps/
#mds.applications=company,common

#make below properties to true to deploy the MDS applications
mds.enabled=false
mds.undeploy=false


# dev deployment server weblogic
dev.serverURL=http://localhost:7001
dev.overwrite=true
dev.user=weblogic
dev.password=welcome123
dev.forceDefault=true
dev.server=localhost
dev.port=8001

# test deployment server weblogic
test.serverURL=http://localhost.test.com:7001
test.overwrite=true
test.user=weblogic
test.password=welcome123
test.forceDefault=true
test.server=localhost.test.com
test.port=8001

# production deployment server weblogic
prod.serverURL=http://localhost.prod.com:7001
prod.overwrite=true
prod.user=weblogic
prod.password=welcome123
prod.forceDefault=true
prod.server=localhost.prod.com
prod.port=8001

  
   Test_RepairApp_build.properties
=====================================
#Add all the Projects with comma Separate
projects=TEST_Rpr_Inbound_EBS,TEST_Rpr_Inbound,TEST_Rpr_Inbound_EBS_CreateRMaStatus,TEST_Rpr_Inbound_EBS_UpsertRepair,TEST_Rpr_Outbound_MDH,TEST_Rpr_Outbound_ETOS

#Add the revision, enabled, partation for each project

TEST_Rpr_Inbound_EBS.revision=1.0
TEST_Rpr_Inbound_EBS.enabled=true
TEST_Rpr_Inbound_EBS.partition=TEST_Rep_Offshore


TEST_Rpr_Inbound.revision=1.0
TEST_Rpr_Inbound.enabled=true
TEST_Rpr_Inbound.partition=TEST_Rep_Offshore


TEST_Rpr_Inbound_EBS_CreateRMaStatus.revision=1.0
TEST_Rpr_Inbound_EBS_CreateRMaStatus.enabled=true
TEST_Rpr_Inbound_EBS_CreateRMaStatus.partition=TEST_Rep_Offshore


TEST_Rpr_Inbound_EBS_UpsertRepair.revision=1.0
TEST_Rpr_Inbound_EBS_UpsertRepair.enabled=true
TEST_Rpr_Inbound_EBS_UpsertRepair.partition=TEST_Rep_Offshore


TEST_Rpr_Outbound_MDH.revision=1.0
TEST_Rpr_Outbound_MDH.enabled=true
TEST_Rpr_Outbound_MDH.partition=TEST_Rep_Offshore


TEST_Rpr_Outbound_ETOS.revision=1.0
TEST_Rpr_Outbound_ETOS.enabled=true
TEST_Rpr_Outbound_ETOS.partition=TEST_Rep_Offshore