Saturday, March 30, 2013

SSO for Java or .Net Web based applications using Openam

  • Single Sign on for Java/J2ee based Web applications
  • Single sign on using  Spring Security SAML Extension and  Role based authentication using Spring Security 
  • Single sign on Java
  • Single sign on for JSF based web application.

Introduction: Single Sign On (SSO) for Web applications using OPENAM 

Why do we need SSO ?
Say a user is logged in to one application and clicks on a link to another application and in this case if you don't want the user to enter his userid/password again but based on some token you know that "Yes the person say johnsmith@xyz.com" is already authenticated so he can access your second application.
Its like you log in to gmail and from there you can navigate to youtube or google+ or blogspot without entering password. This can be facilitated by an IDP and each time the request goes IDP know that yes "person johnsmith@xyz.com" was authenticated already and his token id is "axxbv67745554wedxyXcDb".


OpenAM is and identity provider (and more) formerly known as OpenSSO was owned by Sun which was later taken over by oracle. However Forgerock has it own source code and its called OpenAM and maintains it . You can download and deploy openam as web based J2ee application on any application server like - Tomcat, Websphere , Jboss or Weblogic.

Before getting in to the details of why we need OpenAM lets know some terminologies.I will describe them in my own words as those technical jargon's took me a while to catch up.

IDP:(Identity provider) - A module/application that can authenticate and provide you a security token which can be used in singe sign on.
SP:(Service provider):  A system that allows users (Or principal) to authenticate against IDP.
E.g.: We have a JSF 2.0 web application that talks to openam.
Here our web application is SP, Openam is IDP and I am logging in to our webapp I am the principal (user).
Realm: A realm is the unit that used to organize configuration information. Authentication properties, authorization policies, data stores, subjects (including a user, a group of users, or a collection of protected resources) and other data can be defined within the realm.
Lets say your company has Active directory for authenticating user and you want to use that as data store that the IDP can finally use. In the realm you can to use this ActiveDirectory.

Circle of Trust: COT is a federation of any number of service providers (and at least one identity provider) with whom principals can transact in a secure and apparently seamless environment.
In lay man terms we add a list of IP addresses say the SP urls,IDP url all in to once circle of trust. If they are not in same COT openam doesn't allow us to send request.
Eg: Say your web application (SP) is at www.xyz.com/shopnow and your identity provider url is www.myidp.com/openam then you need to add both these urls to one circle of trust in OpenAM.

Realm and Circle of Trust. How are they connected ?
- This is what I think. 
Realm =>Can have many Data stores or Identity Stores.
COT =>Will have many host names or Ip address (ie. SPs, IDP)
When we create a new Circle of Trust you need to specify the realm name,.
COT ===> Is linked to Realm. 
 For sake of discussion lets call our sample circle of trust as "COT1" and realm as "Relam1"
Where 
COT1 = has (SP -www.xyz.com/shopnow  and IDP - www.myidp.com/openam)
Realm1 == Is configured to use Active Directory as Identity store for Authentication.
So by doing this we are telling hey if the request comes from SP ( www.xyz.com/shopnow) use the IDP (www.myidp.com/openam) because they are in same Circle of Trust = COT1. Now the IDP sees that COT1 is linked to Realm1 and so it uses the Active directory checks the user credentials and does the Authentication.

We can have many circle of trusts linked to one realm.  Here is my visualization.




Fedlet: A client that we can generate using OpenAM. The client generated can be for a .Net or a Java based Fedlet. In Java the Fedlete can be used plugged into existing your web application  if your just doing Single sign on and not role based authorization. In my case I had to allow the user to sign in and also check in what groups the user is and based on that I had to block some pages so we had to use Spring saml extension to talk to IDP instead of Fedlet. At least for initial testing of OpenAM set up Fedlet was very useful.

SAML: Security Assertion Mark Language is an XML based data format that flows between IDP and SP when a principal is trying authentication and/or authorization. You dont need to worry about this as OpenAM generates this for you when it sends response and in your Web application if you are u


There could be a situation where you may have to integrate more than one IDP to your SP in that case you need to have another instance of OpenAM that can act like IDP proxy.
So your configuration will look like

SP (Your Java Web app) <===> IDP Proxy   <=====>  (IDP1, IDP2.....)
Where
IDPProxy is an OpenAM instance
IDP1, IDP2- Are Identity providers which can be OpenAM or any SAML2 Complaint IDPs.

Here is link  for some sample saml request and responses. 
https://rnd.feide.no/2007/12/10/example_saml_2_0_request_and_response/
Dont panic you will not create this xml OpenAM, Spring Saml extension or Fedlet does the job for you.


In the next article I will explain how to install OpenAM as IDP and how you can plugin Spring SAML extension and Spring Security to you web app to talk to OpenAM and trouble shooting.
Before I continue further I want to thank two people for there out standing support and help and answering all my stupid questions during our implementation of SSO  solution and integrating with Spring Saml extension along with Spring Security.
Vladmir Schafer: Author of Spring Saml Extension library
Peter Major and the entire OpenAM community.

If you like my articles or have any suggestions please leave a comment.

Tuesday, September 11, 2012

SQL Injection,CSS attacks, Script attacks in Java or J2ee web applications


Preventing SQL Injection,CSS attacks, Script attacks  in Java or J2ee web applications.
====================================================================

To Prevent SQL Injection,CSS attacks, Script attackes  in Java J2ee based web applicataions we had to add filter which
will inspect each and every field that is submitted to the application.
But be careful as some times this filter may change the values of some inputs.
Eg: In our test app when we added this filter all  quotes like say for name was replacye by html equivalent.
The reason is there can be some fields like name say Ram'S (with an apostrophe).The apsotrophe here would be replaced
with its html Equivalent.So one way is not allow user to enter (by haveing validation in UI)  or
if you still need to allow then exclude that field from filter.
We had to exclude  few fields here for some hidden fields which is used by JSF to maintain state on client side.
The reason was when JSF was storing the client state it had some encrypted striung with quotes and
parenthisis. The filter would think that it was sql attack and would replace the quote with html Equivalent ,
As result JSF decoding of the client state would fail with "StreamCorruptedException".


package com.test.common;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

/**
 * @author reddy
 *  This class goes through the Request parameters and looks for
 *  any suspicious inputs which could be a SQL injected or some java
 *  script some user is trying to inject.
 */

public class SqlInjectionAndXSSFilter implements Filter {
 private static Logger LOGGER = LogManager.getLogger(SqlInjectionAndXSSFilter.class);
 private static Map<String,String>  excludeFieldsMap = new HashMap<String,String>();
 
 public void init(FilterConfig config) throws ServletException {
  //Looking for sql-xss-exclusion-filter.properties
  String propertiesFilePath = config.getInitParameter("properties_file");
  if (propertiesFilePath == null || propertiesFilePath.length() == 0) {
   LOGGER.warn("The properties_file parameter in web.xml for SqlInjectionAndXSSFilter is not specified.");

  } else {
    
      //If you  want to inspect every request parameter
      Properties props = new Properties();
      try {
   props.load(getClass().getClassLoader().getResourceAsStream(propertiesFilePath));

   Iterator<Object> itr = props.keySet().iterator();   

       while (itr.hasNext()) {
        String key = (String)itr.next();
        String value = (String)props.get(key);
        LOGGER.debug("Adding key="+key +" value="+value);
        excludeFieldsMap.put(key,value);
       }

       

       //Send this map to SqlInjectionAndXSSRequestWrapper. I made it static intentionally.
       SqlInjectionAndXSSRequestWrapper.excludeFieldsMap = excludeFieldsMap;
       
            } catch (IOException e) {
                LOGGER.fatal("Could not load properties file: " + propertiesFilePath, e);
                throw new ServletException("Could not load properties file: " + propertiesFilePath);
            }
  }
    }
 
 public void destroy() {



 }



 public void doFilter(ServletRequest request, ServletResponse response,

   FilterChain chain) throws IOException, ServletException {

  chain.doFilter(new SqlInjectionAndXSSRequestWrapper((HttpServletRequest) request),

    response);

 }

 

}



sql-xss-exclusion-filter.properties
===================================
//Property file with Tokens to be excluded from our filter
//Lets Call this file as sql-xss-exclusion-filter.properties, PUT IN YOUR CLASSPATH
//The reason was when JSF was storing the client state it had some encrypted string with quotes
//and then filter would think that it was sql attack and would replace the quote which in trun would make
//jsf encoding fail with "StreamCorruptedException". As a result JSF couldnt restore client state in some cases.

# List of all fields that needs to be excluded from SqlInjectionAndXSSFilter
# Any fields thats not listed here will be inspected by the filter and if
# filter finds any thing suspicious (XSS or SQL attacks code) it will replace
# the contents.
# There are few fields like the jsf state and jsf tree which the filter should never edit
# else jsf cant restore the state and will throw streamcorrupted exceptions.
# Let the key and value be same so that we can load into map for easy operations. (I love maps for the ease of searching)

jsf_tree_64=jsf_tree_64

jsf_state_64=jsf_state_64




package com.test.common;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

/**
 * @author reddy
 * Used by the filter to remove any potential code sent as input parameter which has
 * XSS (Cross site scripting) and
 * More at :
 * http://ha.ckers.org/xss.html
 * http://www.symantec.com/connect/articles/detection-sql-injection-and-cross-site-scripting-attacks  
 *
 */

public class SqlInjectionAndXSSRequestWrapper extends HttpServletRequestWrapper {

 private static Logger logger = LogManager.getLogger(SqlInjectionAndXSSRequestWrapper.class);


 //The filter will set this map

 public static  Map<String,String>  excludeFieldsMap = new HashMap<String,String>();

 

 public SqlInjectionAndXSSRequestWrapper(HttpServletRequest servletRequest) {

  super(servletRequest);

 }



 public String[] getParameterValues(String parameter) {

  String[] values = super.getParameterValues(parameter);

  if (values == null) {

   return null;

  }

  int count = values.length;

  String[] encodedValues = new String[count];

  for (int i = 0; i < count; i++) {

   encodedValues[i] = replaceXSSAndSqlInjection(values[i],parameter);

  }

  return encodedValues;

  /*

  for (int i = 0; i < count; i++) {

   checkXSSAndSqlInjectionPresence(parameter,values[i]);

  }

  return values;

  */

 }



 public String getParameter(String parameter) {

  String value = super.getParameter(parameter);

  if (value == null) {

   return null;

  }

  return replaceXSSAndSqlInjection(value,parameter);

  //checkXSSAndSqlInjectionPresence(parameter,value);

  //return value;

 }



 public String getHeader(String name) {

  String value = super.getHeader(name);

  if (value == null){

   return null;

  }

  return replaceXSSAndSqlInjection(value,name);

 }

 

 /**

  * If its finds any XSS injection it will replace the values with html equivalent and
  * and for SQL injection it will replace few sql key words (insert, delete...etc)
  * @param value
  * @return
  */

 public static String replaceXSSAndSqlInjection(String value, String fieldName) {

  //The key and value will be same

  //Eg:jsf_tree_64=jsf_tree_64  - See sql-xss-exclusion-filter.properties

  //SO here we ignore any fields that we feel should not be inspeacted by this filter..

  String fieldToExclude = excludeFieldsMap.get(fieldName);

  if((fieldToExclude != null) &&(fieldToExclude.equalsIgnoreCase(fieldName))){

   logger.debug("The field name:"+ fieldName +" should not be inspected by SqlInjectionAndXSSFilter.");

   return value;

  }

  

  String orgValue = new String(value);

  //No < and > as it could be for some sql.

  value = value.replaceAll("<", "&lt;").replaceAll(">", "&gt;");

  //No () brackets as part of data....

  value = value.replaceAll("\\(", "&#40;").replaceAll("\\)", "&#41;");

  //Handle any apostrophe.  Can a name have this ??

  value = value.replaceAll("'", "&#39;");

  //Any java script stuff.

  value = value.replaceAll("eval\\((.*)\\)", "");

  value = value.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']","\"\"");

  value = value.replaceAll("script","");



  /*

   * This signature first looks out for the = sign or its hex equivalent (%3D).
   * It then allows for zero or more non-newline characters,
   * and then it checks for the single-quote, the double-dash or the semi-colon.
   * Detect either the hex equivalent of the single-quote, the single-quote itself or
   * the presence of the double-dash. These are SQL characters for MS SQL Server and Oracle,
   * which denote the beginning of a comment, and everything that follows is ignored.
   * See more info at
   * http://www.symantec.com/connect/articles/detection-sql-injection-and-cross-site-scripting-attacks
   * Regex for detecting SQL Injection meta-characters
   */

  value = value.replaceAll("/((\\%3D)|(=))[^\\n]*((\\%27)|(\')|(\\-\\-)|(\\%3B)|(;))/i","");

  

  /*

   * Regex for detecting SQL Injection with the UNION keyword
   *
   * (\%27)|(\') - the single-quote and its hex equivalent
   union - the keyword union
   */

  value = value.replaceAll("/((\\%27)|(\'))union/ix","");

  /*

   *

   * A typical SQL injection attempt of course revolves around the use of the single quote
   * to manipulate the original query so that it always results in a true value.
   *  Most of the examples that discuss this attack use the string 1'or'1'='1.
   *  However, detection of this string can be easily evaded by supplying a value
   *  such as 1'or2>1--. Thus the only part that is constant in this is the initial
   *  alphanumeric value, followed by a single-quote, and then followed by the word 'or'.
   *  The Boolean logic that comes after this may be varied to an extent where a generic pattern
   *  is either very complex or does not cover all the variants. Thus these attacks can be detected to a fair
   *  degree of accuracy by using the next regular expression
   * 
   *  Regex for typical SQL Injection attack

   *  /\w*((\%27)|(\'))((\%6F)|o|(\%4F))((\%72)|r|(\%52))/ix

   */

  value = value.replaceAll("/\\w*((\\%27)|(\\'))((\\%6F)|o|(\\%4F))((\\%72)|r|(\\%52))/ix",""); 

  

  //checking for the keywords and a combination of quotes with conjunctions and quotes with double pipe (||)

  value = value.replaceAll("insert|update|delete|having|drop|(\'|%27).(and|or).(\'|%27)|(\'|%27).%7C{0,2}|%7C{2}","");  

  

  //Regex for "<img src" CSS attack

  value = value.replaceAll("/((\\%3C)|<)((\\%69)|i|(\\%49))((\\%6D)|m|(\\%4D))((\\%67)|g|(\\%47))[^\n]+((\\%3E)|>)/I","");

  

  if(logger.isDebugEnabled()){

   //Lets print only if debug is enable and if the values got changed.

   //Add as safety net

   if((orgValue != null) &&(value!= null) &&(!orgValue.equalsIgnoreCase(value))){

    logger.debug(" Value was changed by Filter from :"+ orgValue);

    logger.debug("          TO:"+ value);

   }

  }

  return value;

 }
}
web.xml:
=======
In your web.xml now configure the filter
<!--  Filter for preventing cross site attacks and Sql injection attacks. -->

 <filter>
  <filter-name>SqlInjectionAndXSSFilter</filter-name>
  <filter-class>com.test.common.SqlInjectionAndXSSFilter</filter-class>
  <init-param>
   <param-name>properties_file</param-name>
   <param-value>sql-xss-exclusion-filter.properties</param-value>
  </init-param>
 </filter>
<


!-- 
 Filter for preventing cross site attacks and Sql injection attacks.
 Include all file extensions. JSF, JSP
-->
  <filter-mapping>
   <filter-name>SqlInjectionAndXSSFilter</filter-name>
   <url-pattern>*.jsp</url-pattern>   
   <dispatcher>REQUEST</dispatcher>
  </filter-mapping>
  <filter-mapping>
   <filter-name>SqlInjectionAndXSSFilter</filter-name>
   <url-pattern>*.jsf</url-pattern>   
   <dispatcher>REQUEST</dispatcher>
  </filter-mapping>


You now try to enter some value in text fields on the UI in your application. The filter will intercept and
replace the html equivalent.So if you dont want a field to be intercepted you can add those fields
in sql-xss-exclusion-filter.properties

Hope this helps. If you have better idea or approach  or if you like this article
please leave your suggestions or comments below.


Wednesday, May 30, 2012

Cross Domain JSONP ( Json with padding ) with Jquery and Servlet or JAX-WS

  • Solving Cross Domain problem using JSONP ( Json with padding ) with Jquery and Servlet JAX-WS
  • or Cross-domain communications with JSONP
  • or Cross domain jquery or cross domain Ajax
  • or java - Sending JSONP vs. JSON data
  • or JSONP javascript or Java JSONP

    Well there are several techniques to address cross domain problem. Here are few.

1. Using CORS ( Cross-Origin Resource Sharing ) where in we modify the repsonse header
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: http://test.com:8080 http://foobar.com
The asterisk permits scripts hosted on any site to load your resources; the space-delimited lists limits access to scripts hosted on the listed servers.
Problem is CORS may not work in all browsers ( See: http://en.wikipedia.org/wiki/Cross-origin_resource_sharing)

2. Other option is to use some server side re-direct of the request to a servlet or a php script on your  own domain which in trun calls third party web site.
But at times we may not have this option to implment a servlet or PHP script which we can call on our domain.

3.If the third party url that you are invoking supports JSONP response then all browsers work without complaining


What is JSONP ?

- JSONP - JSon with padding. It means to your JSON response we will append the callback method name.
eg: Let say your JSON response is  {"totalInterestPmtAmt":5092.79,"totalPmtAmt":15092.79}
and lets assume the callback method name that was sent in request was  getPayment JSONP Response will be :getPayment( {"totalInterestPmtAmt":5092.79,"totalPmtAmt":15092.79} )
(However if you dont give call back method name Jquery dynamically generates a method name sends in request and when response comes back  it will use that method name to call it ...Read further everything will make sense...)

Since all browsers allow injecting java scripts from third party websites without complaining (that they are cross domain) in JSONP the response we need, is wrapped as a Java script method there by fooling the browser to think its as java script.
<script> tag is less restrictive hence in JSONP you got the same JSON response with a call back method added to it. So browser was happy that it was just injecting some java script function and did not complain. Sweet !!!

Enabling JSONP Server side using Servlet as wrapper for JAX-WS webservice
--------------------------------------------------------------------------------------------------
I had an exisitng JAX-WS webservice which returns  JSON response. Most time this webservice is invoked by some other server component. But we had a client who had to call using Ajax and browser started complaining that we are accessing cross domain url.

Let say my webservice url was:
http://abcd.com/Calculation/CalculationWebServiceImpl.wsdl

And the caller is on
http://xyz.com/displayRate.html ---> this page has ajax call. (will show later )

So all we did was added a servlet called CalulationServlet which had the URL
http://abcd.com/Calculation/CalculationServlet

//SERVLET:
package com.rama.test.jsonp;
public class CalculationServlet extends HttpServlet{
   // NOTE: JSONP works only iwth GET request

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        processRequest(request, response);
    }

 //JSONP cannot work for PSOT.....So dont implement.
 protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
     String amount = request.getParameter("amount");
     String rate= request.getParameter("interestRate");
     BigDecimal  principal = new BigDecimal( amount);
     BigDecimal  interestRate = new BigDecimal(rate);        

//If are using Jquery each time the call back method name will be auto generated.// but Parameter name can be controlled
// most often all exmaples I have seen use "callback" as request parameter
//eg: your call method name can be like.  jsonp1337622713385
String callBackJavaScripMethodName = request.getParameter("callback");


//Here called my webservice as if like any other java client.      
//callWebservice -- Takes two input param and returns response as JSON    

 String jsonResponseData =   callWebservice(principal,interestRate);
// so it will look like  
//jsonp1337622713385 ( {"totalInterestPmtAmt":5092.79,"totalPmtAmt":15092.79} );
String jsonPoutput = callBackJavaScripMethodName + "("+ jsonResponseData + ");";

//Write it to Response  

   response.setContentType("text/javascript");
   PrintWriter out = response.getWriter();
   out.println(jsonPoutput);
 }    
}
NOTE: Its very important that the response content type is set to   text/javascript
Now I edited the web.xml that was already there for my webservice I added the following entry

  <servlet>
   <description>This Servlet  was added to support JSONP protocol to resolve cross domain scripting problem
    </description>
        <display-name>CalculationServlet</display-name>
       <servlet-name>CalculationServlet</servlet-name>
        <servlet-class>com.rama.test.jsonp.CalculationServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CalculationServlet</servlet-name>
       <url-pattern>/CalculationServlet</url-pattern>
    </servlet-mapping>
Now my servlet can be invoked using the url
http://abcd.com/Calculation/CalculationServlet?amount=10000  (as the web app name is Calculation)

JQuery to invoke:
Inside the any html page assuming you have Jquery included
<SCRIPT src="scripts/jquery.js"></SCRIPT>

<SCRIPT>

function callWebService() {
///the callback=? the questsion mark will be replace by JQuery with 
//some method name like jsonp1337622713385
//So when response comes back the response is packed inside this method.
//Thats all we did in server side. The callback method name is dynamically 
//generated by JQUERY.


var calcServcURLValue = 'http://abcd.com/Calculation/CalculationServlet?amount=10000&callback=?';
    $.ajax({ 
            url: calcServcURLValue , 
            type: 'get',  /* Dont use post it JSONP doesnt support */
            dataType: 'jsonp',
            success: function(res) {
             alert('Yahoo!!!! We got the Response back')
             processResponse(res);
          }
          , 
            error: function(e , msg){ 
                processError(e,msg);
            }
    }); 
 }


function processError(e , msg){
    alert('Call to Service Failed');
}


//The res object you get is a JSON object 
// Since the JSON response is 
// {"totalInterestPmtAmt":5092.79,"totalPmtAmt":15092.79}
//yes the call back method name will 
//be removed by Jquery isn that neat 

function processResponse(res){
    alert('totalInterestPmtAmt='+ res.totalInterestPmtAmt);
    alert('totalPmtAmt='+ res.totalPmtAmt);
}

</script>

//Add some html and a button to call function callWebService( ) you should be all set.
so this work around will save you from CROSS Domain Issues.

Thursday, March 15, 2012

Calling Stored procedure using hibernate.

Invoking a ORACLE Stored Procedure using hibernate:

There was requirement where we had to select and update a given column or row in one atomic operation and return the results of the updated row. So Oracle has support for this with the RETURNING INTO CLAUSE.
Eg: Example I wanted to update check number and here is the statement to select and update at once.
UPDATE MY_BANK_ACCOUNT  SET   LAST_CHECK_NO = LAST_CHECK_NO+1,
UPDATED_DT = SYSDATE   WHERE INSTITUTION_BANK_ID= 101
RETURNING LAST_CHECK_NO INTO v_next_check_number;
 where v_next_check_number is variable.

Table : MY_BANK_ACCOUNT used in this example
-------------------------------------------
INSTITUTION_BANK_ID            NOT NULL NUMBER INSTITUTION_ID                 NOT NULL NUMBER ROUTING_NUMBER                 NOT NULL VARCHAR2(50) ACCOUNT_NUMBER                 NOT NULL VARCHAR2(50) LAST_CHECK_NO                  NOT NULL NUMBER FRACTION_CODE                  NOT NULL VARCHAR2(50) ACTIVE_STATUS_IND              NOT NULL VARCHAR2(1) CREATED_BY                     NOT NULL VARCHAR2(50) CREATED_DT                     NOT NULL DATE UPDATED_BY                              VARCHAR2(50) UPDATED_DT                              DATE 
So here is the Stored procedure to update and return the Row:

CREATE OR REPLACE PROCEDURE  PROC_GET_NEW_CHECK_NUMBER(
p_cursor out sys_refcursor,p_bankid  IN NUMBER, p_application_name IN VARCHAR ) AS
v_next_check_number      NUMBER;
BEGIN    
    UPDATE  
MY_BANK_ACCOUNT  
        SET   LAST_CHECK_NO = LAST_CHECK_NO+1,
              UPDATED_DT = SYSDATE,
              UPDATED_BY = p_application_name
        WHERE INSTITUTION_BANK_ID= p_bankid 
        RETURNING LAST_CHECK_NO INTO v_next_check_number;
    --COMMIT;  Dont commit here as this stored proc is used in Global Txn so 
    -- we get  error which says COMMIT is not allowed in a subordinate session

    -- In case you are not using Global Txn (Like I do in J2ee) use commit here. 
    OPEN p_cursor for
     SELECT  INSTITUTION_BANK_ID, INSTITUTION_ID, ROUTING_NUMBER, ACCOUNT_NUMBER,

        /* copy  the value from local variable that we stored during update  */
         v_next_check_number AS LAST_CHECK_NO,
         FRACTION_CODE,  ACTIVE_STATUS_IND, CREATED_BY, CREATED_DT,

         UPDATED_BY,  UPDATED_DT    FROM 
MY_BANK_ACCOUNT  
    WHERE INSTITUTION_BANK_ID=p_bankid; 
END 
PROC_GET_NEW_CHECK_NUMBER ;
/

NOTE: Hibernate expects the first argument always to be the Cursor that you will be returning. IT HAS TO BE THE FIRST ARGUMENT. I uses SYS Ref cursor you can use re cursor as well.

In case you want to test your stored procedure in SQLPLUS use the below code.

SET SERVEROUTPUT ON;
DECLARE
   v_cur SYS_REFCURSOR;  
   v_inst_bank_id        NUMBER;    
   v_institute_id        NUMBER;    
   v_routing_number         VARCHAR2(50);
   v_account_number         VARCHAR2(50);
   v_next_check_number      NUMBER;     
   v_fraction_code          VARCHAR2(50);
   v_active_status_ind      VARCHAR2(1);
   v_created_by        VARCHAR2(50);
   v_created_dt        DATE;    
   v_updated_by        VARCHAR2(50);
   v_updated_dt        DATE;
BEGIN
   -- HERE THE BANK ID WE ARE USING IS 1. CHANGE IT ANY VALUE YOU WANT.    
  PROC_GET_NEW_CHECK_NUMBER(v_cur,1,'MytestAPP');  
  COMMIT; -- Caller must commit else you will keep locking that row. 

--  (Since my stored doesn't commit as I am using it in Global TXN. If you have commited in side stored proc ignore this commit )
  LOOP
    FETCH v_cur INTO v_inst_bank_id,v_institute_id,v_routing_number,v_account_number,
             v_next_check_number,v_fraction_code,v_active_status_ind,
             v_created_by,v_created_dt,v_updated_by,v_updated_dt;
    EXIT WHEN v_cur%NOTFOUND;
     dbms_output.put_line( 'New Check Number =' || v_next_check_number  ||' For Bank Id='|| v_inst_bank_id);
     dbms_output.put_line( 'Routing number='|| v_routing_number ||' Account num='|| v_account_number);
  END LOOP;
  CLOSE v_cur;
END;


Now lets Map this Stored procedure to Java class in HBM file.
MyBankAccount.hbm.xml:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.test.reddy.dao.model.MyBankAccount" table="MY_BANK_ACCOUNT">
        <id name="institutionBankId" type="java.lang.Long">
            <column name="INSTITUTION_BANK_ID" />
        </id>
        <property name="institutionId" type="java.lang.Long">
            <column name="INSTITUTION_ID" />
        </property>
        <property name="routingNumber" type="string">
            <column name="ROUTING_NUMBER" />
        </property>
        <property name="accountNumber" type="string">
            <column name="ACCOUNT_NUMBER" />
        </property>
        <property name="lastCheckNumber" type="java.lang.Long">
            <column name="LAST_CHECK_NO" />
        </property>
        <property name="fractionCode" type="string">
            <column name="FRACTION_CODE" />
        </property>
        <property name="activeStatusInd" type="string">
            <column name="ACTIVE_STATUS_IND" />
        </property>
        <property name="createdBy" type="string">
            <column name="CREATED_BY" />
        </property>
        <property name="createdDT" type="java.util.Date">
            <column name="CREATED_DT" />
        </property>
        <property name="updatedBy" type="string">
            <column name="UPDATED_BY" />
        </property>
        <property name="updatedDT" type="java.util.Date">
            <column name="UPDATED_DT" />
        </property>
    </class>



    <!--
        The first argument of the stored procedure is actually an OUT parameter from Oracle. 

        So map how the cursor will be interpreted by hibernate. Dont mess here.
    -->
    <sql-query name="MyBankAccount.getNextCheckNumber"    callable="true">
        <return class="com.test.reddy.dao.model.MyBankAccount">
            <return-property name="institutionBankId" column="INSTITUTION_BANK_ID" />
            <return-property name="institutionId" column="INSTITUTION_ID" />
            <return-property name="routingNumber" column="ROUTING_NUMBER" />
            <return-property name="accountNumber" column="ACCOUNT_NUMBER" />
            <return-property name="lastCheckNumber" column="LAST_CHECK_NO" />
            <return-property name="fractionCode" column="FRACTION_CODE" />
            <return-property name="activeStatusInd" column="ACTIVE_STATUS_IND" />
            <return-property name="createdBy" column="CREATED_BY" />
            <return-property name="createdDT" column="CREATED_DT" />
            <return-property name="updatedBy" column="UPDATED_BY" />
            <return-property name="updatedDT" column="UPDATED_DT" />
        </return>
        { call PROC_GET_NEW_CHECK_NUMBER(?,:bankId,:appName) }
    </sql-query>

</hibernate-mapping> 


Please create a MyBankAccount.java file with above properties
package  com.test.reddy.dao.model;
public class MyBankAccount implements Serializable {
   private Long institutionBankId;
    private Long institutionId;
    private String routingNumber;
    private String accountNumber;
    private Long lastCheckNumber;
    private String fractionCode;
    private String activeStatusInd;
    private String createdBy;
    private Date createdDT;
    private String updatedBy;
    private Date updatedDT;

//PLEASE GENERATE GETTERS and SETTERS - Left it intentionally though you need add getter and setters.

}



Calling your Stored procedure now using Java code:
public static void main(String[] args)throws Exception
        System.out.println("Calling test cursor");
        // Please get hibernate session 
        Session session = HibernateUtil.getSession();
        //Clear any previously loaded Stuff always Reload fresh from DB.
        session.clear();
        //Its just another SQL.
        Query qry = session.getNamedQuery("MyBankAccount.getNextCheckNumber");
        qry.setLong("bankId",1);
        qry.setString("appName","MyTestApp");
        Object result = qry.uniqueResult();
        System.out.println(result);
        System.out.println(((MyBankAccount)result).getLastCheckNumber());
    }


PROBLEMS I FACED:
We upgraded from Oracle9 to Oracle 11.2.0.1.0 . The OracleTypes class in 11g has been moved (I guess after Oracle 9) to a new package from "oracle.jdbc.driver.OracleTypes"  to "oracle.jdbc.OracleTypes" .
So I was getting the below error
  • Caused by: org.springframework.orm.hibernate3.HibernateSystemException: Problem while trying to load or access OracleTypes.CURSOR value; nested exception is org.hibernate.HibernateException: Problem while trying to load or access OracleTypes.CURSOR value.
org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:679)
org.springframework.orm.hibernate3.HibernateAccessor.convertHibernateAccessException(HibernateAccessor.java:412)

So I had to upgrade from  Hibernate 3.1.jar to  hibernate-core-3.3.2.GA.jar. This may also require
- javassist-3.9.0.GA.jar , slf4j-api-1.6.4.jar and slf4j-log4j12-1.6.4.jar

Inside hibernate-core-3.3.2.GA.jar source code they check first for
ORACLE_TYPES_CLASS_NAME = "oracle.jdbc.OracleTypes";
if  not found then they look for the older version.
DEPRECATED_ORACLE_TYPES_CLASS_NAME = "oracle.jdbc.driver.OracleTypes";
(You don't need to worry about this. We can trust Gavin King the Guru of Hibernate , just use hibernate-core-3.3.2.GA.jar)

Also note that hibernate Dialect Should be set to
hibernate.dialect  ===>  org.hibernate.dialect.Oracle10gDialect 
or org.hibernate.dialect.Oracle9iDialect  or org.hibernate.dialect.Oracle8iDialect in hibernate.cfg.xml or corresponding spring xml file which ever approach you are using.

Please do not use org.hibernate.dialect.OracleDialect and  org.hibernate.dialect.Oracle9Dialect (no i ) - its deprecated.


  • Then on server start up the application started throwing XML Parsing exceptions.
 caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ORADataSource' defined in class path resource [spring-config/sample-dao-application-context.xml]: Invocation of init method failed; nested exception is org.springframework.beans.factory.support.BeanDefinitionValidationException: Couldn't find an init method named 'JndiObjectFactoryBean' on bean with name 'ORADataSource'
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1420)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)


After several hours of removing code and adding as few hbm files to the application I found that a common hbm file that had few properties defined in another file was causing this.
My hibernate File had some thing like
 <!ENTITY CommonProperties SYSTEM "file://hibernate-mapping/CommonProperties.hbm.xml">
With hibernate-core-3.3.2.GA.jar this doesn't work. So change the file to classpath as shown below.
<!ENTITY CommonProperties SYSTEM "classpath://hibernate-mapping/CommonProperties.hbm.xml">

  • I was using a older JDBC driver so after fixing the above error I was getting
 org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute query; SQL [{ call PROC_GET_NEW_CHECK_NUMBER(?,?,?) }]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute query
  at com.ibm.ejs.jms.listener.ServerSessionDispatcher.dispatch(ServerSessionDispatcher.java:44)
        at com.ibm.ejs.container.MDBWrapper.onMessage(MDBWrapper.java:100)

java.sql.SQLSyntaxErrorException: ORA-00900: invalid SQL statement

    To fix this I upgraded my JDBC driver to the correct version that matches  the Oracle installation. So in my case I used ojdbc6_11g_11_2_0_1.jar since my Oracle instance :Oracle 11.2.0.1.0

  •   Finally when I added the above as part of an EJB bean which is container  managed it started throwing errors 
Exception: org.hibernate.TransactionException: Could not find UserTransaction in JNDI [java:comp/UserTransaction]
org.hibernate.transaction.JTATransactionFactory.getUserTransaction(JTATransactionFactory.java:173)
org.hibernate.transaction.JTATransactionFactory.createTransaction(JTATransactionFactory.java:149)Thanks to this Article
http://www.ibm.com/developerworks/websphere/techjournal/0609_alcott/0609_alcott.html
If its  EJB and is using Container manager transaction then use
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</prop>
DO NOT USE
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</prop>
its for BMT - Bean manager Transaction . Also when you use BMT Hiberenate expects this in hibernat configuration file.
<prop key="jta.UserTransaction">java:comp/UserTransaction</prop>
And finally the stored procedure worked.
Well I added all the errors that I got and a fix to it as there were not too many threads on few topics and also I was trying to upgrade hibernate and oracle at same time so thought it would help some one out there.


Wednesday, September 21, 2011

Selenium 2 or Webdriver for automation of test cases.
======================================
Selenium2 
WebDriver
Page Objects
Test Automation
Java testing automation
Automating Testing.
KEY WORDS: selenium 2 tutorial in java or Web driver tutorial in java or selenium webdriver tutorial

Recently we have automated our application using selenium 2.0 /webdriver and the out come has been very postivie.We have externalized all data that needs to be entered int our app to be read from XLS sheet and using apache POI we are reading this data and drive the application using Selenium 2.0 or Webdriver.

We are very impressed they way selenium has been developed and the ease of use.
The only difficult part was that we have lot of popovers/popups in our application and to get handle on each of these it took a while. Over all its been great.

We are using the Java version of selenium driver.

I am not explaining basic examples instead will share some lessons that we learn when dealing with complex pages , waiting on asynchronous responses, waiting on page loads

(with out hard coding sleep time outs )  and dynamically checking when a page load as completed.

For basic example see the following link .
http://seleniumhq.org/docs/03_webdriver.html

You can execute the same example with Chrome, IE , Firefox or browser less (HTMLUnit Driver). I have tried HTMLUNIT driver and had less luck though  I was able to execute

same test cases using Chrome/IE/Firefox drivers


USING DIFFERENT DRIVERS:
=======================
WebDriver driver = new ChromeDriver();  ====> Chrome
WebDriver driver = new FirefoxDriver();   =====> Fire Fox
WebDriver driver = new InternetExplorerDriver();  ====  IE or Internet Explorer

NOTE: To excuete  on chorme u need to download a plugin from 
ttp://code.google.com/p/chromium/downloads/list
and set the following system property
System.setProperty("webdriver.chrome.driver","drivers\\chromedriver.exe");
(For Fire fox and IE they come with jars)

HTMLUnitDriver  (Will run tests without launching browser by sending HTTP requests)
===========
WebDriver driver = new HtmlUnitDriver(BrowserVersion.INTERNET_EXPLORER_8);
((HtmlUnitDriver)driver).setJavascriptEnabled(true);  ============> If not java script will not be excuted.
driver.manage().timeouts().setScriptTimeout(10,TimeUnit.SECONDS);  ====> any script if it takes more than 10 seconds time out.



you need the following selenium jars  in addition other common jars
selenium-java-2.4.0-srcs.jar
selenium-java-2.4.0.jar

Please download from
http://code.google.com/p/selenium/downloads/list
(Look for selenium-java-2.4.0.zip  or latest version )

Jars I have included in my project :
------------------------------------------------
apache-mime4j-0.6.jar               
cglib-nodep-2.1_3.jar
commons-codec-1.4.jar               
commons-collections-3.2.1.jar
commons-io-1.4.jar                  
commons-lang-2.4.jar
commons-logging-1.1.1.jar           
cssparser-0.9.5.jar
guava-r08.jar                       
hamcrest-all-1.1.jar
htmlunit-2.8.jar                    
htmlunit-core-js-2.8.jar
httpclient-4.0.2.jar                
httpcore-4.0.1.jar
httpmime-4.0.1.jar                  
jna.jar
json-20080701.jar                   
junit-4.9b2-src.jar
junit-4.9b2.jar                    
junit-dep-4.8.1.jar
nekohtml-1.9.14.jar                 
sac-1.3.jar
selenium-java-2.4.0-srcs.jar  <============== Selenium jars     
selenium-java-2.4.0.jar <============== Selenium jars     
serializer-2.7.1.jar                
testng-5.14.1.jar
xalan-2.7.1.jar                     
xercesImpl-2.9.1.jar
xml-apis-1.3.04.jar


PAGE OBJECTS:
=============
They use a design pattern called Page objects in selenium testing. In layman terms as I understand its  java class which represents a particular page in your application.

(More: http://code.google.com/p/selenium/wiki/PageObjects)

Eg: Say you have an html/jsp/JSF page called EmployeeInfo.jsf/EmployeeInfo.jsp/EmployeeInfo.html
and  let says they have the following fields

<html>
    .... //all other html stuff

    //TITLE for the page
    <span id="employementInfoTxt">Employee Information</span>

    <input id="fname"  type="text" />
    <input id="lname"  type="text" />
    <input id="empStatus"  value="Employed" type="checkbox" />
    <input id="nextButton"  type="button" />
</html>

We can have a page object  (a java class or bean which gives an easy way for us to interact with fields in the page )

public class EmploymentInfoPage{

    private WebDriver driver;
      public EmploymentInfoPage( WebDriver driver){
         this.driver = driver;
    }
   
    //<span id="employementInfoTxt">Employee Information</span>
    @FindBy(how = How.ID, using = "employementInfoTxt")
    private WebElement pageTitle;
   
    @FindBy(how = How.ID, using = "fname")
    private WebElement firstName;

    @FindBy(how = How.ID, using = "lname")
    private WebElement lastName;

    @FindBy(how = How.ID, using = "empStatus")
    private WebElement employmentStatus;

    @FindBy(how = How.ID, using = "nextButton")
    private WebElement next;

   
    public void setFirstName(String firstNameStr) {
        //As good as you typing the keys on the text field
        this.firstName.sendKeys(firstNameStr);
    }
   
    public void setLastName(String lastNameAsStr) {
        this.lastName.sendKeys(lastNameAsStr);
    }

    public void setEmploymentStatus() {
        //Say you are employed...so check the check box
        this.employmentStatus.click();
    }
   
    public void clickNext() {
        this.next.click();
    }
}
Look at the WebElement class ( whethere its text or check box or radio button or button all elements are treated as Webelements.
NOTE:
The annotation @FindBy will look for a element and you can specify if the look up should be by ID or Name or LINK_TEXT or Partial link.
These are the options avaliuable on How
public enum How {
  CLASS_NAME,
  CSS,
  ID,
  ID_OR_NAME,
  LINK_TEXT,
  NAME,
  PARTIAL_LINK_TEXT,
  TAG_NAME,
  XPATH,
}



Now You can test your page with the following class.
====================================

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.PageFactory;

public class TestWebDriver {

   
    public static void main(String[] args) {
       
        System.setProperty("webdriver.chrome.driver","drivers\\chromedriver.exe");
        WebDriver driver = new ChromeDriver();
        //You can point it to a html page o your local as well.
        EmploymentInfoPage empInfoPage = new EmploymentInfoPage(driver);
        driver.get("http://localhost:9080/test/EmployeeInfo.jsf");
        //Load this pageObject with
        PageFactory.initElements(driver,empInfoPage);
       
        //EmploymentInfoPage employmentInfoPage =PageFactory.initElements(this.getDriver(),EmploymentInfoPage.class);
        //WebDriver driver = new FirefoxDriver();
        //WebDriver driver = new InternetExplorerDriver();
        //WebDriver driver = new HtmlUnitDriver(BrowserVersion.INTERNET_EXPLORER_8);
        //((HtmlUnitDriver)driver).setJavascriptEnabled(true);
       
        empInfoPage.setFirstName("Anna");
        empInfoPage.setLastName("Hazare");
        //Checks the check box..
        empInfoPage.setEmploymentStatus();
        //will take you to nect page..
        empInfoPage.clickNext();
    }
}






CASE1 : I have popups how to get handle on them and close
======================================
Solution: Call this method in the Page object which represenst the Main page

private void closePopup(WebDriver driver, int waitTime) {

            //Get handle on main page....
            String mainWindowHandle = driver.getWindowHandle();
            //List all windows           
            Set<String> windowHandles = driver.getWindowHandles();
            System.out.println("Main window:"+ mainWindowHandle);
            for( String window:windowHandles){
                if(mainWindowHandle.compareToIgnoreCase(window) != 0){
                    //Some other window other than main window so it must be pop up
                    System.out.println("Closing window:"+ window);
                    driver.switchTo().window(window).close();
                }
            }
       
        //Switch back to main window and re initialize the values
        driver.switchTo().window(mainWindowHandle);
        //Re load the main page....
        PageFactory.initElements(driver,this);
    }

On the same basis you can even operate on any pop up window.

CASE 2:  I have a I frame in a main page within the ifram they lauch a popup so iframe doesnt have any code but launches a div is opened .
how do I close or have handle on this ( We have Jenia popups in our JSF applications . We used the below approach )
======================================
Solution:

Here is some code snippet where there is popu thats launched through an i frame and our goal is to get handle on the popup and click
the next button on pop up.
protected void clickConfirmationPopup() {
        //We need this for the pop over to appear ( TODO: Can we add some conditional check ???)
        int maxRetries = 5;
        int retryCount = 0;
        while(retryCount < maxRetries){
            try{
                //When the page loads there are frames on the page and for some reason the
                //last frame (that is blank) is getting focus. This call to switch to the default Content
                //is to set the focus back to the main page.
                this.getDriver().switchTo().defaultContent();
                this.getDriver().switchTo().activeElement();
                //Now we should have our control in Iframe
                //System.out.println("PageSource:"+ this.getDriver().getPageSource());
                //Click on pop over button.
                  //
                this.getDriver().findElement(By.id("form1:NextButtonOnPopover")).click();
                //If success lets exit
                break;
            }catch(NoSuchElementException exp){
                retryCount++;
                System.out.println("Failed to find buttont on pop over. " +
                        "May be the pop ovber did not appear in time. Count="+maxRetries);
                System.out.println("====================================");
                //lets try again
                sleep(2000);
                //Lets try again
                if(maxRetries == retryCount){
                    //no more fun to continue again.
                    throw exp;
                }
            }
        }
    }


CASE 3: How to pick a particulare value in a select drop down based on the values of each element (Not dispaly name)
======================================
SOLUTION:
    public void setDropDownValue(WebElement targetElement, String value) {

        List<WebElement> allOptions = targetElement.findElements(By.tagName("option"));
        boolean elementFound = false;

        for (WebElement option : allOptions) {
            //Read the Value attribute for this elemen and see if this what we want   
            if (value.equals(option.getAttribute("value"))) {
                elementFound = true;
                option.click();
                break;
            }
        }

        if (!elementFound) {
            throw new NoSuchElementException("Element: " + targetElement.getTagName() + " value: " + value);
        }
    }


CASE 4 : How to wait for a page to load or how do I know when a page is loaded ?
======================================
SOLUTION:  In the app that i tested we have title page for each page. so when we load each page the page object for that taget page will have String that it will looks for

comparison. But how long to wait to know if the page is loaded. So here is the condition you can use.

Let say you have LoginPage and once you click next on login page you will go to profile page.

//Base class which all pages can use.
abstract Class  BasePage{
   
    private WebDriver driver;
   
    //Max time to wait on page checking the condition
    private static final int DEFAULT_MAX_PAGE_LOAD_SECONDS = 45;
   
    //Check once in every 2 seconds
    private static final int DEFAULT_MILLI_SECONDS_TO_SLEEP_BEFORE_POLLING = 2000;

   
      //Overload in derived class. Tell if there is a some condition
             // that we need to wait for this page.
    abstract public boolean shouldWaitForPageLoad();

    //So what is the condition that needs to be met.
    abstract public boolean isPageLoaded() ;


    public WebDriver getDriver() {
        return driver;
    }

    public void setDriver(WebDriver driver) {
        this.driver = driver;
    }

    protected void waitForCondition(ExpectedCondition<Boolean> expectedCondition) {
        waitForCondition(expectedCondition, DEFAULT_MAX_PAGE_LOAD_SECONDS);
    }

    protected void waitForCondition(ExpectedCondition<Boolean> expectedCondition, int seconds) {
        Wait<WebDriver> w = new WebDriverWait(this.driver, seconds,DEFAULT_MILLI_SECONDS_TO_SLEEP_BEFORE_POLLING);
        w.until(expectedCondition);

    }

    protected void waitForPageLoad() {
        if (shouldWaitForPageLoad()) {
            try {
                PageTransitionExpectedCondition pageTransitionExpectedCondition = new PageTransitionExpectedCondition(this);
                this.waitForCondition(pageTransitionExpectedCondition);
            }
            catch ( Throwable t ) {
                System.out.println("Error Occured during wait:" +t.getCause());
                t.printStackTrace();
            }
        }

    }

}

//Here is the condition checking class
public class PageTransitionExpectedCondition implements ExpectedCondition<Boolean> {

    private Object targetPage = null;
   
    //Are you can use the base class name which all Page object will extend
    //Assuming you have the method isPageLoaded() in the base class and over loaded in sub classes.
    public PageTransitionExpectedCondition( BasePage targetPage) {
        this.targetPage = targetPage;
    }
   
}

//Intentionally left getter and setter out in the code snippet here.
Class LoginPage extends  BasePage {
       
   

    public boolean isPageLoaded() {
    //Ok nothing much here. The first page we are confident will load and
    //We dont want to check any condition. Please next class (ProfilePage)
        return true;
    }
   
    public boolean shouldWaitForPageLoad(){
        //Dont wait for this page as this page has no stuff in it and will load in no time
        return false;
    }


    protected WebElement getNextButton(){
        return this.nextButton;
    }

 //Here we click the next button and wait for profile page to load...So there is no sleep. as such it keeps checking for
             //specified time interval if pga eloads before that it returns..
    public ProfilePage clickNext() {
       
        this.getNextButton().click();

        //Request to Intialize the elements
        ProfilePage profilePage = PageFactory.initElements(this.getDriver(), ProfilePage.class);

        //Call the Wait method thats in base class of every page object   
        profilePage.waitForPageLoad();

        //100% guarnteed your page is loaded here
        return profilePage;
    }

}


//Profile page
Class ProfilePage extends BasePage {
   
    ///This is the title on the page
    private String defaultTitle = "Login Home";
   
    //Element which holds the title on the page
    @FindBy(how = How.ID, using = "form1:financialInfoTxt")
    private WebElement title;

    @FindBy(how = How.ID, using = "form1:nextButton")
    private WebElement nextButton;
   
    public boolean isPageLoaded() {
        boolean isPageLoaded = false;
        isPageLoaded = this.getTitleText().equals(this.getDefaultTitle() );
        return isPageLoaded;
    }

    public boolean shouldWaitForPageLoad(){
        //We need to wait for this page
        return true;
    }

}

So you can apply to each page and when you click on one page and before going to next page you can wait as shown above.


CASE 5:   How do I read a protion of text on a page (eg: I need to get a pin on page which is generated randomly and thats displayed and enter that in another text field)
======================================
Solution :
I have page where the pin number is randomly generated and each time we need to pick the pin and enter in to a text field.
This pin gets generated randomly.

Let Say the Page is Authentication page. Let say it has DIV Section where the pin is displayed and a text field where we need to type the pin thats generate and
then click on the next button.

Class  AuthenticationPage{

    @FindBy(how = How.ID, using = "form1:nextButton")
    private WebElement nextButton;
   
    @FindBy(how = How.ID, using = "securityDiv")
    private WebElement pinHoldingDiv;
   
    //Text field where we need to enter pin
    @FindBy(how = How.ID, using = "form1:authentify:password")
    private WebElement pin;
   

    public String getPin() {
        String pin = null;
        List<WebElement> paragraphs = pinHoldingDiv.findElements(By.tagName("p"));
        for (WebElement paragraph : paragraphs) {
           
            //Ok the Pin is with a paragraph withe text like
            // "Pin:23987 "   
            if (paragraph.getText().startsWith("Pin:") ) {
                //Get the text after String  "Pin:"
                pin = paragraph.getText()..split("Pin:")[0];
                break;
            }
        }
        return pin;
    }

}

Sunday, July 17, 2011

SCEA 5
SCEA 5 part 3 Essay
SCEA 5 part 3 EXAM
Oracle Certified Master PART3 EXAM
Java EE 5 Enterprise Architect PART 3 EXAM
OCMJEA PART 3
OCMJEA 5 PART 3


SCEA 5/
OCMJEA 5
-PART3 - Essay Exam

Earlier we could take part 3 before submitting the part-2 assignment to oracle but now after September 1st 2011 we need to upload part-2 assignment in pearsonvue.com/oracle and then it will allow you to book for part 3 exam.

The part 3 will be based on what you have done in part 2 and why you choose a particular frame work what was the reason etc.
I will list out some topics which if you can correlate to your assignment you will be able to answer most questions in Part3 essay exam.

I personally had prepared notes for each of the questions.
Most importantly make sure you relate this questions to the assignment and ask your self how you have handled in your design.
  1. Why have u chosen framework If any If not why not ?
  2. What technology u have used in presentation and business tier why ?
  3. Set of design patterns on which layer and why ?
  4. Security (network security and application security)
  5. what changes you suggest or how will you handle if the volume increases ?
  6. How you have handled security threats ?
  7. Why you choose EJBS if not why ?
In general prepare for the following.
( I guess I got these below questions from some other blog)
1) How does your design handle Scalability?
2) How does your design handle performance?
3) How does your design handle security?
4) How does your design handle Reliability?
5) How does your design handle Availability?
6) How does your design handle Extensibility?
7) How does your design handle Manageability?
8) How does your design handle Maintainability?

Each of the below question also ask , "Why did you choose?"

1) How does your design support session/state handling?
2) How does your design handle persistence?
3) How does your client tier talk to business tier?
4) How does your design handle Qos 5 Sec in peak time?
5) How does your design handle transactions?
6) How does your design handle authentication and authorization?


I gathered some notes in general for any application which helped a lot. Here are some tips for the above questions.
1) How does your design handle Scalability?
- Scalability by deploying apps on mutiple clusters if Required....??? EXPAND more on this. , The business components and presentation can be deployed on seperate servers if required which supports Scalability.
- Also stateless beans can be more easily load balanced across clusters.
- Use connection pooling for any data base connections to improve Scalability.
- Application is designed to be deployed on mutiple srevers which can be clustered it supports bothe vertical and horizontal scaling.
2) How does your design handle performance?
- One way to improve performance is to reduce the amount of data passed between components. So whereever possible between layers presentation<->business<->Data access layer send or receive only required information and use Data transfer Objects (DTO).
- Use Fast lanereader when browsing the catalog or products as the data is read only and using fast lane reader we can directly access the data using JDBC components.
The improved performance with fast lane reader is due to the fact that the component reads data in a form in which we wnat to use it. Using entity beans will be an over head in such cases.
- Using Service locator to improve performance.Any lookup for remote object (In case if we want to deploy business components on a different server) can be cached and we can eliminate redundant lookups which improves performance.
- If the EJBS are on Same server use Local Interfaces instead of remote interfaces.
- Using Busines Delegate pattern to reduce the number of round trips between presentation and Business logic layer.
- Use connection pooling for any data base connections to improve performance.
- Also the request across server will be evenly distributed by the load balancer to ensure good utilization of resources.

3) How does your design handle security?
- Using HTTPS for all external connections (Explain more)
- The servers itself will be within a DMZ (De militarized Zone)
- For JMs communicataion there are few options.
- Enabling JMS Provider authentication and access control
- JMS Queues and Topics protection, so that the desinations are available for access to privileged applications
- JMS Message-level (Using Encryption and Digital signatures) and Transport-layer security (Using SSL).
These options depends upon JMS provider and not specified by JMS standards.


4) How does your design handle Reliability? (????????????????? correct the numbers here.)
- We have two load balancer so even if one goes down other load balancer can pick and serve the requests.
- If one of the server goes down the loan balancer will ensure the new request will be routed to a server that is running.
- We have total Four clusters on which the application is running and two Hot stand by Databases.
- Session migration will be enabled so that if one server goes down the user will still be able to continue his shopping without any problems as the session will be migrated to the server thats up and running.


5) How does your design handle Availability?
- Application is designed for high avaibility. This is made possible by having two load balancers so that if one goes down the other load balancer will serve the requests/
- We have two clusters each with two nodes and each node can have multiple servers. To start with, each node has one server.
Since Cluster itself is on a seperate physcial machine at any given point of time we will have a server up and running all times even if the physcial machine has issues

6) How does your design handle Extensibility?
- The applicataion is designed with seperation of concerns- Presentation layer, Business layer, Data access layer.
Each layer is loosely coupled with each other with good usage of design patterns, interfaces and best practices of Object oriented design like encapsulation, inheritance.
So any change to sub systems will have less impact on systems which are using it as long the interfaces remain same. Even if there are changes the impact will be minimal for adpating new changes.


7) How does your design handle Manageability?
- Since application uses J2ee we can pluging in any JMX based tools for application and network management and monitoring. In addition we can also have good logging mechanism to indicate any Fatal or Error conditions.
Using JMX we can also trun on different logging levels at run time if required. (Eg: Say if there is some error that happens only in production we can trun on debug levels for a while using JMX modules)

8) How does your design handle Maintainability?
- Due to the layered architecrture each layer address a particular need so any enhancement can be made easily. Also each layer is loosely coupled with best deisgn practices which makes understanding functionality and making changes easier.
This can also be supported with good documentation of the application (Architecture diagrams, Interface agreements with extenal systems, Class diagrams, Sequence diagrams, Java doc etc)


1) How does your design support session/state handling?
- For maintaining the shopping cart application uses stateful session bean.

2) How does your design handle persistence?
- Using JPA and Entity Beans. The access is through Data Access Object (DAO).

3) How does your client tier talk to business tier?
- The presentation tier call's Business Facade <--> Business Delegate <---> DAO. The business facade is used to make sure there is less coupling between
presentation and business layer.The business delegate uses Service locator for invoking any EJB (RMI/IIOP) and DAO's.

4) How does your design handle Qos 5 Sec in peak time?


5) How does your design handle transactions?
- Using EJBs CMT through JPA.

6) How does your design handle authentication and authorization?
- When user completes his shopping we can give a provision to check out as guest or the user can create a profile in which case the the future logins will involve FORM based authentication mechanism.
- For internal users who maintian the applicataion in production, run reports for future projections or analysis etc we have LDAP based authentication mechanism.Here users can be put to different roles
so that not every internal user is authorized to run reports or view some critical data (eg: related to orders placed and payment relatred data)



NOTE/WARNING: After completing part-3 exam I got a message saying completed successfully and that I will get the results in 4-6 weeks with a print out at the exam center. But when I logged into pearson vue account the status for part-3 was showing as error. When I called Pearson initially they said its not an issue but later of my continuous questioning I was informed that the part 3 essay was not uploaded to oracle site due to net work error in Pearson application. Frankly I went though such a pain calling pearson, oracle. Pearson support doesnt have any mail access so the only way is to call them and each time they would tell some story. Finally after 21 days they resolved the problem. (yes it took them 21 days to upload my essay to oracle. I am hoping they have submitted what I have answered and not an empty file).
Hope no one will have this trouble.

Good luck and after September 1st all folks need to take a mandatory Part-4 which is a training from oracle. My personal opinion is it will be to expensive for any one to pay entire certification cost and it may discourage more people. As the Part-4 training I heard is very expensive.

Resources: