Wednesday, January 25, 2012

To develop sample webservice application using Xfire

To know more about xfire
http://xfire.codehaus.org/

Below are the steps to create a sample web service "AdditionWebService" (by using xfire) which takes input 2 numbers and returns sum of those numbers as response.

To create new webservice project
You need to have J2EE eclipse developer for below steps to follow
In eclipse go to - File->New->Project
search for web


select "Dynamic Web Project" , give Project Name, Next & Finish

Folder structure once the project is created.


In .classpath change <classpathentry kind="output" path="build/classes"/>
to
<classpathentry kind="output" path="WebContent/WEB-INF/classes"/>

Inorder to add JBOSS jar files to classpath
Create User library "JBOSS4.3"
Go to eclipse->Window->Preferences->Java->Build Path->User Libraries
Click on new -> (give any name) JBOSS4.3, OK
Select JBOSS4.3 and select "Add JARs" go to <JBOSS-HOME>client
For example -  C:\jboss-eap-4.3\jboss-as\client
select all jars and click open. Click ok

Now add that user library to build path of the project
Right click on the project, go to properties, in Java Build Path, In Libraries tab, click on "Add Library"
select User library, click next and select "JBOSS4.3" Click OK, Finish.


Create request & response bean

In /AdditionWebService/src/com/test/bean/AdditionRequest.java
package com.test.bean;

public class AdditionRequest {
    private int anumber;
    private int bnumber;
    public int getAnumber() {
      return anumber;
    }
    public int getBnumber() {
      return bnumber;
    }
    public void setAnumber(int anumber) {
      this.anumber = anumber;
    }
    public void setBnumber(int bnumber) {
      this.bnumber = bnumber;
    }
}
In /AdditionWebService/src/com/test/bean/AdditionResponse.java
package com.test.bean;

public class AdditionResponse {
    private int cnumber;

    public int getCnumber() {
      return cnumber;
    }

    public void setCnumber(int cnumber) {
      this.cnumber = cnumber;
    }
}
Create interface 
In /AdditionWebService/src/com/test/service/AdditionWebService.java
package com.test.service;

import com.test.bean.AdditionRequest;
import com.test.bean.AdditionResponse;

public interface AdditionWebService {
    public AdditionResponse addNumbers(AdditionRequest addRequest);
}

Implementation 
In /AdditionWebService/src/com/test/service/AdditionWebServiceImpl.java
package com.test.service;

import javax.jws.WebService;

import com.test.bean.AdditionRequest;
import com.test.bean.AdditionResponse;

@WebService
public class AdditionWebServiceImpl implements AdditionWebService {
   public AdditionResponse addNumbers(AdditionRequest addRequest) {
       AdditionResponse addResponse = new AdditionResponse();
       addResponse.setCnumber(addRequest.getAnumber()+addRequest.getBnumber());
       return addResponse;
   }
}

In /AdditionWebService/WebContent/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
      id="WebApp_ID" version="2.5">
      <display-name>AdditionWebService</display-name>
      
      <!--  XFire servlet-related entries START -->
      <servlet>
            <servlet-name>XFire</servlet-name>
            <servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class>
      </servlet>
      <servlet-mapping>
            <servlet-name>XFire</servlet-name>
            <url-pattern>/services/*</url-pattern>
      </servlet-mapping>
      <!--  XFire servlet-related entries END -->
</web-app>
In /AdditionWebService/WebContent/META-INF/xfire/services.xml
<beans xmlns="http://xfire.codehaus.org/config/1.0">
  <service>
    <name>AddService</name>
    <namespace>addition</namespace>
    <serviceClass>com.test.service.AdditionWebService</serviceClass>
    <implementationClass>com.test.service.AdditionWebServiceImpl</implementationClass>
  </service> 
</beans>

Jars that needs to be downloaded for Xfire
http://xfire.codehaus.org/Dependency+Guide

You can download all jars mentioned in above link http://xfire.codehaus.org/Download
download distribution zip file and In xfire-1.2.6\lib you will find all required jars

Copy required jars mentioned in http://xfire.codehaus.org/Dependency+Guide to /AdditionWebService/WebContent/WEB-INF/lib

To create war & deploy to JBOSS server
Right click on project -> Export


Search for war


In Destination folder go to your deploy folder & click finish.

Once war is deployed goto http://localhost:8080/AdditionWebService/services/AddService?wsdl
to generate wsdl file. 


View source and copy to AddService.wsdl file
To test service using soapUI client 
Create new soap UI project


Sample request and response xml


To test with Java client
Generate client using wsdl 


Select output folder - 

Below files will be created. 


In /AddServiceClient/src/com/test/client/AddServiceClient.java

package com.test.client;

import addition.AddServiceLocator;
import addition.AddServicePortType;

import com.test.bean.AdditionRequest;
import com.test.bean.AdditionResponse;

public class AddServiceClient {
      private static AddServiceLocator service;
      private static AddServicePortType port;

      public static void main(String [] args)  {
            try {
                  
            // webservice end address     
            service = new AddServiceLocator();
            String webservice_address = "http://localhost:8080/AdditionWebService/services/AddService";
            service.setAddServiceHttpPortEndpointAddress(webservice_address);
            port = service.getAddServiceHttpPort();

            // create request
            Integer anumber = new Integer(3);
            Integer bnumber = new Integer(4);
            AdditionRequest addRequest = new AdditionRequest();
            addRequest.setAnumber(anumber);
            addRequest.setBnumber(bnumber);
            
            // calling webservice method
            AdditionResponse addResponse = port.addNumbers(addRequest);
            
            System.out.println("Addtion service response : "+addResponse.getCnumber());
            
            } catch (Exception e) {
                   e.printStackTrace();
            }
      }
}
Output - 
Addtion service response : 7

Tip for faster deployment & developement

Inorder to avoid building jar & ear on every change of class file. Follow below steps.
For example - if you have CRS in eclipse -
In /Store/EStore/META-INF/MANIFEST.MF
Add "classes" before all jars of "ATG-Class-Path" as in below figure.




Now if you re-build the ear using runAssembler
A new folder _Store.EStore_sclasses folder will be created.


Now in eclipse create a "linked folder"
File -> New -> Folder ->


Once you have this linked folder -
In .classpath file, point output folder to
<classpathentry kind="output" path="EStore/_Store.EStore_sclasses"/>


So that whenever eclipse build or compile a class is saved (if you have build automatically set),  .class files are directly stored in ear -
For example -
C:\ATG\ATG10.0.3\home\cimEars\atg_production_lockserver.ear\atglib\_Store.EStore_sclasses
Since "clasess" is kept before of all jars in ATG-Class-Path, classes in this folder are picked (lib/classes.jar is not considered) by this way you dont need to build jars & create ear again after modification of a java file(s).

Installing Commerce Reference Store

As many people asked for CRS installation details. I tried to cover as much as possible to give step by step instruction.

For CRS installation details refer below -
http://docs.oracle.com/cd/E22630_01/CRS.1002/pdf/ATGCRSInstall.pdf

Installations you need to have before proceeding further
ATG 10.0.3, JDK 1.6, BEA 10.3, oracle xe. (all are freeware, you dont need any license files)
This steps will also work for ATG9.x, JDK 1.5, BEA 10.0

Below is my Environment details -
DYNAMO_HOME - C:\ATG\ATG10.0.3\home
JAVA_HOME - C:\jdk1.6.0_23
BEA_HOME - BEA_HOME=C:\bea10.3
Installed oracle xe - C:\oraclexe\app\oracle\product\10.2.0\
For oracle jdbc drivers -
CLASSPATH=C:\oraclexe\app\oracle\product\10.2.0\server\jdbc\lib\ojdbc14.jar;

Create a new weblogic domain "CRSV10"
Execute configuration wizard - C:\bea10.3\wlserver_10.3\common\bin\config.exe
When asked for Domain Name give CRSV10


And when asked for JDK give installed jdk 1.6


Thats it CRSV10 domain is created.

Go to C:\bea10.3\user_projects\domains\CRSV10\bin> and run startWebLogic.cmd
http://localhost:7001/console
Keep it running until the setup is completed.

Schema's that needs to be created before going further -
-- For Production site
-- for JNDI - ATGProductionDS - CORE schema
-- core user - crscorev10/password1
create user crscorev10 identified by password1 default tablespace users temporary tablespace temp;
grant connect, resource to crscorev10;
grant select any table to crscorev10;
grant create any table to crscorev10;
grant update any table to crscorev10;
grant delete any table to crscorev10;
grant alter any table to crscorev10;
grant create any view to crscorev10;

-- for JNDI - ATGSwitchingDS_A - for Switching A schema
-- switch A - crscatav10/password1
create user crscatav10 identified by password1 default tablespace users temporary tablespace temp;
grant connect, resource to crscatav10;
grant select any table to crscatav10;
grant create any table to crscatav10;
grant update any table to crscatav10;
grant delete any table to crscatav10;
grant alter any table to crscatav10;
grant create any view to crscatav10;

-- for JNDI - ATGSwitchingDS_B - for switching B schema
-- switch B - crscatbv10/password1
create user crscatbv10 identified by password1 default tablespace users temporary tablespace temp;
grant connect, resource to crscatbv10;
grant select any table to crscatbv10;
grant create any table to crscatbv10;
grant update any table to crscatbv10;
grant delete any table to crscatbv10;
grant alter any table to crscatbv10;
grant create any view to crscatbv10;

-- For Publishing site
-- for JNDI - ATGPublishingDS - Production Core schema
-- pub user - crspubv10/password1
create user crspubv10 identified by password1 default tablespace users temporary tablespace temp;
grant connect, resource to crspubv10;
grant select any table to crspubv10;
grant create any table to crspubv10;
grant update any table to crspubv10;
grant delete any table to crspubv10;
grant alter any table to crspubv10;
grant create any view to crspubv10;

Pre-define ATG servers & Weblogic servers & ports that needs to be created.
Just keep these values defined, so that at the time of cim installation, you need to provide these values.
For Production -
rmiport - 8860
drpport - 8850
file deployment port - 8810
file synchronization deploy server port - 8815
httpPort=7003
httpsPort=7004

atg server name - crs_production_v10
weblogic server name - crs_production_v10

EAR name - crs_production_v10.ear

For Publishing -
rmiport - 8861
drpport - 8851
file deployment port - 8811
file synchronization deploy server port - 8816
lock server port - 9010

httpPort=7005
httpsPort=7006

atg server name - crs_publishing_v10
weblogic server name - crs_publishing_v10

Ear name - crs_publishing_v10.ear

RUN CIM
Go to <ATG-Home>/home/bin
run cim.bat

At the time of "Product Selection" -
Note: If you already did executed cim.bat & something got messed up previously, you can still select "Production selection" & Continue & select.
Note: When * is selected at option & if you want to go with that option just press enter. Selecting the option again will toggle.
. If cim prompts for example hostname[localhost] > then press enter to select localhost as hostname or enter new value "myhost" to assign to hostname.

Below are the products & Addons I selected
-------PRODUCT MODULE CALCULATION start-----------------------------------------------
enter [h]elp, [m]ain menu, [q]uit to exit

Current Product Selection:

  ATG Platform and Content Administration
  ATG Search
  ATG Site Administration
  ATG Commerce Reference Store

Selected AddOns:

  ATG Search
  Merchandising UI
  Switching Datasource
  Include Search QueryConsole on Production
  Index by SKU
  Storefront Demo Application
  Full

Server Instance Types:
  Production Server
     DafEar.Admin DPS DSS B2CCommerce DCS.PublishingAgent
DCS.AbandonedOrderServices DAF.Search.Routing DCS.Search Store.Search
DAF.Search.Base.QueryConsole DCS.Search.Index.SKUIndexing
DCS.Search.Query.SKUIndexing Store.Storefront

  Publishing Server
     DCS-UI.Search DCS-UI.Versioned BIZUI PubPortlet DafEar.Admin
B2CCommerce.Versioned DCS.Versioned DCS-UI Store.EStore.Versioned
Store.Storefront SiteAdmin.Versioned DAF.Search.Versioned DAF.Search.Routing
SearchAdmin.AdminUI DCS.Search.Versioned Store.Search Store.Search.Index
SiteAdmin.Search DCS.Search.Index.SKUIndexing DCS.Search.Query.SKUIndexing
-------PRODUCT MODULE CALCULATION end-----------------------------------------------

1) Database Configuration -
For Database Configuration, you need configure
*[P]  Publishing
  [S]  Switching A
  [B]  Switching B
  [C]  Production Core
  [D]  Done

As CIM prompts, go with default settings, When asked for Connection details, give as below

-------CONNECTION DETAILS START---------------------------------------------
enter [h]elp, [m]ain menu, [q]uit to exit

Publishing
  Select Database Type

*[1]  Oracle Thin
  [2]  MS SQL
  [3]  iNet MS SQL
  [4]  DB2
  [5]  My SQL

Select one > 1

   Enter User Name [[crs10pub]] > crspubv10
   Enter Password [[*********]] > *********
   Re-enter Password > *********
   Enter Host Name [[localhost]] >
   Enter Port Number [[1521]] >
   Enter Database Name [[xe]] >
   Enter Database URL [[jdbc:oracle:thin:@localhost:1521:xe]]
>
   Enter Driver Path [[C:/oraclexe/app/oracle/product/10.2.0/server/jdbc/lib/ojdbc14.jar]] >
   Enter JNDI Name [[ATGPublishingDS]] >

-------CONNECTION DETAILS END------------------------------------------
Once, above step is done, Test connection, Create Schema, Import Initial Data
And repeat "Database Configuration" for Swithching A(crscatav10), Switching B(crscatbv10) & Core (crscorev10)
Once Database Configuration - Done

2) Server Instance Configuration -
Next step is "Server Instance Configuration"
2 instances one for Publishing and one for Production needs to be configured.
============ PUBLISHING SERVER CONFIGURATION start ================
*[P]  Publishing Server - 0 Instances Configured
  [S]  Production Server - 0 Instances Configured
  [D]  Done

*[P]  Publishing Server General Configuration - REQUIRED
  [I]  Instance Management - REQUIRED
  [C]  Modify Calculated Module List - OPTIONAL
  [S]  Scenario Manager - OPTIONAL
  [O]  Configure Another Server Instance Type

   Enter Production Lock Server Hostname [[crs_production]] >  localhost
   Enter Production Lock Server Port [[9012]] >
   Enter the Remote Production Search Instance Host Name [[crs_production]]>  localhost
   Enter the Remote Production Search Instance RMI Port Number [[8860]] >

  [P]  Publishing Server General Configuration - DONE
*[I]  Instance Management - REQUIRED
  [C]  Modify Calculated Module List - OPTIONAL
  [S]  Scenario Manager - OPTIONAL
  [O]  Configure Another Server Instance Type

*[A]  Add Server Instance
  [R]  Remove Server Instance
  [D]  Done
>
  Select Type of Server Instance To Create

*[1]  Publishing with a Server Lock Manager : Minimum 1 Required
  [2]  Publishing

Select one >
   Enter Server Instance Name :  [[atg_publishing_lockserver]] > crs_publishing_v10
   Enter HTTP Port [[7003]] > 7005
   Enter HTTPS Port [[7004]] > 7006
   Enter Site HTTP Port [[7003]] > 7005
   Enter RMI Port [[8860]] > 8861
   Enter DRP Port [[8850]] > 8851
   Enter File Deployment Port [[8810]] > 8811
   Enter File Synchronization Deploy Server Port [[8815]] > 8816
============ PUBLISHING SERVER CONFIGURATION end ================

============ PRODUCTION SERVER CONFIGURATION start ================

  [P]  Publishing Server - 1 Instance Configured - DONE
*[S]  Production Server - 0 Instances Configured
  [D]  Done
 >
*[P]  Production Server General Configuration - REQUIRED
  [I]  Instance Management - REQUIRED
  [C]  Modify Calculated Module List - OPTIONAL
  [S]  Scenario Manager - OPTIONAL
  [O]  Configure Another Server Instance Type
>
  [P]  Production Server General Configuration - DONE
*[I]  Instance Management - REQUIRED
  [C]  Modify Calculated Module List - OPTIONAL
  [S]  Scenario Manager - OPTIONAL
  [O]  Configure Another Server Instance Type
 >
*[A]  Add Server Instance
  [R]  Remove Server Instance
  [D]  Done
>
  Select Type of Server Instance To Create
*[1]  Production with a Server Lock Manager : Minimum 1 Required
  [2]  Production
Select one > 1
   Enter Server Instance Name :  [[atg_production]] > crs_production_v10
   Enter HTTP Port [[7003]] >
   Enter HTTPS Port [[7004]] >
   Enter Site HTTP Port [[7003]] >
   Enter RMI Port [[8860]] >
   Enter DRP Port [[8850]] >
   Enter File Deployment Port [[8810]] >
Enter Lock Server Hostname [[crs_production_v10]] > localhost
Enter Lock Server Port [[9012]] >
============ PRODUCTION SERVER CONFIGURATION end ================

Once "Server Instance Configuration" is done
Next would be "Application Assembly & Deployment"

3) Application Assembly & Deployment
-------DEPLOYMENT SERVER PRODUCTION start------------------------
*[C]  crs_production_v10 - Production
  [P]  crs_publishing_v10 - Publishing with a Server Lock Manager
  [D]  Done
>
   Enter Ear File Name for Production [[atg_production.ear]] > crs_production_v10.ear

Current runAssembler arguments :
-server crs_production_v10
Weblogic Admin Server must be running.

Top Level Module List:

DafEar.Admin DPS DSS B2CCommerce DCS.PublishingAgent
DCS.AbandonedOrderServices DAF.Search.Routing DCS.Search Store.Search
DAF.Search.Base.QueryConsole DCS.Search.Index.SKUIndexing
DCS.Search.Query.SKUIndexing Store.Storefront

*[D]  Deploy Production crs_production_v10.ear to Weblogic Online
  [R]  Register Datasources on Weblogic Online
  [A]  Add database driver to app server classpath
  [P]  Post Deployment Actions on Weblogic Online
  [E]  Edit runAssembler arguments
  [O]  Configure Another Server Instance
 > D

Once deployment of crs_production_v10.ear is done, go with next options like Register Datasource on Weblogic online, Add db driver to app server path,
& Post Deployment Actions on Weblogic online
-------DEPLOYMENT SERVER PRODUCTION start------------------------

-------DEPLOYMENT SERVER PUBLISHING start------------------------
  [C]  crs_production_v10 - Production - Done
*[P]  crs_publishing_v10 - Publishing with a Server Lock Manager
  [D]  Done

 Enter Ear File Name for Publishing with a Server Lock Manager [[atg_publishing_lockserver.ear]] > crs_publishing_v10.ear
Current runAssembler arguments :
-server crs_publishing_v10
Weblogic Admin Server must be running.

Top Level Module List:

DCS-UI.Search DCS-UI.Versioned BIZUI PubPortlet DafEar.Admin
B2CCommerce.Versioned DCS.Versioned DCS-UI Store.EStore.Versioned
Store.Storefront SiteAdmin.Versioned DAF.Search.Versioned DAF.Search.Routing
SearchAdmin.AdminUI DCS.Search.Versioned Store.Search Store.Search.Index
SiteAdmin.Search DCS.Search.Index.SKUIndexing DCS.Search.Query.SKUIndexing

*[D]  Deploy Publishing with a Server Lock Manager crs_publishing_v10.ear to
Weblogic Online
  [R]  Register Datasources on Weblogic Online
  [A]  Add database driver to app server classpath
  [P]  Post Deployment Actions on Weblogic Online
  [E]  Edit runAssembler arguments
  [O]  Configure Another Server Instance
 > d

Once deployment of crs_production_v10.ear is done, go with next options like Register Datasource on Weblogic online, Add db driver to app server path,
& Post Deployment Actions on Weblogic online
-------DEPLOYMENT SERVER PUBLISHING end------------------------
Once Above steps are done, exit CIM.

Checks & Validations before starting servers -

1) ATG servers that are created by CIM
Production server - C:\ATG\ATG10.0.3\home\servers\crs_production_v10
Publishing server - C:\ATG\ATG10.0.3\home\servers\crs_publishing_v10

2) Ear's that are created by CIM
Production ear - C:\ATG\ATG10.0.3\home\cimEars\crs_production_v10.ear
Publishing ear - C:\ATG\ATG10.0.3\home\cimEars\crs_publishing_v10.ear
Note: All ears are standalone ears

3) The runAssembler command used to create above ears by CIM is
For production ear -
runAssembler -server crs_production_v10  C:/ATG/ATG10.0.3/home/../home/cimEars/crs_production_v10.ear
 -m DafEar.Admin DPS DSS B2CCommerce DCS.PublishingAgent DCS.AbandonedOrderServices DAF.Search.Routing DCS.Search Store.Search DAF.Search.Base.QueryConsole DCS.Search.Index.SKUIndexing DCS.Search.Query.SKUIndexing Store.Storefront
For publishing ear -
runAssembler -server crs_publishing_v10  C:/ATG/ATG10.0.3/home/../home/cimEars/crs_publishing_v10.ear
 -m DCS-UI.Search DCS-UI.Versioned BIZUI PubPortlet DafEar.Admin B2CCommerce.Versioned DCS.Versioned DCS-UI Store.EStore.Versioned Store.Storefront SiteAdmin.Versioned DAF.Search.Versioned DAF.Search.Routing SearchAdmin.AdminUI DCS.Search.Versioned Store.Search Store.Search.Index SiteAdmin.Search DCS.Search.Index.SKUIndexing DCS.Search.Query.SKUIndexing

4) Weblogic servers that are created by CIM
In C:\bea10.3\user_projects\domains\CRSV10\config\config.xml
  <server>
    <name>crs_production_v10</name>
    <listen-port>7003</listen-port>
    <web-server>
      <web-server-log>
        <number-of-files-limited>false</number-of-files-limited>
      </web-server-log>
    </web-server>
    <listen-address></listen-address>
  </server>
  <server>
    <name>crs_publishing_v10</name>
    <listen-port>7005</listen-port>
    <web-server>
      <web-server-log>
        <number-of-files-limited>false</number-of-files-limited>
      </web-server-log>
    </web-server>
    <listen-address></listen-address>
  </server>

5) App deployments in Weblogic server done by CIM -
Note: By default <staging-mode>nostage</staging-mode> is not added in config.xml
Add <staging-mode>nostage</staging-mode> to each app-deployment, having this option
will not copy the ear to weblogic domain while starting which will consume time at server startup.
  <app-deployment>
    <name>crs_production_v10.ear</name>
    <target>crs_production_v10</target>
    <module-type>ear</module-type>
    <source-path>C:\ATG\ATG10.0.3\home\..\home\cimEars\crs_production_v10.ear</source-path>
    <security-dd-model>DDOnly</security-dd-model>
    <staging-mode>nostage</staging-mode>
  </app-deployment>
  <app-deployment>
    <name>crs_publishing_v10.ear</name>
    <target>crs_publishing_v10</target>
    <module-type>ear</module-type>
    <source-path>C:\ATG\ATG10.0.3\home\..\home\cimEars\crs_publishing_v10.ear</source-path>
    <security-dd-model>DDOnly</security-dd-model>
    <staging-mode>nostage</staging-mode>
  </app-deployment>
<

6) Before starting servers, make sure your lockmanagers are pointing to right host
In /c/ATG/ATG10.0.3/home/servers/crs_production_v10
./localconfig/atg/dynamo/service/ClientLockManager.properties:lockServerAddress=localhost
./localconfig/atg/dynamo/service/ClientLockManager_production.properties:lockServerAddress=localhost

In /cygdrive/c/ATG/ATG10.0.3/home/servers/crs_publishing_v10
./localconfig/atg/commerce/search/config/RemoteCatalogRankConfigAdapter.properties:remoteHost=localhost
./localconfig/atg/commerce/search/config/RemoteSearchUpdateAdapter.properties:remoteHost=localhost
./localconfig/atg/commerce/search/refinement/RemoteCatalogRefineConfigAdapter.properties:remoteHost=localhost
./localconfig/atg/dynamo/service/ClientLockManager.properties:lockServerAddress=localhost
./localconfig/atg/dynamo/service/ClientLockManager_production.properties:lockServerAddress=localhost

7) Make sure you have protocol.jar added to classpath, if not add it in
C:\bea10.3\user_projects\domains\CRSV10\bin\setDomainEnv.cmd
rem CIM - Prepending protocol.jar CLASSPATH
set CLASSPATH=C:/bea10.3/user_projects/domains/CRSV10/lib/protocol.jar;%CLASSPATH%
8) For faster server startup make sure that you have provided weblogic username/password in
C:\bea10.3\user_projects\domains\CRSV10\bin\startManagedWebLogic.cmd
set WLS_USER=weblogic
set WLS_PW=<weblogic password>
9) Make sure you have database drivers in your classpath.
CLASSPATH=C:\oraclexe\app\oracle\product\10.2.0\server\jdbc\lib\ojdbc14.jar;

Starting weblogic servers
1) Starting production server
In command prompt -
Go to cd C:\bea10.3\user_projects\domains\CRSV10\bin
set JAVA_OPTIONS=-Datg.dynamo.server.name=crs_production_v10
startManagedWebLogic.cmd crs_production_v10
Once server is started.
http://localhost:7003/crs/storeus

As you can observe there wont be any images shown yet. They will be shown once you have a full deployment.



2) Starting publishing server
In command prompt -
Go to cd C:\bea10.3\user_projects\domains\CRSV10\bin
set JAVA_OPTIONS=-Datg.dynamo.server.name=crs_publishing_v10
startManagedWebLogic.cmd crs_publishing_v10
Once server is started.
http://localhost:7005/atg/bcc

=========== If you get errror START ====================
**** Error      Wed Jan 25 12:28:48 CST 2012    1327516128324   /atg/portal/framework/PortalObjectResolver      No root community folder for portal 'default'

You need to re-import BIZUI
Have below files
C:\ATG\ATG10.0.3\home\localconfig\atg\dynamo\service\jdbc\JTDataSource.properties
$class=atg.service.jdbc.MonitoredDataSource
dataSource=/atg/dynamo/service/jdbc/FakeXADataSource

C:\ATG\ATG10.0.3\home\localconfig\atg\dynamo\service\jdbc\FakeXADataSource.properties
$class=atg.service.jdbc.FakeXADataSource
URL=jdbc:oracle:thin:@localhost:1521:xe
user=crspubv10
password=password1
needsSeparateUserInfo=true
readOnly=false
driver=oracle.jdbc.xa.client.OracleXADataSource

In C:\ATG\ATG10.0.3>
C:\ATG\ATG10.0.3\BIZUI\install\importBizui.bat

before restart delete files - JTDataSource.properties &  FakeXADataSource.properties in localconfig.
=========== If you get errror END ====================

3) Full deployment -
Go to http://localhost:7005/atg/bcc
use login - admin/admin
Go to Content Adminstration->Admin Console

Go to Configuration tab -> Click on "Add Site"

Give Site Name as Production & see below options & Repository Mappings are selected.


Click on Agents tab, Click on "Add agent Site"

Give agent Name as "ProdAgent" and rmi port as rmi://localhost:8680/atg/epub/AgentTransport & press ">>". Please refer below screenshot & "Save Changes"


Click on Configuration tab & click on "Make Changes Live"


Go with "Do a full deployment" option & click on "Make Changes Live"

To Monitor deployment status, go to "Overview" tab & selection "production" site to check deployment status


Now check store
http://localhost:7003/crs/storeus


For login id's use "select * from dps_user" on crscorev10 schema
For example -
username - alex@example.com
password for all logins is "password"

Thats it, commerce reference store is ready for development.

Hope this helps!!

Thursday, December 29, 2011

Heap dump analysis

Below is one example of analyzing heap dump to know which objects are responsible for JVM out of memory.
Once you have java option option -XX:+HeapDumpOnOutOfMemoryError, heap dump will be generated once JVM is out of memory.
or else you can use JMX tools to generate heap dump.
for more information go through http://atgkid.blogspot.com/2011/12/how-to-take-thread-dumps-and-heap-dumps.html

Once heap dump is generated.

Download Eclipse Memory Analyzer (For 64-bit OS get 64 bit version) - http://eclipse.org/mat/
Depending on the heap size dump you need to increase the vm size of Eclipse MAT
To increase size in Mac OS X, Right click on MemoryAnalyzer (application) then "Show Package Contents".
Edit - MemoryAnalyzer.app/Contents/MacOS/MemoryAnalyzer.ini

In below example - size of heap dump is 1.8 GB and Eclipse MAT vm size is "3048m" and instance  vm size (from which the heap dump is generated) is 2560m.

Open heap dump -


Once the heap dump is loaded in Eclipse Memory Analyzer
Open dominator tree.

Select "Group by class"

By here you can know what type of objects occupied much of heap dump.
For example - In below scenario, GSAItem objects occupy 41% of heap dump (788 MB of 1.8 GB)

To further know which item's are resposible for 41%
Right click on atg.adapter.gsa.GSAItem -> List objects -> with outgoing references

Once the objects are listed. To know what type of items. 
In GSAItem object, mItemDescriptor.mItemDescriptorName will give the name of the GSAItem.

We need to group by value "mItemDescriptor.mItemDescriptorName" on Class atg.adapter.gsa.GSAItem (in dominator_tree).
So go back to dominator_tree tab, right click on atg.adapter.gsa.GSAItem -> Java Basics -> Group By Value.


In Group By Value window, fill field with "mItemDescriptor.mItemDescriptorName" and click finish.

This will take time depending on the number of objects it needs to parse. 
Once it is done, you can see which type of items (GSAItems) take more space in jvm heap space. (sort it by Retained Heap)
In below scenario, ss-sku items took 333 MB of jvm heap space and number of ss-sku items in memory are 35,465 (i.e 35,465 items are cached in memory)


Hope this helps!


How to take thread dumps and heap dumps using java tools

1) To take thread dumps -
Once you have below java options
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000
(Note: all tools mentioned below are available in <JAVA_HOME>/bin)

Using jdb
jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8000

> suspend
All threads suspended.
"where all" will give snapshot of all threads.
> where all
http-127.0.0.1-8443-6:
  [1] java.lang.Object.wait (native method)
  [2] java.lang.Object.wait (Object.java:485)
  [3] org.apache.tomcat.util.net.JIoEndpoint$Worker.await (JIoEndpoint.java:416)
  [4] org.apache.tomcat.util.net.JIoEndpoint$Worker.run (JIoEndpoint.java:442)
  [5] java.lang.Thread.run (Thread.java:662)
http-127.0.0.1-8443-5:
  [1] java.lang.Object.wait (native method)
  [2] java.lang.Object.wait (Object.java:485)
  [3] org.apache.tomcat.util.net.JIoEndpoint$Worker.await (JIoEndpoint.java:416)
  [4] org.apache.tomcat.util.net.JIoEndpoint$Worker.run (JIoEndpoint.java:442)
  [5] java.lang.Thread.run (Thread.java:662)
http-127.0.0.1-8443-4:
  [1] java.lang.Object.wait (native method)
  [2] java.lang.Object.wait (Object.java:485)
...
..
to resume all threads.
> resume

Using  jstack -
jstack <jvmid>  (you can get jvmid using jps)

For example -
C:\Documents and Settings\Administrator>jps
4416 Main
5800
3300 Jps
6676

C:\Documents and Settings\Administrator>jstack 4416
2011-12-27 16:32:19
Full thread dump Java HotSpot(TM) Server VM (19.0-b09 mixed mode):

"ajp-127.0.0.1-8009-Acceptor-0" daemon prio=6 tid=0x6fc39c00 nid=0x11fc runnable [0x6d27f000]
   java.lang.Thread.State: RUNNABLE
        at java.net.PlainSocketImpl.socketAccept(Native Method)
        at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390)
        - locked <0x14495ae0> (a java.net.SocksSocketImpl)

To get thread dump using jboss jmx-console, please go through below link
http://atgkid.blogspot.com/2011/10/how-to-take-thread-dumps-in-jboss.html

2) To take heap dumps - 
Using jmap (available from jdk 1.6 but can also be used on jvm with 1.4+ )
jmap -dump:format=b,file=<filename>.hprof <jvmid>

C:\Documents and Settings\Administrator>jps
4416 Main
5800
3300 Jps
6676

C:\Documents and Settings\Administrator>jmap -dump:format=b,file=sample.hprof 4416
Dumping heap to C:\Documents and Settings\Administrator\sample.hprof ...
Heap dump file created

Using java option -XX:+HeapDumpOnOutOfMemoryError
Once you have above java option, JVM will create heap dump once it is out of memory.

Using  jconsole - Java Monitoring and Management Console - JMX-compliant graphical tool for monitoring a Java virtual machine. It can monitor both local and remote JVMs
To use jconsole you need to have java option "-Dcom.sun.management.jmxremote"


heap dump file will be created in folder from where the application is run. For example - <JBOSS-HOME>/bin or <BEA-DOMAIN-HOME>/bin

Using  jvisualvm - comes with java 1.6 but can be used to visualize/monitor applications running on jdk 1.4 and higher. 
Monitor showing CPU and Heap Usage and total threads and classes. 
To get thread dump you can use

Sample heap dump taken using jvisualvm


To take thread dumps in jvisualvm


Sample Thread dump taken using jvisualvm 


Saturday, December 10, 2011

hitCount for referred items will not be increased while accessing parent item

While accessing an item, hitCount (in Dynamo component browser repository cache usage statistics) for referred items will not be increased.

For example - In PioneerCycling
In test4.jsp
<%@ taglib uri="dsp" prefix="dsp"%>
<dsp:page>
<dsp:importbean bean="/atg/commerce/catalog/ProductLookup"/>
<dsp:droplet name="ProductLookup" >
<dsp:param name="id" value="prod10023"/>
<dsp:param name="elementName" value="product"/>
<dsp:oparam name="output">
<dsp:valueof param="product.smallImage.url"/> <br>
</dsp:oparam>
</dsp:droplet>
</dsp:page>
By default PioneerCycling ProductCatalog has simple cache and item-cache-size for all items is 1000.
Before accessing this jsp

Product - accesscount is 0. Hit count is 0.
Media - accesscount is 0, hit count is 0.
Once test4.jsp is accessed for the first time.

Product - accesscount is 2, hit count is 0.
Media - accesscount is 6, hit count is 0.

First time access - In logs. select queries are fired.
[++SQLQuery++]
 SELECT t1.product_id,t1.version,t1.description,t1.nonreturnable,t1.brand,t1.end_date,t1.display_name,t1.disallow_recommend,
        t1.long_description,t1.creation_date,t1.start_date,t1.parent_cat_id,t1.product_type
   FROM dcs_product t1
  WHERE t1.product_id = ?
-- Parameters --
p[1] = {pd} prod10023 (java.lang.String)
[--SQLQuery--]
[++SQLSelect++]
 SELECT template_id,thumbnail_image_id,small_image_id,large_image_id
   FROM dcs_prd_media
  WHERE product_id=?
-- Parameters --
p[1] = {pd} prod10023 (java.lang.String)
[--SQLSelect--]

Once again if the test4.jsp is refreshed

Product - accessCount is 3, hit count is 1.
Media - accessCount is 6, hit count is 0.

As you can observe - neither the access count or hit count is increased for media items. But for product it got increased.
Note: Only first time queries are fired. Once items are cached there are no queries fired for product and media.
As test4.jsp is refreshed, product stats are getting increased but media stats are not getting increased.

Why?
Reason - (Below explanation is given by Oracle ATG support Nick Glover)
First time when product is accessed all its properties are loaded from database including media items, so for the first time accessCount for product and media items is increased. Once media items are loaded they are stored as references in the product property values. So, the next time the product is accessed, they don't need to be loaded at all, the product has a reference to them. This is not considered a cache hit on the media items because the media item cache is not being used in this situation; instead the product item cache is being used and its references to the media items are what is saving the trip to the database. And obviously, the hit ratio for media items is going to be 0% because the initial loading of them is a miss, and you have not done any direct requests for the media items that successfully found them in cache to get a cache hit.

Regarding Weak entry cache -
Suppose that number of products in application is 10000 and the item-cache-size is 5000
and number of media-items is 30000 (for each product 3 media-items) and the item-cache-size is 1000.
So if 1 product is accessed, 3 media items are loaded.

In above scenario, if 1000 products are accessed
product entry count is 1000 (in main cache)
media entry count is 1000 (in main cache)
media weak entry count is 2000 (in weak cache)

weak entry items in weak cache are not garbage collected until the referenced item (parent item) is removed/pushed from main cache.


Friday, November 25, 2011

Regarding ConcurrentUpdateException and InvalidVersionException

There are 3 places where order version is stored
1) Database level - dcspp_order.version
2) Repository item cache level - orderItem.getPropertyValue("version");
3) Session level - order.getVersion();

// This check is done in classes where order is modified
if (order.getVersion() != orderItem.getPropertyValue("version"))
     throw atg.commerce.order.InvalidVersionException

// This check is done while updating item
if (dcspp_order.version != orderItem.getPropertyValue("version"))
      throw atg.repository.ConcurrentUpdateException

Note: concurrency can be maintained on any repository item, please go through below documentation
http://docs.oracle.com/cd/E26180_01/Platform.94/RepositoryGuide/html/s0709maintainingitemconcurrencywithth01.html

atg.repository.ConcurrentUpdateException - Is thrown if 2 separate sessions (belong to 2 different instances) of same user edit same order simultaneously or if 2 applications are editing same order. One way to reproduce in cluster environment (in production)
Login in one browser 1  with one user suppose xyz and logout
Login in another browser 2  with same user xyz and logout
Login back in browser 1 with same user xyz

This exception is thrown in logs of instance (browser 1 session instance)
CONTAINER:atg.commerce.CommerceException; SOURCE:CONTAINER:atg.service.pipeline.RunProcessException: An exception was thrown from the context of the link named [updateCommerceItemObjects].; 
SOURCE:CONTAINER:atg.commerce.CommerceException: Saving order 2288449002 failed because doing so would result in data being overwritten. This save attempt had an out of date repository item [commerceItem].; 
SOURCE:atg.repository.ConcurrentUpdateException: no rows updated oldVersion=20 for item=commerceItem:ci55251446 in GSATransaction=atg.adapter.gsa.GSATransaction@6a77cca2    
thread=ajp-10.238.160.131-30100-37 transaction=TransactionImple < ac, BasicAction: aeea083:6d44:4ecb6eb0:da1fd5 status: ActionStatus.RUNNING >
Note: Typically item-cache-timeout by default is -1 (when not set) which means item will be in cache until invalidated. Suppose the item-cache-timeout for order is set to 30 mins.

Explanation -
When the user xyz login in one browser 1
  suppose his/her session is tied to one instance 1 and suppose his order version is incremented to 2.
logout
Note that user xyz order is cached in this instance 1 and its version is 2 and it will be there in the cache until item-cache-timeout which is 30 mins.

If the same user xyz tries to login using another browser 2
  suppose his/her session now got tied to another instance 2 and his order version will be incremented to 3.
logout
Note that user xyz order is cached in this instance 2 and its version is 3 and it will be there in the cache until 30 mins

since orderRepository has simple cache, instance 1 has no idea of updated version.
Note: If the browser 1 cookies are not removed, request will always go to instance 1.
In this 30 mins time, when user xyz login using browser 1, at the time of loadorder since the version in cache (which is 2) doesnt match with version in database
(which is 3) ConcurrentUpdateException is thrown.

This can also happen if the user in application like CSC and dotcom user both working on same order, then above exception is thrown

atg.commerce.order.InvalidVersionException -  is caused if 2 sessions (of same instance) of same user modifying same order simultaneously. 
One way to reproduce in dev environment (only 1 instance) or you need to make sure that 2 sessions belongs to same instance in cluster environment.

If the user has 2 seperate session in 2 seperate browsers, where both sessions are tied to one instance and since both session are updating same order, InvalidVersionException exceptions is thrown.

Explanation -
Whenever the order is updated, both order (session) version and order repository version are updated.
When updating if both order version and order repository version are not equal, then invalid version exception is thrown.

**** Error      Fri Nov 25 15:08:57 CST 2011    1322255337883   /atg/commerce/order/purchase/RepriceOrderDroplet        ---
CONTAINER:atg.service.pipeline.RunProcessException:
An exception was thrown from the context of the link named [updateOrderAfterReprice].; SOURCE:atg.commerce.order.InvalidVersionException: This order (2293186179) is out of date.
Changes have been made to the order and the operation should be resubmitted. Order version 4, Repository item version 9.
        at atg.service.pipeline.PipelineChain.runProcess(PipelineChain.java:371)
        at atg.service.pipeline.PipelineChainContext.runProcess(PipelineChainContext.java:185)
        at atg.service.pipeline.PipelineManager.runProcess(PipelineManager.java:453)
        at atg.service.pipeline.servlet.PipelineChainInvocation.service(PipelineChainInvocation.java:267)
        at atg.commerce.order.purchase.RepriceOrder.service(RepriceOrder.java:438)
        at atg.servlet.DynamoServlet.service(DynamoServlet.java:123)
        at atg.taglib.dspjsp.DropletTag.invokeServlet(Unknown Source)
        at atg.taglib.dspjsp.DropletTag.doAfterBody(Unknown Source)
        at org.apache.jsp.checkout.shippinginfo_jsp._jspx_meth_dsp_005fdroplet_005f8(shippinginfo_jsp.java:2128)
....stack trace CROPPED after 10 lines.
Caused by :atg.commerce.order.InvalidVersionException: This order (2293186179) is out of date. Changes have been made to the order and the operation should be resubmitted. Order version 4, Repository item version 9.
        at atg.commerce.order.OrderManager.updateOrder(OrderManager.java:2557)
        at atg.commerce.order.processor.ProcUpdateOrder.runProcess(ProcUpdateOrder.java:111)
        at atg.service.pipeline.PipelineLink.runProcess(PipelineLink.java:233)
        at atg.service.pipeline.PipelineChain.runProcess(PipelineChain.java:343)
        at atg.service.pipeline.PipelineChainContext.runProcess(PipelineChainContext.java:185)
        at atg.service.pipeline.PipelineManager.runProcess(PipelineManager.java:453)
        at atg.service.pipeline.servlet.PipelineChainInvocation.service(PipelineChainInvocation.java:267)
        at atg.commerce.order.purchase.RepriceOrder.service(RepriceOrder.java:438)
        at atg.servlet.DynamoServlet.service(DynamoServlet.java:123)
....stack trace CROPPED after 10 lines.