Wednesday 22 November 2017

Interview Preparation | ATG Dynamo


1.    What are the areas you have worked on in ATG?

2.    What is a Nucleus?
Nucleus is the ATG container for components, provides a hierarchical name space each component has a unique full name so that pages and other components reference it, creates and initializes component instance on request Decouples code from configuration and manages component scope.
Any Java object with an empty constructor can act as a Component in Nucleus, so writing a new Nucleus component is as easy as writing a Java class. Nucleus components are standard JavaBeans, each with an accompanying .properties file, storing configuration values Nucleus sets the configured values on each new instance of a component. There can be many instances of a component.  In each case, the configured values in the .properties file become the initial values for properties of the “live” component.  After initialization, the live values may change, depending on usage of the particular property. 
Nucleus is Oracle ATG Web Commerce’s component model for building applications from JavaBeans. Nucleus lets you assemble applications through simple configuration files that specify what components are used by the application, what parameters are used to initialize those components, and how those components hook up to each other.
Nucleus by itself provides no application-specific functions. The JavaBean components implement all of an application’s functionality. Nucleus is the mechanism that gives those components a place to live, and a way for those components to find each other.

A Nucleus serves two purposes:

·         It is the root of a NameContext hierarchy, and
·         It implements the policies for resolving names in the hierarchy.

Running Nucleus

To use ATG platform functionality, a Web application needs to start Nucleus by invoking NucleusServlet. This servlet does not need to have any paths mapped to it, but must have the load-on-startup flag set to 1 so that it runs before any other ATG component. The web.xml file in atg_bootstrap.war includes the following lines:

<servlet>
  <servlet-name>NucleusServlet</servlet-name>
  <servlet-class>atg.nucleus.servlet.NucleusServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

The NucleusServlet creates an instance of Nucleus and sets it as an attribute of the web application. The Nucleus instance can be retrieved using the Nucleus.getGlobalNucleus()method.
Note: When you declare servlets in web.xml, you can use optional load-on-startup tags to determine the order the servlets are called. If you do not use these tags, the servlets are called in the order that they appear in web.xml. Because NucleusServlet must run first, its load-on-startup value must be 1, as in the example above.

Starting a Nucleus Component

When you start up an application, Nucleus reads the configuration path, which is a list of directories to use to find configuration files. Within one of those directories is a file called Nucleus.properties that contains the name of the first component to create. In the standard ATG platform configuration, the start of the Nucleus.properties file looks like this:
$class=atg.nucleus.Nucleus
initialServiceName=/Initial
You can view the properties of the Nucleus component by opening the / component in the ATG Control Center Components by Path window. The initialServiceName property instructs Nucleus to configure and start up its initial service using Initial.properties, which in the standard ATG platform configuration looks like this:

$class=atg.nucleus.InitialService
initialServices=\
     /atg/Initial,\
     VMSystem,\
     /atg/dynamo/StartServers


3.    Difference between dsp: include and jsp:include?

Dsp imports all objects of type class also, where as jsp imports only primitive types.
Jsp includes are dynamic where as dsp include are for data which is smaller than 64 kb.

ATG created the DSP tag library as a mechanism for accessing all data types, including those that exist in ATG’s Nucleus framework. Other functions provided by these tags manage transactions and determine how data is rendered in a JSP. It’s best to use tags from the DSP tag library only for tasks that involve Dynamo Application Framework (DAF) resources. Dsp tag support for the passing of object parameters between pages. In particular, use dsp:include rather than jsp:include, and use dsp:param rather than jsp:param.

4.    What is Formhandlers?

Form handlers evaluate the validity of form data before it is submitted, check for errors, and determine what action to take—for example, submit the data, direct the user to a different page, and display an error message. Often when you use a form handler, the form input fields are associated with properties of the form handler rather than the component you ultimately want to modify. For example, your form might include this tag:
<dsp:input type="text" bean="MyFormHandler.age"/>

When the form is submitted, a method of MyFormHandler associated with the age property is invoked. Depending on how this method is written, it might validate the data and then set the value of Person1.age, or use the data to fill in a record in a database.
A form handler class must include one or more handler methods. A handler method is typically invoked when the user clicks the submit button, and handles the processing of the form. Depending on the purpose of the form handler, it can have several different handler methods that each perform a different operation. For example, a form handler that works with user profiles might have separate handler methods for creating the profile, modifying the profile, and logging the user in.

Following are the tasks assigned to Form Handlers by ATG :
·         Validate data before it is submitted.
·         Detect missing information and display appropriate messages to the user.
·         Direct users to different pages depending on form submission results.
·         Read and write database or repository data.

Subclassing ATG Form Handlers

Oracle ATG Web Commerce form handler classes all implement the interface atg.droplet.DropletFormHandler. Three form handler base classes implement this interface:
·                     atg.droplet.EmptyFormHandler
·                     atg.droplet.GenericFormHandler
·                     atg.droplet.TransactionalFormHandler
EmptyFormHandler
atg.droplet.EmptyFormHandler implements the DropletFormHandler interface and provides empty implementations of the methods in this interface.
GenericFormHandler
atg.droplet.GenericFormHandler extends EmptyFormHandler. It provides simple implementations of DropletFormHandler interface methods and adds basic error handling logic. If errors occur in processing a form that uses GenericFormHandler, the errors are saved and exposed as properties of the form handler component. 
TransactionalFormHandler
atg.droplet.TransactionalFormHandler extends atg.droplet.GenericFormHandler; it treats the form processing operation as a transaction. Although this form handler methods are processed discretely, their results are saved simultaneously. The transaction management occurs in the beforeGet and afterGet methods. This establishes the transaction before any of properties are set or handler methods are called, rather than in the handler methods themselves.

Handler Methods

The handleX method is passed the request and response objects that encapsulate the request.

public boolean handleX (atg.servlet.DynamoHttpServletRequest request,
                        atg.servlet.DynamoHttpServletResponse response) throws IOException, ServletException
Handler Method Returns
The handler method returns a Boolean value, which indicates whether to continue processing the rest of the page after the handler is finished:
Return value
Action
false
No further values are processed process after the handler is called, and the rest of the page is not served. For example, a handler that redirects the user to another page should return false.
true
Normal processing of the remaining values continues, and the page specified by the form’s action attribute is served.
As mentioned earlier, Oracle ATG Web Commerce form handlers typically implement the interface DropletFormHandler. This interface has the following methods, which are called at specific points as the form is processed:
Method
When called:
beforeSet
Before any setX methods are called
afterSet
After all setX methods are called
beforeGet
Before any input tags that reference this component are rendered
afterGet
After page rendering is complete, before the socket is closed
handleFormException
If an exception occurs when trying to call the setX method of a form
The beforeGet and afterGet methods are called only when the page is rendered, not when the form is submitted. The beforeSet and afterSet methods are called only when the form is submitted, not when the page is rendered. It is possible to have all four of these methods called on the same page.
OOTB FormHandlers
ATG provides hundreds of readymade form handlers for performing all sorts of tasks, like
·         updating a customer profile(CommerceProfileFormHandler),
·         managing your shopping cart(CartModifierFormHandler),
·         checking out(ExpressCheckoutFormHandler), or
·         interacting with a repository(RepositoryFormHandler).
Following are the form handler component properties to handle form errors/exceptions:
·         formError --> Boolean that is set to true if any errors occur during form processing.

·         formExceptions  --> A vector of the exceptions that occur during form processing.  If your form handler is session-scoped, clear the formExceptions property after you display errors to the user.

·         propertyExceptions  --> A read-only property that returns a Dictionary of subproperties, one for each property set by the form. For each property that generates an exception, a corresponding subproperty in the propertyExceptions Dictionary contains that exception
Use the checkFormRedirect(String pSuccessURL, String pFailureURL, DynamoHttpServletRequest pRequest, DynamoHttpServletResponse pResponse) method of GenericFormHandler to redirect to a url from the formhandler on a success/error cases. A handler that redirects the user to another page should return false.
The atg.droplet.GenericFormHandler class (and any subclass of GenericFormHandler you write) includes a handleCancel method for implementing Cancel buttons in forms. This method redirects to the URL specified in the form handler’s cancelURL property.
When a dsp:setvalue tag is rendered for a form handler property, it invokes the setX and handleX methods of the form handler (if the methods exists).
A form handler component should be either request- scoped or session-scoped. When your form handler spans several pages, such as in a multi-page registration process, you want the session-scoped form handler. It is especially important to clear error messages to ensure they do not appear in other forms where they are not relevant.
5.    What is Droplet?
Droplets are the backbone of front-end content for all ATG applications.  A droplet allows dynamic content to be easily weaved into JavaServer Pages (JSPs).  Because droplets are easy to insert into JSPs, developers without Java knowledge can handle the rendering of dynamic content.
Out of the box, ATG comes with a large selection of droplets for most common tasks like iterations, repository lookups, page linking etc.  When these droplets don’t fit the requirement, customizations are necessary.  Fortunately, custom droplets are very easy to write. The focus of this post is to walk through the steps involved in creating a custom droplet.



Create a matching ATG component for the class.  The scope of the component should be global.
SayHelloDroplet.properties

$class=com.test.droplet.SayHelloDroplet
$scope=global
$description=Prints hello to the user

SayHelloDroplet.java
package com.test.droplet;

import atg.core.util.StringUtils;
import atg.servlet.DynamoHttpServletRequest;
import atg.servlet.DynamoHttpServletResponse;
import atg.servlet.DynamoServlet;
import atg.userprofiling.Profile;

import javax.servlet.ServletException;
import java.io.IOException;
import java.text.MessageFormat;

public class SayHelloDroplet extends DynamoServlet {

//input parameters
private static final String PARAM_PROFILE = “profile”;
private static final String PARAM_CURRENT_PAGE = “currentPage”;

//output parameters
private static final String PARAM_MESSAGE = “message”;
private static final String PARAM_ERROR_MESSAGE = “errorMsg”;

//open parameters
private static final String OPARAM_OUTPUT = “output”;
private static final String OPARAM_ERROR = “error”;

@Override
public void service(DynamoHttpServletRequest pRequest, DynamoHttpServletResponse pResponse)
throws ServletException, IOException {

Profile profile = (Profile) pRequest.getObjectParameter(PARAM_PROFILE);

if(profile == null) {
// render error
pRequest.setParameter(PARAM_ERROR_MESSAGE, “The passed in Profile was null.”);
pRequest.serviceParameter(OPARAM_ERROR, pRequest, pResponse);
} else {
String name = (String) profile.getPropertyValue(“firstName”);
if(StringUtils.isBlank(name)) {
name = profile.getRepositoryId();
}

String currentPage = pRequest.getParameter(PARAM_CURRENT_PAGE);

// render output
if(StringUtils.isBlank(currentPage)) {
pRequest.setParameter(PARAM_MESSAGE, MessageFormat.format(“Hello, {0}.”, name));
} else {
pRequest.setParameter(PARAM_MESSAGE, MessageFormat.format(“Hello, {0}, thanks for visiting {1}.”, name, currentPage));
}
pRequest.serviceParameter(OPARAM_OUTPUT, pRequest, pResponse);
}
}
}

sampleDroplet.jsp
<dsp:page>
    <h1>Sample Droplet</h1>
    <dsp:droplet name=”/test/droplet/SayHelloDroplet”>
        <dsp:param name=”profile” bean=”/atg/userprofiling/Profile”/>
        <dsp:param name=”currentPage” value=”sampleDroplet.jsp”/>
        <dsp:oparam name=”output”>
            <dsp:valueof param=”message”/>
        </dsp:oparam>
        <dsp:oparam name=”error”>
            Error: <dsp:valueof param=”errorMsg”/>
        </dsp:oparam>
    </dsp:droplet>
</dsp:page>

Input Parameters
Input parameters are an optional, but usually used, part of droplets.  They are the way to pass primitives or objects into the droplet.  In the example, the Profile object is the only input parameter.  Input parameters are passed to the droplet using the dsp:param tag from the dsp tag library using one of three variations:
·         Using the value tag to add a raw (or expression language) value: <dsp:param name=”myParam” value=”my value”/>
·         Using the paramtag to pass a page parameter by name: <dsp:param name=”myParam” param=”somePageParam”/>
·         Using the bean tag to use the value of an ATG component as in the example: <dsp:param name=”profile” bean=”/atg/userprofiling/Profile”/>.
Output Parameters


To set output parameters, use the pRequest.setParameter(String pParameterName, Object pValue) method.
Error: <dsp:valueof param=”errorMsg”/>
Open Parameters
Open parameters are executed one or many times during the droplet’s processing.  The Java code backing the droplet will determine which to show and when.  In the example, the error open parameter was serviced when the Profile passed in was null and the output parameter was shown when processing was successful.
Open parameters are indicated in the droplet by using dsp:oparam tags as shown below.

To service an open parameter, call the pRequest.serviceParameter(String pOpenParamName, pRequest, pResponse) method.  Remember, all parameters must be set before calling this method!
pRequest.serviceParameter(OPARAM_ERROR, pRequest, pResponse);
or
pRequest.serviceParameter(OPARAM_OUTPUT, pRequest, pResponse);
or you can use request.serviceLocalParameter("output", request, response);
Local Parameters
You might want to create parameters that are visible only locally to an ATG servlet bean.
In that case, use the getLocalParameter(String paramName) and serviceLocalParameter(String paramName, ServletRequest, ServletResponse) methods.
These methods return only values that are defined in the current frame for this invocation of the ATGservlet bean. This includes parameters passed to the ATG servlet bean between the open and close dsp:droplet tags and parameters defined at the top level of the called ATG servlet bean.
For example:
<dsp:param name="notLocalForA" value="x"/>
<dsp:droplet name="A">
<dsp:param name="localForA" value="y"/>
</dsp:droplet>

In this example notLocalForA is not local for the ATG servlet bean A, and localForA is local.

6.    Signature of all class, method related to Formhandlers/Droplet?
See Formhandlerand Droplet’s’s QA.


7.    What is Component?
Components in ATG are a public java class with appropriate properties with set/get methods. Additionally a component comes with .properties file that specify the class name and the scope and also any default values. The properties file also contains any dependency injections of other components. This .properties file must be placed under CONFIGPATH of the ATG.
The name of the component is the full path name of the .properties file under the configpath starting with a “/”. For example, /com/vam/firstbean. CONFIGPATH variable is computed dynamically during startup based on the modules started, their order of startup and based on the entry in the MANIFEST.MF file of every module started.
Use of components gives following advantages.
      Code reusability
      Reduced development time
      Container independent
      Entire application behavior can be changed by modifying one/some of the components.
Note: In ATG, a component have one of the 3 scopes i.e. Global, Session, Request.
Create / Modify Components

We can create / modify component and configure initial properties by

         Using the eclipse ATG component browser plug-in.
         Using ATG Control Center (ACC) browser.
         Manually by editing the .properties file.

Using any of the above approach, we can browse components, set properties (single and multi-value), link / unlink components.

Public Constructor with No Arguments

Nucleus can create a component automatically from a properties file only if the component class is declared public and it implements a public constructor with no arguments. 
Any Java class with a constructor that takes no arguments can be instantiated as a Nucleus component, which gives you a wide degree of latitude when you create component classes. However, these classes should implement certain interfaces that give components access to a number of Nucleus capabilities, such as automatic creation, configuration, and notifications.
The easiest way to implement these interfaces is to subclass atg.nucleus.GenericService, which implements all interfaces described in the following sections. However, your class might already extend some other class, thereby preventing you from extending GenericService. In this case, your class must implement the necessary interfaces.
Creating a HelloWorld component: That just appears in DynAdmin

HelloWorldComponent.java

package com.buddha.components;
 
import atg.nucleus.GenericService;
import atg.nucleus.ServiceException;
 
public class HelloWorldComponent extends GenericService {
 
    public String firstStr = "Dummy Value"; /* This value will be overwritten */
 
    public String getFirstStr() {
        return firstStr;
    }
 
    public void setFirstStr(String firstStr) {
        this.firstStr = firstStr;
    }
 
    @Override
    public void doStartService() throws ServiceException {
        super.doStartService();
        System.out.println("Hello ATG Component!");
    }
 
    @Override
    public void doStopService() throws ServiceException {
        super.doStopService();
        System.out.println("Hello ATG Component! Stops now!");
    }
}

Manifest.MF

Manifest-Version: 1.0
ATG-Required: DafEar.Admin 
ATG-Config-Path: config/
ATG-Class-Path: ./bin/ 

 

HelloWorldComponent.properties


$class=com.buddha.components.HelloWorldComponent
firstStr=HelloWorld

Build the project and copy the project folder into ${DYNAMO_ROOT} and run the following command to generate an ear file of your project and deploy it in your jboss server.
runAssembler.bat -jboss HelloWorld.ear -m EXP_HelloATGComponentWorld

Navigate to Dyn/Admin and search for the component HelloWorldComponent and click on the component listed in the search results.

You can observe the log as something like this 21:53:00,485 INFO  [stdout] (http-/0.0.0.0:8080-1:ipaddr=127.0.0.1;path=/dyn/admin/nucleus//com/buddha/components/HelloWorldComponent;sessionid=gT4bmHj5WKs1Rf85GN0Z+9Qu) Hello ATG Component! This line is generated because of the sysout in our doStartService();

8.    What is Scope of Component?
An application component can be set to one of the following scopes:
      Global: Component is shared among all users.
      Session: Separate instances of the component are provided to each user.
      Request: Separate instances of the component are provided to each active request.
      Window: Separate instances of the component are provided to each browser window.

A request-scoped component may have properties that point to objects of any scope. Dynamo correctly connects the request-scoped component to the appropriate component for that request.
On the other hand, global and session-scoped components should not have pointers to request-scoped components. This is because request-scoped components are constantly being created, destroyed, and shuffled around between requests. It is a very bad idea for anything other than another request-scoped object to hold onto a pointer for a request-scoped object.
Session Management
There is a very useful out of the box component named GenericSessionManager in ATG. GenericSessionManager component helps you to track down all session scope objects and it’s state.
The GenericSessionManager is an incredibly useful way to explore the values on a given session's profile.  View a list of active sessions in your instance, and then drill a profile's namespace to see what's been set.
a.    You can access the GenericSessionManager from the URI given below. (This is part of the ATG dyn admin component browser)
b.    Once you click on the view button, Session Manager will list out all the active sessions with in the application server.


9.    OOTB FormHandlers for Cart, Checkout, Profile?
Form Handler for Cart:
A customer adds an item to their shopping cart using CartModifierFormHandler, the submit button on the form submits to the handleAddItemToOrder method. Before any computation is done, the handleAddItemToOrder method invokes the preAddItemToOrder method. Additionally, after all computation is complete but before returning any information, the handleAddItemToOrder method invokes the postAddItemToOrder method.
By default these preXXX and postXXX methods have no functionality. They are provided so you can easily extend the form handlers to support additional functionality. However, be aware that these methods do not take any input parameters.
public class CartModifierFormHandler extends PurchaseProcessFormHandler
This formhandler is used to modify a ShoppingCart by adding items to it, deleting items from it, modifying the quantities of items in it, and preparing it for the checkout process.
Understanding the CartModifierFormHandler
The CartModifierFormHandler is used to add items to and remove items from an Order, modify the quantity of items in the Order, and prepare the Order for the checkout process.
CartModifierFormHandler is an instance of class atg.commerce.order.purchase.CartModifierFormHandler; it is located in Nucleus at /atg/commerce/order/purchase/CartModifierFormHandler.
Many of the methods (described below) in CartModifierFormHandler call OrderManager.updateOrder() to save the Order in its present state to the Order Repository. For information on OrderManager.updateOrder() and the updateOrder pipeline that it executes
Form Handler for Checkout:
The form handlers in /atg/commerce/order/purchase (CartModifierFormHandler, ShippingGroupFormHandler, PaymentGroupFormHandler, CommitOrderFormHandler, and ExpressCheckoutFormHandler) are the ones you should use to build your checkout process.
public class ExpressCheckoutFormHandler extends PurchaseProcessFormHandle
The ExpressCheckoutFormHAndler is used to expedite the checking out of an Order. This supports creating a maximum of one Profile derived HardgoodShippingGroup and one Profile derived CreditCard, followed by committing the Order. If the ExpressCheckoutFormHandler.PaymentGroupNeeded property is true then a CreditCard PaymentGroup will automatically be taken from the Profile. If false, then the user may supply the CreditCard information in a form through the ExpressCheckoutFormHandler.PaymentGroup property. If the ExpressCheckoutFormHandler.ShippingGroupNeeded property is true then a HardgoodShippingGroup will automatically be taken from the Profile. If false, then the user may supply the HardgoodShippingGroup information in a form through the ExpressCheckoutFormHandler.ShippingGroup property. If the ExpressCheckoutFormHandler.CommitOrder property is true, then the ExpressCheckoutFormHandler.ExpressCheckout handler will commit the Order. Set to false in order to display a confirmation page before committing the Order.

Preparing a Simple Order for Checkout
If your site supports the use of only a single HardgoodShippingGroup and a single CreditCard for a given Order, you can manage and expedite the pre-checkout process for Orders using the ExpressCheckoutFormHandler (class atg.commerce.order.purchase.ExpressCheckoutFormHandler). ExpressCheckoutFormHandler supports the use of a single Profile-derived HardgoodShippingGroup and a single Profile-derived CreditCard.
ATG Commerce provides an instance of ExpressCheckoutFormHandler, which is located in Nucleus at /atg/commerce/order/purchase/ExpressCheckoutFormHandler.
Methods:
      handleExpressCheckout
      runRepricingProcess
      commitOrder

Form Handler for Profile:

A ProfileFormHandler component can be request- or session-scoped. The default scope is request: each time a user accesses a page with a profile form, the ATG platform creates an instance of the ProfileFormHandler that uses the configured values of the component’s properties.

A ProfileFormHandler component can be request- or session-scoped. The default scope is request: each time a user accesses a page with a profile form, the ATG platform creates an instance of the ProfileFormHandler that uses the configured values of the component’s properties.

public class ProfileFormHandler extends ProfileForm
This class provides a convenient form handler for operating on the current user's profile. It can be used to add new profiles, edit the current profile, login (switch profiles based on login name and password) and logout.

ProfileFormHandler Submit Operations

The ProfileFormHandler supports the following operations that can be specified for form submission:
Operation
Function
cancel
Cancels any changes the user has made to values in the form but has not yet submitted.
changePassword
Changes the password property of the profile to the new value entered by the user.
clear
Clears the value Dictionary.
create
Creates a permanent profile and sets the profile properties to the values entered in the form.
delete
Deletes the current profile.
login
Uses the login and password values entered by the user to associate the correct profile with that user.
logout
Resets the profile to a new anonymous profile and optionally expires the current session.
update
Modifies the properties of the current profile.
For example, when a user logs into a site, a form can invoke the login operation as follows: <dsp:input bean="ProfileFormHandler.login" type="submit" value="Submit"/>
Each operation is associated with a handler method.
Profile Form Handler Extensions
The commerce DCS module sets the class of the /atg/userprofiling/ProfileFormHandler component as follows:
$class=atg.commerce.profile.CommerceProfileFormHandler
Note: This class extends the ScenarioProfileFormHandler which in turn extends the ProfileFormHandler.

The Oracle ATG Web Commerce profile form handler (atg.commerce.profile.CommerceProfileFormHandler) is a subclass of atg.userprofiling.ProfileFormHandler. It performs operations specific to Commerce. For example, an anonymous user can accumulate promotions in their activePromotions attribute. During login, the anonymous user’s active promotions are copied into the list of active promotions of the persistent user. During the registration and login process, any shopping carts (Orders) created before logging in are changed to be persistent.
If the user’s persistent profile contains any old shopping carts (Orders in an incomplete state), these shopping carts are loaded into the user’s session. After log in, the PricingModelHolder component is reinitialized to cache all the promotions that the persistent user has accumulated during previous sessions. These operations are performed by overriding the addPropertiesOnLogin, postCreateUser and postLoginUser methods from the ProfileFormHandler.
public class CommerceProfileFormHandler extends ScenarioProfileFormHandler
This form handler is a subclass of the DPS ProfileFormHandler to perform some operations that are specific to Commerce. The additional functionality includes:
      During a login operation the active promotions from the anonymous user are copied into the list of active promotions of the persistent user.
      After the login operation is finished the session-scope PricingModelHolder is reinitialized to cache all the promotions that the persistent user has accumulated.
      During the registration and login process any shopping carts (i.e. Orders) which were created while they were anonymous (and thus not persistent) are changed to be persistent.
      If the user logs in any old shopping carts (i.e. Orders in an INCOMPLETE state) are loaded into the user's session.
public class ScenarioProfileFormHandler extends ProfileFormHandler implements atg.scenario.ScenarioConstants, atg.scenario.targeting.SlotConstants
This form handler subclasses the DPS ProfileFormHandler and performs operations that are specific to the DSS layer.
Specifically, when a user logs in, if the session's transient user has any associated scenario instances, they are copied over to the persistent user's profile, provided that:
      the logged-in user does not possess an existing instance of that scenario/segment, OR
      the scenario/segment permits multiple instances per individual
This functionality allows scenarios to be continued across the login boundary.
In addition, when a user logs in and the session's transient user has persistent slot instances, they are copied over to the persistent user's profile, provided that:
      the logged-in user does not possess an existing instance of that persistent slot
This functionality also allows persistent slots to be continued across the login boundary.

10. Describe most commonly used FormHandlers in ATG.

Here are some of the commonly used FormHandlers, although ATG provides many out of the box FormHandlers and even we can write our own custom FormHandlers by extending GenericFormHandler class provided by ATG.
CartModifierFormHandler -- This formhandler is used to modify a ShoppingCart by adding items to it, deleting items from it, modifying the quantities of items in it, and preparing it for the checkout process.
ExpressCheckoutFormHandler -- The ExpressCheckoutFormHAndler is used to expedite the checking out of an Order. This supports creating a maximum of one Profile derived HardgoodShippingGroup and one Profile derived CreditCard, followed by committing the Order.
SaveOrderFormHandler -- The SaveOrderFormHandler is used to save the user's current Order based on a descriptive name that the user specifies. A new empty Order is then made the user's current shopping cart. If a descriptive name for the Order is not specified, then one is created based on the user's Locale and date and time.
ShippingGroupFormHandler -- The ShippingGroupFormHandler is used to associate ShippingGroups with the various Order pieces. This component is used during the Order checkout process, and any Order successfully processed by the ShippingGroupFormHandler is ready for the next checkout phase, which may be Payment.
PaymentGroupFormHandler -- The PaymentGroupFormHandler is used to associate PaymentGroups with the various Order pieces. This component is used during the Order checkout process, and any Order successfully processed by the PaymentGroupFormHandler is ready for the next checkout phase, which may be confirmation.
CommitOderFormHandler -- The CommitOrderFormHandler is used to submit the Order for final confirmation. This calls the OrderManager's processOrder method. If there are no errors with processing the Order, then the current Order in the user's ShoppingCart will be set to null and the submitted Order will become the ShoppingCart's last Order.
CancelOderFormHandler -- The CancelOrderFormHandler is used to cancel the user's current Order, which deletes the Order from the ShoppingCart.
RepositoryFromHandler -- Saves repository data to a database.
ProfileFormHandler -- Connects forms with user profiles stored in a profile repository.
SearchFormHandler -- Specifies properties available to a search engine.
SimpleSQLFormHandler -- Works with form data that is stored in a SQL database.



11. Formhandlers structures/hierarchy?

Subclassing ATG Form Handlers

Oracle ATG Web Commerce form handler classes all implement the interface atg.droplet.DropletFormHandler. Three form handler base classes implement this interface:
·                     atg.droplet.EmptyFormHandler
·                     atg.droplet.GenericFormHandler
·                     atg.droplet.TransactionalFormHandler
EmptyFormHandler
atg.droplet.EmptyFormHandler implements the DropletFormHandler interface and provides empty implementations of the methods in this interface.
GenericFormHandler
atg.droplet.GenericFormHandler extends EmptyFormHandler. It provides simple implementations of DropletFormHandler interface methods and adds basic error handling logic. If errors occur in processing a form that uses GenericFormHandler, the errors are saved and exposed as properties of the form handler component. 
TransactionalFormHandler
atg.droplet.TransactionalFormHandler extends atg.droplet.GenericFormHandler; it treats the form processing operation as a transaction. Although this form handler methods are processed discretely, their results are saved simultaneously. The transaction management occurs in the beforeGet and afterGet methods. This establishes the transaction before any of properties are set or handler methods are called, rather than in the handler methods themselves.

Transactions in Repository Form Handlers

A form handler that can manipulate repository items should ensure that all operations that occur in a handler method call are committed in a single transaction. Committing all operations simultaneously helps ensure data integrity. A repository or database transaction is completed successfully or not at all; partially committed data is rolled back if an error occurs mid-transaction.
The RepositoryFormHandler and TransactionalRepositoryFormHandler classes ensure atomic transactions in this way. If you subclass either class without overriding the handler methods, your subclass handles transactions properly. If you override any handler methods, or add new handler methods, you must make sure that these methods handle transactions properly.
Note: A form handler starts and ends a transaction only when no other active transactions are in progress. If a transaction is in progress, the form handler returns a status for each operation it attempts and permits the transaction to continue after the form handler itself finishes processing.
To create a form handler that works with repository items while a transaction is in progress:
a.    Create a form handler that subclasses RepositoryFormHandler or TransactionalRepositoryFormHandler, depending on your requirements. The source code for both form handlers is provided in
<ATG10dir>/DAS/src/Java/atg/repository/servlet
Both form handlers create a transaction if one is not already in progress and provide the status of all operations performed by the form handler while the transaction is in place. The two form handlers mainly differ in the transaction lifespan.
b.    Create methods on your new form handler that are transaction-aware
Note: RepositoryFormHandler and TransactionalRepositoryFormHandler are useful for manipulating repository items. The form handler class atg.droplet.TransactionFormHandler supports transactions and lets you work with the JDBC directly.
RepositoryFormHandler
atg.repository.servlet.RepositoryFormHandler is a base form handler that provides tools for creating, modifying, and deleting items stored in an SQL repository.
In the RepositoryFormhandler, the transaction is governed entirely by the submit handler method, meaning the transaction starts when a submit handler method is invoked and ends when it completes execution. Transaction status is reported for the data validation and the data commit operations.
TransactionalRepositoryFormHandler
The atg.repository.servlet.TransactionalRepositoryFormHandler, a subclass of the RepositoryFormhandler, provides enhanced transaction support by broadening the scope of the transaction. This class also defines a few additional properties that are useful for transaction monitoring. Oracle ATG Web Commerce Adaptive Scenario Engine does not include any instances of this class.
Transactions begin when the beforeSet method is invoked and end with the afterSet method. Because a transaction status is generated for all operations that occur during its execution, a status is recorded for each the following operations:
      beforeSet method execution
      Processing of all other tags in the JSP (tags that implement submit operations have the lowest priority on the page)
      Submit handler method data validation
      Submit handler method data commit
      afterSet method execution

12. What is Transaction-Aware Methods?
When you create a form handler that subclasses RepositoryFormHandler or TransactionalRepositoryFormHandler, make sure that its methods can correspond with the Transaction Manager. There are two ways to do this:
·         Base New Handler Methods on handleUpdate Source Code so that you can reuse the transaction code in it, then modify the rest accordingly.
·         Modify Existing Handler Methods by inserting code before or after their execution in the preX or postX methods, respectively.
Base New Handler Methods on handleUpdate Source Code
The code provided here implements the handleUpdate method. Create your own handler methods by making changes to this code sample and inserting it into your subclassed form handler:
public boolean handleUpdate(DynamoHttpServletRequest pRequest,
                            DynamoHttpServletResponse pResponse) throws ServletException, IOException {
 
  TransactionDemarcation td = getTransactionDemarcation();
  TransactionManager tm = getTransactionManager();
  try {
    if (tm != null) td.begin(tm, td.REQUIRED);
 
    int status = checkFormError(getUpdateErrorURL(), pRequest, pResponse);
    if (status != STATUS_SUCCESS) return status == STATUS_ERROR_STAY;
 
    // update the repository item
    preUpdateItem(pRequest, pResponse);
 
    if (!getFormError())
      updateItem(pRequest, pResponse);
 
    postUpdateItem(pRequest, pResponse);
 
    // try to redirect on errors
    if ((status = checkFormError(getUpdateErrorURL(), pRequest, pResponse))
     != STATUS_SUCCESS)
   return status == STATUS_ERROR_STAY;
 
    // try to redirect on success
    return checkFormSuccess(getUpdateSuccessURL(), pRequest, pResponse);
  }
  catch (TransactionDemarcationException e) {
    throw new ServletException(e);
  }
  finally {
   try { if (tm != null) td.end(); }
    catch (TransactionDemarcationException e) { }
  }
}
Modify Existing Handler Methods
The three existing submit handler methods (handleCreate, handleUpdate, and handleDelete) each provide a pair of empty pre and post methods where you can add custom code.
It is likely that you use either the preX or the postX method for a given existing handler method although you can customize both. For example, consider a subclass ofTransactionalRepositoryFormHandler where preUpdate and postUpdate are used:
a)    The form is rendered, which causes getX method to display current values for properties used in the form.
b)    The user fills in the form and submits it.
c)    The form handler’s beforeSet method is invoked. If a transaction is not currently in progress, the TransactionalRepositoryFormHandler component creates a one.
d)    If tag converters are used, they are applied to the specified content. Any form exceptions that occur now or at any point during the form handler execution are saved to the form handler’s formException property.
e)    The setX method is called, followed by the form handler’s handleUpdate method. Severe form exceptions might cause form processing to stop and the transaction to rollback, before redirecting users to a different page.
f)    The preUpdateItem method is invoked. The preX method for the handleUpdate method is preUpdateItem. Serious errors generated from this operation might also prompt the transaction to rollback.
g)    The updateItem method, which is the handleUpdate method responsible for processing the content and updating the database, is invoked. Again, this is another operation that can cause a transaction to rollback when serious errors are detected. At this point, the changes made by the actions associated with the transaction are kept private, meaning that they are only visible within the transaction itself.
h)    The postUpdateItem method is invoked. Again, the transaction is rolled back if serious errors are detected.
i)     The afterSet method is invoked. If the transaction was started by the beforeSet method, the transaction concludes and the content it saved to the database is publicly visible.
Use the preX method when you want to expand the constraints for data validation. For example, you might want to check if the user-entered zip code and country correspond to each other. The countries that use zip codes require them to be a certain length. The preX method can verify that a zip code uses the appropriate format for the country, before saving the zip code and country values to the database. Any discrepancies produce a form exception and roll back the transaction.
The postX method is useful for verifying user entered-data after that data has been converted by tag converters. For example, a form handler that saves credit card information might use a postX method to handle authorization. After that credit card number has been formatted correctly and all related information is updated in the database, the postX method executes. If the authorization fails, the transaction is rolled back, the original data refreshed, a form error exception is thrown, and the user is redirected to a page where the use can re-enter credit card information.
13. What is repository?
The ATG Repository API (atg.repository.*) is the foundation of persistent object storage, user profiling, and content targeting in ATG products. A repository is a data access layer that defines a generic representation of a data store.
ATG provides an easy to use and powerful object relational mapping (ORM) persistence framework. It supports numerous databases, including Oracle and DB2, as well as popular open source databases such as and MySQL. It uses reflection primarily to determine the java bean properties and does not need the developer to code any POJO also.
Repository
The data access layer that defines a generic representation of a data store. Repositories access the underlying data storage device through a connector, which translates the request into whatever calls are needed to access that particular data store. Connectors for relational databases and LDAP directories are provided out-of-the-box. Connectors use an open, published interface, so additional custom connectors can be added if necessary.

A repository is a collection of repository items. Each repository connects to a single data store. But application & subsystems in Dynamo can use different repositories or share the same repository.

The repository is not the data store itself instead, it is a collection of JavaBeans whose properties can be found and stored in the data store. The mission of the repository is to provide a mechanism to retrieve the data elements and a run-time representation of the available Meta information about each object.

Following are the main conceptual parts of the Repository API.
·         Repository Items - Each employee would have a corresponding repository item. Repository item is corresponding to row in database table. Repository item is made of properties. These properties correspond roughly to columns of a table
·         Item Descriptors - An employee item descriptor would specify all of the properties that an employee repository item could possess.
·         Repository Queries - An application can build queries that return the appropriate employee.

Repository Item
Repository items are like a JavaBeans. Their properties are determined dynamically at runtime. The properties in a particular repository item depend on the type of item. One item might represent the user profile (name, address, phone number) while another may represent the meta-data associated with a news article (author, keywords, synopsis). Each repository item is made of properties. These properties store the data that makes up a repository item. Each property has a name, such as id, firstName, or lastName etc. In the SQL repository, these properties correspond roughly to columns of a table. The properties available to a type of repository item are defined in the repository’s item descriptors.
So the purpose of the Repository interface system is to provide a unified way for data access. For example, developers can use targeting rules with the same syntax to find people or content. Each repository item must have an identifier, which is called a repository ID. The repository ID must uniquely identify the repository item from all other repository items of the same type. So each item descriptor must specify the columns that act as the repository ID (which will usually be the same as the table’s primary key. If we don’t define an id property in the item descriptor, then the id property must use the default data-type, which is string.
For example, In the SQL repository, a repository item often corresponds to a row in a table. In the SQL profile repository, each user profile is a repository item.
Types of Repository in ATG
The following Repository models exist in ATG.
a.    SQL Repositories - use ATG’s Generic SQL Adapter (GSA) connector to perform a mapping between ATG and data stored in a SQL database. It can be used to access content, user profiles, application security information, and more.
b.    LDAP Repository - Uses the Dynamo LDAP connector to access user data in an LDAP directory.
c.    Composite Repository - provides a means for using more than one data store as the source for a single repository.
d.    Versioned Repositories - an extension of the GSA used in ATG Publishing. This is to maintain versions of repository items.
Item Descriptor
Each repository item type is described by a Repository item descriptor (which has a one-to-one correlation with RepositoryView). The item descriptor gives a name to the type, and also describes the properties for that type. The name of each property is defined in the item descriptor, as well as the class of the Java object used to represent that type (Integer, String, etc.). The item descriptors exposed by a repository depend on a combination of the underlying data store and the configuration of the repository.
For example, In the SQL repository, each database table might have its own repository item descriptor. Or another alternative might join multiple tables into a single item descriptor. Also Repositories can support multiple item descriptors. For example, a SQL repository instance that supports a commerce application might have different item descriptors representing users, products, product categories, orders, etc.
An item descriptor implements the atg.repository.RepositoryItemDescriptor interface and may subclass atg.repository.ItemDescriptorImpl.
Item-Descriptor Relationships
      One to One – Represented by ‘auxiliary’ tables.
      One to Many – Represented by ‘multi’ tables
      Many to Many – achieved using an intermediate table.
The multi-column-name attribute ensures that the ordering of the multivalues are maintained.
The column specified by the multi-column-name attribute is used for multi-valued properties of data-types array, map, and list and is not used for sets (which are unordered). For map type properties, the values in the column specified by the multi-column-name attribute must be a string. For list or array type properties, these values should be an integer or numeric type, and must be sequential.
Advantages
ATG Data Anywhere Architecture offers several advantages over the standard data access methods such as Java Data Objects (JDO), Enterprise JavaBeans (EJB), and Java Database Connectivity (JDBC). Among the differences:
Data source independence
ATG Data Anywhere Architecture provides access to relational database management systems, LDAP directories, and file systems using the same interfaces. This insulates application developers from schema changes and also storage mechanism. Data can even move from a relational database to an LDAP directory without requiring recoding. Java Data Objects support data source independence, but it is up to vendors to provide an LDAP implementation.
Fewer lines of Java code
Less code leads to faster time-to-market and reduced maintenance cost. Persistent data types created with ATG Data Anywhere are described in an XML file, with no Java code required.
Unified view of all customer interactions
A unified view of customer data (gathered by web applications, call center applications, and ERP systems) can be provided without copying data into a central data source. This unified view of customer data leads to a coherent and consistent customer experience.
Maximum performance
Intelligent caching of data objects ensures excellent performance and timely, accurate results. The JDO and EJB standards rely on a vendor implementation of caching that might not be available.
Simplified transactional control
The key to overall system performance is minimizing the impact of transactions while maintaining the integrity of your data. In addition to full Java Transaction API (JTA) support, ATG Data Anywhere lets both page developers and software engineers control the scope of transactions with the same transactional modes—required, supports, never—used by EJB deployment engineers.
Fine-grained access control
You can control who has access to which data at the data type, data object, even down to the individual property with Access Control Lists (ACLs).
Integration with ATG product suites
ATG personalization, scenarios, commerce, portal, and content administration applications all make use of repositories for data access. A development team is free to use EJBs along side of ATG technology, but the easiest way to leverage investment in ATG technology is to follow the example set by the solution sets. The ATG solution sets satisfy all their data access needs with repositories.




14. How do you create custom repository?
Now create a property file which specifies the repository mapping xml file for your RDBMS.
Step 1. Analyse the Requirement.
From Above diagram, following points are collected.

a)    There are two separate OBJECTS, which can be clubbed together. So now these two Objects "Author" and "Book" will treated as Items (<item-descriptor>) under the one repository XML definition file.
b)    Identify the each Property under the each Object. Identify the Data Types of each. 

Step 2: Drawing in line repository structure.


Step 3: Creating the XML Definition file(with minimal required attributes) 

File Name: /my/library.xml

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<!DOCTYPE gsa-template
        PUBLIC "-//Art Technology Group, Inc.//DTD General SQL Adapter//EN"
        "http://www.atg.com/dtds/gsa/gsa_1.0.dtd">

<gsa-template>

  <header>
    <name>Library Repository</name>
    <author>Iranna</author>
  </header>
   
<item-descriptor name="author" display-name="author" >
   
    <table name="AUTHOR_MASTER" type="primary" id-column-name="author_id">
        <property name="id" column-name="author_id"/>
        <property name="firstName" column-name="first_name"
display-name="firstName" data-type="string"/>
        <property name="lastName" column-name="last_name"
display-name="lastName" data-type="string"/>
        <property name="dob" column-name="dob" display-name="dateOfBirth" data-type="date"/>
        <property name="gender" column-name="gender"
display-name="gender" data-type="enumerated">
                   <attribute name="useCodeForValue" value="true"/>
                   <option value="Male" code="101"/>
                   <option value="Female" code="202"/>
                   <option value="DontSpecify" code="303"/>
         </property>
    </table>
</item-descriptor>

<item-descriptor name="book" display-name="book" >
   
    <table name="BOOK_MASTER" type="primary" id-column-name="book_id">
        <property name="id" column-name="book_id"/>
        <property name="name" column-name="name" display-name="name" data-type="string"/>
        <property name="description" column-name="description"
display-name="description" data-type="big string"/>
        <property name="price" column-name="price" display-name="price" data-type="double"/>

        <property name="pages" column-name="pages" display-name="pages" data-type="int"/>
       <property name="available" column-name="available"
display-name="available" data-type="boolean"/> 
    </table>
</item-descriptor>

</gsa-template>
 

Step 4: Creating the Component for XML Definition file. 

Path: /my/Library.properties

$class=atg.adapter.gsa.GSARepository
$scope=global
repositoryName=Library

# database access- for making repositry as versioned, use SwitchingDataSource else use JTDataSource
dataSource=/atg/dynamo/service/jdbc/SwitchingDataSource
transactionManager=/atg/dynamo/transaction/TransactionManager

# our XML definitionFile
definitionFiles=/my/library.xml

# XML parsing
XMLToolsFactory=/atg/dynamo/service/xml/XMLToolsFactory

# id generation
idGenerator=/atg/dynamo/service/IdGenerator

transactionManager=/atg/dynamo/transaction/TransactionManager

dataSource=/atg/dynamo/service/jdbc/dataSourceFile
# The “dataSourceFile”  is yet another property file where the JDBC connections and database driver,server name, user, password etc are specified.
Step 5: Registering the Repository
The next step is to register our repository with dynamo by creating /config/atg/registry/ContentRepositories.properties
initialRepositories+=\                           
/playground/dummyRepository,\                       

15.  What are the cache modes in repository?

The SQL repository supports the following caching modes:
a.    Simple Caching handles caches in each server locally; no attempt is made to synchronize updates across multiple server instances.
b.    Locked Caching uses read and write locks to synchronize access to items stored by multiple caches.
c.    Distributed TCP Caching uses TCP to broadcast cache invalidation events to all servers in a cluster.
d.    Distributed JMS Caching uses JMS to broadcast cache invalidation events to all servers in a cluster.
e.    Distributed Hybrid Caching uses TCP to send cache invalidation events only to those servers that are known to cache the target items.

Setting Caching Mode

Caching modes are set at the item descriptor level, through the <item-descriptor> tag’s cache-mode attribute. The default caching mode is Simple Caching. To set a different caching mode on an item descriptor, set cache-mode to one of the following values:
      simple
      locked
      distributed (Distributed TCP Caching)
      distributedJMS (Distributed JMS Caching)
      distributedHybrid (Distributed Hybrid Caching)

Disabling Caching

You can disable caching for items of a specified type, or for specific item properties:
      To set an item type’s caching mode, set its <item-descriptor> tag’s cache-mode attribute to disabled.
      To disable caching for an individual property within an item descriptor, set the <property> tag’s cachemode attribute to disabled. Each property’s definition overrides the caching mode set for its item descriptor. For example:
<item-descriptor name="user" cache-mode="simple">            
  <table name="dps_user">                                                
    <property name="password" cache-mode="disabled">        
  ...                                                                                
  </table>                                                                       
  ...
Caution: If caching is disabled for an item type or individual item properties, any code that retrieves that item requires access to the database, which can noticeably degrade application performance.

Inherited Caching Modes

You can set a property to inherit the default caching mode by setting its cache-mode attribute to inherit. 

Simple Caching

When caching mode is set to simple, each server maintains its own cache in memory. A server obtains changes to an item’s persistent state only after the cached entry for that item is invalidated. This mode is suitable for read-only repositories such as product catalogs, where changes are confined to a staging server, and for architectures where only one server handles a given repository item type.

You can ensure that an item’s cached data is regularly refreshed by setting its item descriptor’s item-cache-timeout attribute.

Locked Caching

A multi-server application might require locked caching, where only one ATG instance at a time has write access to the cached data of a given item type. You can use locked caching to prevent multiple servers from trying to update the same item simultaneously.

<item-descriptor name="myItem" cache-mode="locked">

Locked caching has the following prerequisites:
      Item descriptors that specify locked caching must disable query caching by setting their query-cache-size attribute to 0.
      A repository with item descriptors that use locked caching must be configured to use a ClientLockManager component; otherwise, caching is disabled for those item descriptors. The repository’s lockManager property is set to a component of type atg.service.lockmanager.ClientLockManager.
      At least one ClientLockManager on each ATG instance where repositories participate in locked caching must be configured to use a ServerLockManager.
      A ServerLockManager component must be configured to manage the locks among participating ATG instances.

ClientLockManager

If an SQL repository contains item descriptors that use locked caching, set the Repository component’s lockManager property to a component of typeatg.service.lockmanager.ClientLockManager. ATG provides a default ClientLockManager component:

/atg/dynamo/service/ClientLockManager
Thus, you can set an SQL Repository’s lockManager property as follows:
lockManager=/atg/dynamo/service/ClientLockManager
ClientLockManager properties
A ClientLockManager component must be configured as follows:
Property
Setting
useLockServer
true enables this component to connect to a ServerLockManager
lockServerAddress
Host address of the ServerLockManager and, if set, the backup ServerLockManager
lockServerPort
The ports used on the ServerLockManager hosts, listed in the same order as inlockServerAddress
For example, given two ServerLockManagers on hosts tartini.acme-widgets.com and corelli.acme-widgets.com, where both use port 9010, the ClientLockManager is configured as follows:

$class=atg.service.lockmanager.ClientLockManager
lockServerAddress=tartini.acme-widgets.com,corelli.acme-widgets.com
lockServerPort=9010,9010
useLockServer=true

Note: The liveconfig configuration layer always sets useLockServer to true.

ServerLockManager

The server lock manager synchronizes locking among various ATG servers, so only one at a time can modify the same item. At least one ATG server must be configured to start the/atg/dynamo/service/ServerLockManager component on application startup.
To do this, add the ServerLockManager to the initialServices property of /atg/dynamo/service/Initial in the ServerLockManager server’s configuration layer. For example:
<ATG9dir>/home/localconfig/atg/dynamo/service/Initial.properties
This properties file sets the initialServices property as follows:

#/home/localconfig/atg/dynamo/service/Initial.properties:
 
initialServices+=ServerLockManager
ServerLockManager properties
A ServerLockManager component is configured with the following properties:

Property
Description
port
This server’s port
otherLockServerAddress
The other ServerLockManager’s address
otherLockServerPort
The port of the ServerLockManager specified in otherLockServerAddress
otherServerPollInterval
The interval in milliseconds that this server waits before polling the server specified inotherLockServerAddress
waitTimeBeforeSwitchingFromBackup
The time in milliseconds that this server waits after detecting that the primary ServerLockManager has failed, before taking over as the primary ServerLockManager

For example, given ServerLockManagers tartini.acme-widgets.com and corelli.acmewidgets.com running on port 9010, their respective configurations might look like this:

# tartini:9010
$class=atg.service.lockmanager.ServerLockManager
port=9010
otherLockServerAddress=corelli.acme-widgets.com
otherLockServerPort=9010
otherServerPollInterval=2000
waitTimeBeforeSwitchingFromBackup=10000
 
 
# corelli:9010
$class=atg.service.lockmanager.ServerLockManager
port=9010
otherLockServerAddress=tartini.acme-widgets.com
otherLockServerPort=9010
otherServerPollInterval=2000
waitTimeBeforeSwitchingFromBackup=10000

Distributed TCP Caching

If an application modifies an item whose item descriptor specifies distributed TCP caching mode, a cache invalidation event is broadcast from that ATG instance to all other ATG instances that use distributed TCP caching. The event message supplies the nature of the change, the changed item’s type, and repository ID. Receiving repositories respond by invalidating that cached item.
Distributed TCP caching is suitable for sites where the following conditions are true:
      Items of a type that specifies distributed TCP caching are likely to be cached across most ATG instances in the application.
      Items are subject to frequent reads.
      Items are rarely changed, added or deleted.
An item that changes frequently—say, more than 50 or 100 times per second —is not suitable for distributed TCP caching mode, because the extra network activity incurred by cache invalidation messages outweighs caching benefits. Cache invalidation events are broadcast to all ATG instances that enable distributed caching, even if they do not cache the invalidated item; as the number of these ATG instances increases, so too increases the network activity associated with each cache invalidation event.
Event server components of class atg.adapter.gsa.event.GSAEventServer send and receive cache invalidation events over TCP among participating ATG instances.
gsa_subscriber_table maintains routing information for each item descriptor that uses distributed TCP caching: its repository path, and the address and port of that repository’s event server.

Distributed JMS Caching

When an item descriptor’s caching mode is set to distributedJMS , all cache invalidation events sent for items of that type use JMS, which persists cache invalidation event messages in the SQL database until delivery is complete.
By contrast, Distributed TCP Caching cannot guarantee that all servers receive cache invalidation events.

Distributed Hybrid Caching

Distributed hybrid caching provides intelligent cache invalidation across multiple ATG instances. Unlike distributed JMS and TCP caching, which broadcast invalidation events to all participating servers, distributed hybrid caching sends invalidation events only to servers where the items are cached, which can significantly reduce network traffic.

Simple versus Distributed Caching

Simple caching mode is generally sufficient if site users do not require immediate access to recent item changes. You can use item descriptor attributes item-expire-timeout andqueryexpiretimeout to specify how long items can stay in the item and query caches, respectively, before they are invalidated. For many multi-server sites, setting this attribute to a low threshold provides a reasonable response time to item changes, while avoiding the network overhead incurred by distributed caching modes—especially Distributed TCP Cachingand Distributed JMS Caching.

16. What is item cache, query cache?
For each item descriptor, an SQL repository generally maintains two caches:
      Item Caches
      Query Caches

Item Caches

Item caches hold the values of repository items, indexed by repository IDs. Item caching can be explicitly enabled for each item descriptor. Even if caching is explicitly disabled, item caching occurs within the scope of each transaction (see Disabling Caching).
An item cache entry is invalidated when that item is updated. The scope of an entry’s invalidation depends on its caching mode. For example, when an item is changed under simple caching mode, only the local cache entry is invalidated; other Oracle ATG Web Commerce instances are not notified. Oracle ATG Web Commerce provides several different Distributed Caching Modes to invalidate items across multiple instances.

Query Caches

Query caches hold the repository IDs of items that match given queries. When a query returns repository items whose item descriptor enables query caching, the result set is cached as follows:
      The query cache stores the repository IDs.
      The item cache stores the corresponding repository items.
Note: Queries that include derived item properties are never cached.
17. What is ATG Cache Flushing?
You can flush (invalidate) the caches for an item descriptor or an entire SQL repository, using the following methods. Note that first, you must cast youratg.repository.RepositoryItemDescriptor to an atg.repository.ItemDescriptorImpl. If you are using distributed cache mode, use the Cache Invalidator, as described in theCache Invalidation Service section below.
The methods in atg.repository.ItemDescriptorImpl are:
invalidateItemCache()
Invalidates the item caches for this item descriptor.
invalidateCaches()
Invalidates both the item and query caches for this item descriptor.
removeItemFromCache(String pId)
Removes the specified item from any repository caches
These methods also have versions that accept a boolean parameter that indicates whether the cache should be changed globally, or just for the local cache. These methods are:
removeItemFromCache(id, boolean pGlobal)
invalidateCaches(boolean pGlobal)
invalidateItemCache(boolean pGlobal)
If this global parameter is true, the invalidation occurs across the cluster. Otherwise, the invalidation occurs only in the local ATG instance.
The removeItemFromCache method, when given a true value, will use one of two mechanisms to distribute the invalidation event:
      If the item descriptor uses distributed cache mode, it uses the event server to send the invalidation event.
      Otherwise, it uses the GSAInvalidatorService to send the event.
The invalidateCaches and invalidateItemCache methods, when given true for the global parameter, will always use the GSAInvalidatorService. If this service is not enabled, a warning is logged and the cache is only invalidated locally.
This method in atg.repository.RepositoryImpl affects all caches in the repository:
invalidateCaches()
Invalidates all caches in this repository.
You can cast your repository to these classes and call these methods from there. You can both flush items of a specific kind, items and queries of a specific kind or a specific item with these methods.
For example, here is how you might use the invalidateItemCache() method to invalidate the item caches for every item descriptor in a repository:
RepositoryImpl rep = getRepository();
String[] descriptorNames = getItemDescriptorNames();
// iterate over all the descriptors
for (int i=0; i<descriptorNames.length; i++) {
            String name = descriptorNames[i];
            ItemDescriptorImpl d = (ItemDescriptorImpl)rep.getItemDescriptor(name);
            d.invalidateItemCache();
}

Flushing Item Caches

Flushing Item Caches

The class atg.repository.ItemDescriptorImpl provides three methods that can be called on an item descriptor in order to flush its cache. Each method provides an overloaded version with a boolean parameter, where an argument of true specifies to invoke the method across the entire cluster; an argument of false limits the flush operation to the local repository.
Note: If the item descriptor is set to distributed hybrid caching, any action on the local repository is propagated to other ATG instances, whether invoked by the boolean or non-boolean method version.
In order to use these methods, atg.repository.RepositoryItemDescriptor must be cast to atg.repository.ItemDescriptorImpl.
invalidateItemCache()
Invalidates item caches for this item descriptor:
void invalidateItemCache()
void invalidateItemCache(boolean pGlobal)
For example:

RepositoryImpl rep = getRepository();
ItemDescriptorImpl d = (ItemDescriptorImpl)rep.getItemDescriptor("user");
d.invalidateItemCache();

Note: This method’s boolean has no affect on remote item caches that use distributed TCP caching; it only invalidates the local item cache.
invalidateCaches()
Invalidates item and query caches for this item descriptor:
void invalidateCaches()
void invalidateCaches(boolean pGlobal)
removeItemFromCache()
Removes the specified item from the cache:
void removeItemFromCache(String pId)
void removeItemFromCache(String pId, boolean pGlobal)
void removeItemFromCache(String pId, boolean pGlobal, boolean pRemoveTransientProperties)

Flushing Query Caches

The class atg.repository.RepositoryViewImpl provides the method invalidateQueryCache(), which clears the query cache:
public void invalidateQueryCache()



18. Relationship in repository? How do you implement M2M relationship?
Item-Descriptor Relationships
      One to One – Represented by ‘auxiliary’ tables.
      One to Many – Represented by ‘multi’ tables
      Many to Many – achieved using an intermediate table.
The multi-column-name attribute ensures that the ordering of the multi values are maintained.

Primary Tables

Each item descriptor must specify one primary table. The primary table is specified with the type="primary" XML attribute in a <table> tag. The <table> tag for the primary table sets its id-column-names attribute to the columns that store the repository ID. For example:
<table name="user" type="primary" id-column-names="id">
    properties...
</table>

Auxiliary Tables

You can handle some data relationships with auxiliary attribute tables. For example, you can store users and their addresses in two related database tables, as described in the following piece of an XML repository definition:

<item-descriptor name="user">
  <table name="dps_user" type="primary" id-column-names="id">
    <property name="login" data-type="string"/>
  </table>
  <table name="dps_address" type="auxiliary" id-column-names="id">
    <property name="address1"/>
    <property name="city"/>
    <property name="state"/>
    <property name="zip"/>
  </table>
</item-descriptor>

Each user has a single address. For the purposes of this example, the user information is stored in a separate table from the user’s address information.
Note: that if you use auxiliary tables, each table definition, whether primary or not, must define an id-column-names attribute. This attribute defines the column names in the table that represent the repository ID. This indicates how to join auxiliary tables to the primary table. The columns in the id-column-names attribute must be listed in the same order as they are in the id-column-names attribute of the primary table.
Multi Tables
The following example shows how the XML repository definition might specify the multi-valued property interests:
<item-descriptor name="user">
  <table name="dps_user" id-column-names="id" type="primary">
    <property name="login" data-type="string"/>
  </table>
  <table name="dps_interest" type="multi" id-column-names="id"
         multi-column-name="idx">
    <property name="interests" column-name="interest" data-type="array"
              component-data-type="string"/>
    </table>
</item-descriptor>
Some examples demonstrate a variety of data relationship mappings

Simple One-to-One

This example maps a repository item to a single table row. It includes just a primary table, with no joins with other tables.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE gsa-template
  PUBLIC "-//Art Technology Group, Inc.//DTD Dynamo Security//EN"
         "http://www.atg.com/dtds/gsa/gsa_1.0.dtd">
 
<gsa-template>
    <header>
      <name>Repository Example Version A</name>
      <author>Pat Durante</author>
      <description>
         This template maps a repository item to a single
         table row.  Just a primary table...no joins with
         other tables.  Simplest case.
      </description>
    </header>
 
    <item-descriptor name="user" default="true">
       <table name="usr_tbl" type="primary" id-column-names="id">
          <property name="id" data-type="string"/>
          <property name="name" column-names="nam_col" data-type="string"/>
          <property name="age" column-names="age_col" data-type="int"/>
       </table>
    </item-descriptor>
</gsa-template>
SQL Statements
drop table usr_tbl;
 
CREATE TABLE usr_tbl (
        id                      VARCHAR(32)     not null,
        nam_col                 VARCHAR(32)     null,
        age_col                 INTEGER null,
        primary key(id)
);

One-to-One with Auxiliary Table

This example maps a repository item to a primary table and an auxiliary table (a one-to-one relationship).
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE gsa-template
  PUBLIC "-//Art Technology Group, Inc.//DTD Dynamo Security//EN"
         "http://www.atg.com/dtds/gsa/gsa_1.0.dtd">
 
<gsa-template>
    <header>
      <name>Repository Example Version B</name>
      <author>Pat Durante</author>
      <description>
         This template maps a repository item to a
         primary table and an auxiliary table (a one-to-one
         relationship.)  Each user has a job title and
         function.
      </description>
    </header>
 
    <item-descriptor name="user" default="true">
       <table name="usr_tbl" type="primary" id-column-names="id">
          <property name="id" data-type="string"/>
          <property name="name" column-names="nam_col" data-type="string"/>
          <property name="age" column-names="age_col" data-type="int"/>
       </table>
 
       <table name="job_tbl" type="auxiliary" id-column-names="id">
          <property name="function"/>
          <property name="title"/>
       </table>
    </item-descriptor>
</gsa-template>
SQL Statements
drop table usr_tbl;
drop table job_tbl;
 
CREATE TABLE usr_tbl (
        id                      VARCHAR(32)     not null,
        nam_col                 VARCHAR(32)     null,
        age_col                 INTEGER null,
        primary key(id)
);
 
CREATE TABLE job_tbl (
        id                      VARCHAR(32)     not null references usr_tbl(id),
        function                VARCHAR(32)     null,
        title                   VARCHAR(32)     null,
        primary key(id)
);


One-to-Many Mapping to Other Repository Items

This example maps out a one-to-many relationship between user items and address items. It demonstrates the use of the component-item-type attribute, which allows one repository item to contain other repository items. Each user item can contain many address items, such as home address, shipping address, business address.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE gsa-template
PUBLIC "-//Art Technology Group, Inc.//DTD Dynamo Security//EN"
"http://www.atg.com/dtds/gsa/gsa_1.0.dtd">
<gsa-template>
  <header>
    <name>Repository Mapping Example Version F</name>
    <author>Ben Erwin</author>
    <description>
This template maps out a one-to-many relationship
between user items and address items. It
demonstrates the use of the component-item-type
attribute (which allows one repository item
to contain other repository items.) Each user
item will contain many address items (home address,
business address, etc.)
    </description>
  </header>
  <item-descriptor name="address">
    <table name="addr_tbl" type="primary" id-column-name="addr_id">
        <property name="user" column-name="user_id" item-type="user"/>
        <property name="street" data-type="string"/>
        <property name="city" data-type="string"/>
    </table>
  </item-descriptor>
  <item-descriptor name="user" default="true">
    <table name="usr_tbl" type="primary" id-column-name="id">
        <property name="id" data-type="string"/>
        <property name="name" column-name="nam_col" data-type="string"/>
        <property name="age" column-name="age_col" data-type="string"/>
    </table>
    <table name="addr_tbl" type="multi" id-column-name="user_id">
        <property name="addresses" column-name="addr_id" data-type="set"
                  component-item-type="address"/>
    </table>
  </item-descriptor>
</gsa-template>
SQL Statements
CREATE TABLE usr_tbl (
  id VARCHAR(32) not null,
  nam_col VARCHAR(32) null,
  age_col VARCHAR(32) null,
  primary key(id)
);
 
CREATE TABLE addr_tbl (
  addr_id VARCHAR(32) not null,
  user_id VARCHAR(32) null references usr_tbl(id),
  street VARCHAR(32) null,
  city VARCHAR(32) null,
  primary key(addr_id)
);

Many-to-Many

This example maps out a many-to-many relationship. It defines two item types, user and address. Each user can have many addresses. Many users may live at the same address.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE gsa-template
  PUBLIC "-//Art Technology Group, Inc.//DTD Dynamo Security//EN"
         "http://www.atg.com/dtds/gsa/gsa_1.0.dtd">
 
<gsa-template>
    <header>
      <name>People Repository Version H</name>
      <author>Pat Durante</author>
      <description>
        This template maps out a many-to-many relationship
        between user items and address items.  Each user can
        have many addresses.  Many users may live at the
        same address.
      </description>
    </header>
 
  <item-descriptor name="address">
    <table name="addr_tbl" type="primary" id-column-names="address_id">
        <property name="street" data-type="string"/>
        <property name="city" data-type="string"/>
    </table>
 
    <table name="user_address_tbl" type="multi" id-column-names="addr_id">
        <property name="users" column-names="user_id" data-type="set"
                  component-item-type="user"/>
    </table>
  </item-descriptor>
 
  <item-descriptor name="user" default="true">
    <table name="usr_tbl" type="primary" id-column-names="id">
        <property name="id" data-type="string"/>
        <property name="name" column-names="nam_col" data-type="string"/>
        <property name="age" column-names="age_col" data-type="int"/>
    </table>
 
    <table name="user_address_tbl" type="multi" id-column-names="user_id">
        <property name="addresses" column-names="addr_id" data-type="set"
                  component-item-type="address"/>
    </table>
  </item-descriptor>
</gsa-template>
SQL Statements
drop table addr_tbl;
drop table user_address_tbl;
drop table usr_tbl;
 
CREATE TABLE addr_tbl (
     address_id        VARCHAR(32)      not null,
     street            VARCHAR(32)      null,
     city              VARCHAR(32)      null,
     primary key(addr_id)
);
CREATE TABLE user_address_tbl (
     addr_id            VARCHAR(32)     not null references addr_tbl(address_id),
     user_id            VARCHAR(32)     not null references usr_tbl(id),
     primary key(addr_id, user_id)
);
 
CREATE INDEX user_address_tbl_user_idx ON user_address_tbl(user_id);
 
CREATE TABLE usr_tbl (
     id                 VARCHAR(32)     not null,
     nam_col            VARCHAR(32)     null,
     age_col            INTEGER     null,
     primary key(id)
);

19. What is item-expire-timeout, query-expire-timeout and item-cache-timeout?

Cache Timeout

An item descriptor can limit the lifetime of cached items in two ways:
Force refreshes of items in the item and query caches
An item descriptor’s item-expire-timeout and query-expire-timeout attributes specify how long items can stay in the item and query caches, respectively, before they are invalidated. For example, if the item-expire-timeout for a cached item is set to 60000 (milliseconds), its data becomes stale after 60 seconds; and the item must be reloaded from the database when it is next accessed.
The following item-descriptor tag sets attributes item-expire-timeout and query-expire-timeout to 180 seconds:
<item-descriptor name="order" cache-mode="simple"
      item-expire-timeout="180000"
      query-expire-timeout="180000">
...
</item-descriptor>
Refresh unused item cache entries
An item cache entry is regarded as stale if it is not accessed within the time span specified in its item-cache-timeout attribute. A stale item must be reloaded from the database the next time it is accessed. If set to 0 (the default), the item can remain indefinitely in the item cache until it is otherwise invalidated.
The following item-descriptor tag sets attribute item-cache-timeout to 180 seconds:
<item-descriptor name="order" cache-mode="simple"
                 item-cache-timeout="180000">
...
</item-descriptor>
You can use cache timeout attributes together with simple caching to control the behavior of repository caches. Cache timeout attributes are useful for caching user data associated with a particular session. A user session is typically handled by a single ATG server for as long as the session lasts. If the user session expires and the user moves to another ATG server, the cached data expires before the user can log back on to a server that might have previously cached stale data for that user.

Cache Configuration


The SQL repository maintains separate item caches and query caches for unrelated item descriptors. Thus, each one can be configured independently.
Item cache attributes
You can configure item caches with the following <item-descriptor> attributes:
Attribute
Description
item-cache-size
The maximum number of items of this type to store in the item cache. When this maximum is exceeded, the oldest items are removed from the cache.
Note: Within an inheritance tree, the last-read item descriptor’s item-cache-size setting applies to all item descriptors within the inheritance tree. In order to ensure the desired item cache size, be sure to assign the same item-cache-size to all related item descriptors
Default: 1000
item-expire-timeout
The maximum time in milliseconds that an entry can remain in the item cache before its content becomes stale. After turning stale, the item cache entry is reloaded from the database the next time it is accessed. See Cache Timeout for more information.
Default 0 (items remain cached indefinitely or until invalidated)
item-cache-timeout
The time in milliseconds that an item cache entry can remain unused before its content becomes stale. After turning stale, the item cache entry is reloaded from the database the next time it is accessed. See Cache Timeout for more information.
Default: 0 (items remain cached indefinitely or until invalidated)
Query cache attributes
You can configure query caches with the following <item-descriptor> attributes:
Attribute
Description
query-cache-size
The maximum number of queries for items of this type to store in the query cache. When this maximum is exceeded, the oldest queries are removed from the cache.
Default: 0
query-expire-timeout
The maximum time in milliseconds that an entry can remain in the query cache before its content becomes stale. After turning stale, the result set is reloaded from the database the next time the entry is accessed. See Cache Timeout for more information.
Default: 0 (items remain cached indefinitely or until invalidated)


20. What is Property Descriptor, Derived Property?
Property Descriptor:
Suppose we have an item-descriptor “contact” in which we are storing firstName,lastName and title and we need to concatenate  these three values while displaying in the front end.To implement this,
      getPropertyValue method of RepositoryPropertyDescriptor needs  to be overridden to implement the logic.
      In the repository definition,the value of property-type attribute  of displayContactName property which is a transient property  is the Qualified class path of the implementation class.
<item-descriptor name="contact"  display-property="displayContactName">
<property name="displayContactName" data-type="string"
            property-type="com.contact.ContactDisplayName" queryable="false" />
<table name="CONTACT_INFO" id-column-names="CONTACT_ID" type="primary">
<property name="firstName" column-name="FNAME"
data-type="string"  required="true"  />
                   <property name="lastName" column-name="LNAME" required="true" />
                   <property name="title" column-name="TITLE" required="true" />
</table>
</item-descriptor>

public class ContactDisplayName extends RepositoryPropertyDescriptor {
@Override
public Object getPropertyValue(RepositoryItemImpl pItem, Object pValue) {

//pItem is nothing but contact repository item
StringBuilder displayName = new StringBuilder();
//getting the title repository value
String title =
//getting the firstName repository value
String fname = (String) pItem.getPropertyValue("firstName");
//getting the lastName repository value
String lname = (String) pItem.getPropertyValue("lastName");

displayName = displayName.append((String) pItem.getPropertyValue("title").
append (".").append( (String) pItem.getPropertyValue("firstName")).append(" ").
append((String) pItem.getPropertyValue("lastName"))

return displayName.toString();
}

}

See Another Example for Property Descriptor: 

Derived Property

In an SQL repository, you can use derived properties. This feature enables one repository item to derive property values from another repository item or from another property in the same repository item. To illustrate: some data models are organized in a tree structure where certain property values are passed down from other properties. For example, an organization might have divisions, departments, and employees, organized in a tree structure. A repository represents this tree structure with division, department, and employeeitem descriptors. Each of these item descriptors might define a property called spendingLimit. A business rule might specify that an employee’s spending limit comes from their department if it is not set for that employee. If the spending limit is not set for the department it should be derived from the spending limit for the division.
This derived property relationship is represented in a repository definition file as follows:

<item-descriptor name="employee">
   <property name="department" item-type="department"/>
   <property name="empSpendingLimit" data-type="int"/>
   <property name="spendingLimit" writable="false">
     <derivation>
       <expression>empSpendingLimit</expression>
       <expression>department.spendingLimit</expression>
     </derivation>
   </property>
 </item-descriptor>
 
<item-descriptor name="department">
   <property name="division" item-type="division"/>
   <property name="deptSpendingLimit" data-type="int"/>
   <property name="spendingLimit" writable="false">
     <derivation>
       <expression>deptSpendingLimit</expression>
       <expression>division.divSpendingLimit</expression>
     </derivation>
   </property>
 </item-descriptor>
 
<item-descriptor name="division">
   <property name="division" item-type="division"/>
   <property name="divSpendingLimit" data-type="int"/>
</item-descriptor>

Note: When it is requested, the value of empSpendingLimit is returned if it is non-null; otherwise, department.spendingLimit is returned.
Derived properties can use multiple levels of subproperties. So the spending limit example might derive the employee’s spending limit as follows:

<item-descriptor name="employee">
  <property name="department" item-type="department"/>
  <property name="spendingLimit" data-type="int" writable="false">
    <derivation>
      <expression>department.employeeDefaultInfo.spendingLimit</expression>
    </derivation>
  </property>
</item-descriptor>

<item-descriptor name="department">
   <property name="employeeDefaultInfo" item-type="employeeInfo"/>
   <property name="deptSpendingLimit" data-type="int"/>
 </item-descriptor>

<item-descriptor name="employeeInfo">
  <property name="spendingLimit" data-type="int" writable="false"/>
  <property name="officeLocation" data-type="string"/>
</item-descriptor>




21. What is Request handling pipeline? Types of pipeline?

One of the most important tasks for an Oracle ATG Web Commerce server is handling HTTP requests. The Oracle ATG Web Commerce server extends the basic web server model with various Nucleus services that implement the Servlet interface, and which are linked in order to process HTTP requests. Each servlet performs a specialized function on a request, then relays the request—sometimes in modified form—to the next servlet in the chain. While each servlet performs a unique service, it often relies on changes that previous servlets made to the request. This chain of servlets is called a request handling pipeline.
There are two request-handling pipelines used by Dynamo.
·         DAF Servlet Pipeline - It is used to handle the JSP request.
·         DAS Servlet pipeline - It is used to handle JHTML request.

Starting the Request-Handling Pipeline

The second resource called by the Web container executes the request-handling pipeline. The resource you specify here depends on the type of pages you author:
·         For JSPs, specify the PageFilter filter.
·         For JHTML pages, specify the DynamoProxyServlet servlet.
Both PageFilter and DynamoProxyServlet call an instance of DynamoHandler, which is the first servlet in the pipeline. DynamoHandlergenerates a DynamoHTTPServletRequest(called the Dynamo request) that wraps the generic HTTPServletRequest so that servlets are able to read information on the request as well as modify the request itself. A matching DynamoHTTPServletResponse is also generated. DynamoHandler passes the Dynamo request/response pair to the next servlet in the request-handling pipeline. This pipeline is a series of servlets that share dynamic information about the request and response with the Nucleus framework in order to render the requested page.
Although DynamoHandler chiefly does the same thing in both pipelines, a different version of it is used for each request type.
·         PageFilter calls /atg/dynamo/servlet/dafpipeline/DynamoHandler to start the DAF servlet pipeline for JSP requests.
·         DynamoProxyServlet calls /atg/dynamo/servlet/pipeline/DynamoHandler to start the DAS servlet pipeline for JHTML requests.
The main difference between the DAS and DAF servlet pipelines is that the DAS servlet pipeline automatically compiles the page from JHTML to Java, whereas the DAF servlet pipeline relies on the application server to handle the complete page compilation process.
Sites that use JSPs: PageFilter
When your site uses JSPs, include PageFilter in web.xml:
·         Insert the filter name and class name in enclosing <filter> tags.
·         Map the filter to either a directory holding JSPs or the .jsp extension. This information is included in enclosing <filtermapping> tags.
This example shows the code you should include in web.xml:

<filter>
 <filter-name>PageFilter</filter-name>
 <filter-class>atg.filter.dspjsp.PageFilter</filter-class>
</filter>
<filter-mapping>
 <filter-name>PageFilter</filter-name>
 <url-pattern>*.jsp</url-pattern>
</filter-mapping>
Sites that use JHTML Pages: DynamoProxyServlet
To use DynamoProxyServlet in web.xml:
·         Insert the servlet name, class, and execution order in enclosing <servlet> tags. The order of execution should be 2, so that DynamoProxyServlet runs just afterNucleusServlet.
·         Map this servlet either to the directory holding JHTML files or to the extension .jhtml. This information is provided in enclosing <servletmapping> tags.
This example shows the code you should include in web.xml:
<servlet>
  <servlet-name>DynamoProxyServlet</servlet-name>
  <servlet-class>atg.nucleus.servlet.NucleusProxyServlet</servlet-class>
  <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
  <servlet-name>DynamoProxyServlet</servlet-name>
  <url-pattern>/dyn/*</url-pattern>
</servlet-mapping>
Sites that Use JSPs and JHTML Pages
For sites using both JSP and JHTML pages, you need to define both PageFilter and DynamoProxyServlet resources in your web.xml so they are available when needed. For each request, one of the two resources is called just after NucleusServlet.

Request Processing


By default, PageFilter is mapped to handle JSP requests. When the application server invokes PageFilter, it checks the request and response for a reference to a Dynamo request and response pair. The pair does not exist, so PageFilter starts the DAF servlet pipeline by calling DynamoHandler, the first servlet in the pipeline. The DAF servlet pipeline processes through a series of servlets that modify the request and response by extracting path information and providing session, user, and security information. The last servlet in the pipeline is TailPipelineServlet. It is responsible for calling FilterChain.doFilter(), which invokes the next filter defined inweb.xml. The web application, unless it uses Oracle ATG Web Commerce Portal, does not include other servlet filters.
You can use the ATG Dynamo Server Admin Component Browser to view request handling pipeline servlets and their sequence within the pipeline:
a)    In the Component Browser (http://host:port/dyn/admin/nucleus/), navigate to the first pipeline servlet:        /atg/dynamo/servlet/dafpipeline/DynamoHandler
b)    The Component Browser lists all pipeline servlets in order of execution.


22. Customizing request handling pipeline?

The atg.servlet.pipeline package provides interfaces for creating request handling pipeline servlets. All pipeline servlet classes directly or indirectly implement interfaceatg.servlet.pipeline.PipelineableServlet. This interface provides a nextServlet property that points to the next component in the pipeline. The ATG installation provides the implementation class atg.servlet.pipeline.PipelineableServletImpl, which you can subclass to create your own servlets. PipelineableServletImplimplements all Servlet methods, so you only need to override the service method.
To insert into a request handling pipeline a servlet that subclasses PipelineableServletImpl:
a)    Extend atg.servlet.pipeline.PipelineableServletImpl.
b)    Define the servlet as a globally scoped Nucleus component.
c)    Reset the previous servlet’s nextServlet property to point to the new servlet.
d)    Set the new servlet’s nextServlet property to point to the next servlet in the pipeline.
e)    Add the servlet’s path to the initialServices property of /atg/dynamo/servlet/Initial.
The PipelineableServlet interface has two sub-interfaces that provide more flexibility for inserting new servlets into the pipeline:
·         atg.servlet.pipeline.InsertableServlet
·         atg.servlet.pipeline.DispatcherPipelineableServlet
InsertableServlet
The InsertableServlet interface lets a servlet insert itself into the pipeline when the service starts, without requiring changes to servlets already in the pipeline, through theinsertAfterServlet property, which points back to the preceding servlet. The inserted servlet reads the preceding servlet’s nextServlet property and points to it as the next servlet to execute after itself.
For example, a servlet pipeline might contain Servlet1, whose nextServlet property points to Servlet2. You can insert MyNewServlet, which implementsInsertableServlet, between the two by setting its insertAfterServlet property so it points to Servlet1. This configuration splices ServletNew between Servlet1 and Servlet2 as follows:
·         MyNewServlet sets its own nextServlet property to the value of Servlet1’s nextServlet property.
·         MyNewServlet reads Servlet1’s nextServlet property and links to Servlet2 as the next servlet to execute after itself.
If an insertable servlet inserts only itself into a pipeline, it uses the nextServlet property of its insertAfterServlet servlet to resume pipeline execution. However, if the inserted servlet starts a secondary pipeline, it sets its own nextServlet property to the next servlet in that pipeline. After the last secondary pipeline servlet executes, it passes control to the nextServlet servlet originally specified by the insertAfterServlet servlet, and the original pipeline resumes execution.
The ATG installation provides an implementation of the InsertableServlet interface, atg.servlet.pipeline.InsertableServletImpl. This class implements all Servletmethods, so you only need to override the service method.
To add an InsertableServlet to the servlet pipeline:
a)    Write your servlet by extending atg.servlet.pipeline.InsertableServletImpl.
b)    Define the servlet as a globally scoped Nucleus component.
c)    Set the insertAfterServlet property of your servlet to point to the path of the pipeline servlet you want your servlet to follow. For example, you can insert a servlet after DynamoServlet as follows:
insertAfterServlet=/atg/dynamo/servlet/dafpipeline/DynamoServlet
d)    Add the servlet’s path to the initialServices property of /atg/dynamo/servlet/Initial:
initialServices+=/myServlet
When the inserted servlet finishes processing, it calls the method passRequest() (defined in InsertableServletImpl), which automatically passes the request and response objects to the next servlet in the pipeline.
Sample Servlet Code
The following pipeline servlet class URIPrinter extends atg.servlet.pipeline.InsertableServletImpl. It prints the request URI before passing the request on to the next servlet in the pipeline:
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import atg.servlet.*;
import atg.servlet.pipeline.*;
 
public class URIPrinter extends InsertableServletImpl {
 
            public URIPrinter () {
            }
            public void service (DynamoHttpServletRequest request, DynamoHttpServletResponse response)
                         throws IOException, ServletException {
 
                        System.out.println ("Handling request for " + request.getRequestURI ());
                        passRequest (request, response);
            }
}
Note: Subclasses of InsertableServletImpl that add their own logic to doStartService must call super.doStartService().
DispatcherPipelineableServlet
The DispatcherPipelineableServlet interface provides a mechanism for conditionally branching the pipeline. This interface includes a dispatcherServiceMap property that is a Map of possible servlets to invoke next, depending on some condition. For example, the MimeTypeDispatcher servlet determines which servlet to invoke depending on the MIME type of the request. ATG provides the implementation class DispatcherPipelineableServletImpl.

23. What are the Advantages of DAF?

·         It is used to maintain huge data.
·         It has repositories which help is data anywhere architecture.
·         Dependency injection.
·         It can write any object of type 1 call in to the db.
·         Dynamo messaging using patch bay and JMS.
·         “Inversion of Control” design pattern, whereby software components are discrete.
·         Entities coupled together by the Nucleus container, rather than through direct reference.

24. Logging features of ATG?

Oracle ATG Web Commerce includes three different systems for sending, receiving, and recording messages generated by components: Logging, Data Collection, and Recorders. Oracle ATG Web Commerce Logging provides a convenient way to log system messages. Any component that extends the GenericService class or implements the ApplicationLogging interface can send LogEvents that are received by log listeners and logged to a flat file. The logging system can log only text messages and exceptions.

Any component whose base class implements “ApplicationLogging” Interface can use atg logging infrastructure. Logging can be done per-component, per-module or per-application basis. Error, Warning, Info & Debug messages are the various logging mechanisms. First three are logged by default, whereas the Debug messages are just for debugging purpose and should be removed when the code goes into production. Logging is managed using the “GLOBAL.properties” file, which specfies the log levels of various modules.

25. What is Configuration Layering?

Properties set in later entries in the CONFIGPATH override earlier entries. By adding an entry to the config-path you can customize any components in the system without losing the original configuration information. You can have a global configuration common to all machines then have machine specific information in the last layer.

26. How to register a repository with the dynamo?

Create “/config/atg/registry/ContentRepositories.properties” file and append our repository file (XML) name to the “initialRepositories” property

initialRepositories+= /myModule/mySampleRepository

27. What are the performance issues with ATG?

Performance problems come in many shapes and sizes, but they all mean that the processing of some task is not happening at the expected and previously observed speed.
·         Performance issues include CPU utilization problems
·         Slow response times
·         High levels of database activity
·         Long running SQL queries
·         Slow CA deployments
Just to name a few.

28. What is module hierarchy in ATG?



Module Dependencies

ATG application often depends on other modules which are started automatically when your module is started. These dependencies are declared in the module manifest file at location
<module-name>/META-INF/MANIFEST.MF


The list show above will include DSS at a minimum. If our application uses facilities provided by other application layers (e-commerce) then we will need to include those modules in the list as well. Note that we only need to include the top-level module; all additional modules required by the top modules will automatically be started.

E.g. If our application requires DSS, which requires DPS, then we need to specify only DSS not DPS.


ATG Modules

The following tables list the module names for the main Oracle ATG Web Commerce applications, demos, and reference applications. This is not an exhaustive list of all Oracle ATG Web Commerce modules.
Module
Description
Admin.Init
Adds missing administrative accounts for the ATG Control Center. For more information, see the Managing Access Control chapter.
Admin.Reset
Resets the default login accounts for the ATG Control Center. For more information, see the Managing Access Control chapter.
DAF.Search
Enables the Oracle ATG Web Commerce platform integration with Oracle Endeca Commerce. See the ATG-Endeca Integration Guide.
DAS-UI
Enables an Oracle ATG Web Commerce server to accept connections from the ATG Control Center.
Note: This module must be running if you want to use the ATG Control Center.
DCC
Runs the ATG Control Center in the same JVM used by the application server that the Nucleus-based application is running on. For more information, see the Installation and Configuration Guide.
DPS
Oracle ATG Web Commerce Personalization.
DSS
Oracle ATG Web Commerce Scenarios.
DSSJ2EEDemo
Oracle ATG Web Commerce demo (Quincy Funds).
RL
Repository Loader. Takes files that are stored in a file system, converts them into repository items, and loads the items into the repository. To learn more, see the Repository Guide.
SQLJMSAdmin
Browser-based administration interface for Oracle ATG Web Commerce’s SQL JMS message system. For more information, see Using the SQL-JMS Administration Interface.
Content Administration Modules

Module
Description
AssetUI
Supports the building of browser-based user interfaces for an ATG Content Administration (versioned) environment. The module includes the Asset Picker and functionality related to it. Requires the WebUI module (see below).
BizUI
The Oracle ATG Web Commerce Business Control Center. Includes the Home page functionality.
PublishingAgent
Publishing Agent. Runs on production and staging servers and performs content deployment operations by communicating with the ATG Content Administration server.
PublishingWebAgent
Publishing web agent. Runs on the production and staging web servers and performs web content deployment operations by communicating with the ATG Content Administration server.
Publishing.base
ATG Content Administration. See the Content Administration Programming Guide for more information.
Publishing.WebAppRef
The source module for the Web Application Reference Implementation provided with ATG Content Administration.
Publishing.WebAppRefVer
The versioning module for the Web Application Reference Implementation provided with ATG Content Administration.
PubPortlet
Supplies the portlets that make up the Oracle ATG Web Commerce Business Control Center interface. Including this module also causes the Publishing.base, AssetUI, and BizUI modules to be included. Include this module to perform most basic tasks in ATG Content Administration, such as product evaluation.
WebUI
Contains support for browser-based user interfaces. Examples are the tree-based asset browsing feature, a calendar widget, and the View Mapping system.
Portal Modules

Module
Description
Portal.gears
Includes the Portal Application Framework and baseline gears.
Portal.paf
Portal Application Framework (PAF). At a minimum, you must include this module to use Oracle ATG Web Commerce Portal. To learn more about the PAF, see the Portal Administration Guide.
Portal.gear-name
Portal.portlet-name
Includes the specified gear or portlet. For example, if you create a gear called productprices, include the module Portal.productprices.
ATG Commerce Modules

Module
Description
B2BCommerce
ATG Business Commerce
Note: To run ATG Commerce, you must use one and only one of the following modules: B2BCommerce,B2BCommerce.Versioned, B2CCommerce, or B2CCommerce.Versioned.
B2BCommerce.Versioned
Use instead of B2BCommerce module if running ATG Merchandising. (Also requires modules DCS-UI.Versioned and PubPortlet.)
Note: To run ATG Commerce, you must use one and only one of the following modules: B2BCommerce,B2BCommerce.Versioned, B2CCommerce, or B2CCommerce.Versioned.
Including this module also includes B2BCommerce, DCS.DynamicCustomCatalogs.Versioned, and their modules.
B2CCommerce
ATG Consumer Commerce
Note: To run ATG Commerce, you must use one and only one of the following modules: B2BCommerce,B2BCommerce.Versioned, B2CCommerce, or B2CCommerce.Versioned.
Including this module also includes DCS and its modules.
B2CCommerce.Versioned
Use instead of B2CCommerce module if running ATG Merchandising. (Requires the DCS-UI.managementand PubPortlet modules also.)
Note: To run ATG Commerce, you must use one and only one of the following modules: B2BCommerce,B2BCommerce.Versioned, B2CCommerce, or B2CCommerce.Versioned.
Including this module also includes B2Commerce, DCS.Versioned, and their modules.
CommerceGears.orderapproval
Order Approval Portal Gear (Requires ATG Portal also.)
Including this module also includes Portal.paf, Portal.authentication, Portal.templates,Portal.communities, B2BCommerce, and their modules.
CommerceGears.orderstatus
Order Status Portal Gear (Requires ATG Portal also.)
Including this module also includes Portal.paf, Portal.authentication, Portal.templates,Portal.communities, DCS, and their modules.
Cybersource
Third-party commerce module (from CyberSource Corp.) for authorizing credit cards, crediting and settling accounts, calculating taxes, and verifying addresses.
Including this module also includes DCS and its modules.
DCS
Base ATG Commerce module.
Including this module also includes DSS, DPS, and their modules.
DCS.AbandonedOrderServices 
Provides tools for dealing with abandoned orders and shopping carts.
Including this module also includes DCS and its modules.
DCS.CustomCatalogs
Runs custom catalogs in an ATG Commerce production environment, required to support pre-ATG 11.0 Commerce applications; otherwise unused.
DCS.DynamicCustomCatalogs
Runs custom catalogs in an ATG Commerce development environment.
Including this module also includes DCS.CustomCatalogs and its modules.
DCS.DynamicCustomCatalogs.
Versioned
Runs custom catalogs in an environment running ATG Commerce and ATG Merchandising. (Requires theDCS-UI.management and PubPortlet modules also.)
Including this module also includes DCS.DynamicCustomCatalogs, DCS.CustomCatalogs.Versioned, and their modules.
DCS.PublishingAgent
Use instead of the PublishingAgent module on the target server if ATG Commerce repository items are deployed to that server.
Including this module also includes PublishingAgent, DCS, and their modules.
DCS.Search
Adds commerce-specific elements to the integration with Oracle Endeca Commerce. See the ATG-Endeca Integration Guide.
DCS.Versioned
Use instead of DCS module if running ATG Commerce with ATG Merchandising.
Including this module also includes Publishing.base, DCS, and their modules.
DCSSampleCatalog
ATG Commerce Sample Catalog.
Including this module also includes DCS and its modules.
Fulfillment
ATG Commerce order fulfillment.
Including this module also includes DCS and its modules.
MotorpriseJSP
ATG Business Commerce reference application (Motorprise).
Including this module also includes B2BCommerce, DCS.AbandonedOrderServices, and their modules.
PayFlowPro
Third-party commerce module (from VeriSign) for handling credit card authorization, settlement, and crediting.
Including this module also includes DCS and its modules.
Taxware
Third-party commerce module (from ADP Taxware) for calculating taxes, verifying addresses and determining tax jurisdictions.
Including this module also includes DCS and its modules.


Reference: ATG Modules and features

29. EAR file structure in ATG Project?

Manifest file: <module-name>/META-INF/MANIFEST.MF

Manifest-Version: 1.0 
ATG-Config-Path: config/ 
ATG-Required: DAS DPS DSS  
ATG-J2EE: j2ee-apps/EShop-ee.ear 
ATG-EAR-Module: j2ee-apps/EShop-ee.ear 
ATG-Class-Path: lib/ 

Through command line move to C:\ATG\ATG9.1\home\bin and execute the following command:

runAssembler C:\Dummy.ear –m Dummy;DafEar;DafEar.Admin

The above command takes semi-colon separated list of modules to be assembled into the big EAR and also two other important applications that make up the ACC viz., DafEar and DafEar.Admin. The resultant Dummy.ear is created in the C:\ drive.
To enable liveconfig, you can use the –liveconfig argument for runAssembler (see the Assembling Applications section of the ATG Programming Guide), or add the following line to the WEB-INF/ATG-INF/dynamo.env file in the atg_bootstrap.war module of your EAR file:
atg.dynamo.liveconfig=on


30. What is ATG Scheduler? What you did in ATG Scheduler?

Most server-side applications have routine tasks that must be performed periodically. For example, a component in the application might need to clear a cache every 10 minutes, or send email each morning at 2:00, or rotate a set of log files on the first of every month.
Oracle ATG Web Commerce includes a Scheduler service, atg.service.scheduler.Scheduler, which keeps track of scheduled tasks and executes the appropriate services at specified times. You can see a list of all scheduled tasks in the Component Browser at /atg/dynamo/service/Schedule.
Oracle ATG Web Commerce also includes a SingletonSchedulableServiceatg.service.scheduler.SingletonSchedulableService, which enables multiple Oracle ATG Web Commerce servers to run the same scheduled service, while guaranteeing that only one instance of the service performs the scheduled task at a time. This provides some protection from server failures, as the loss of one Oracle ATG Web Commerce server does not prevent the scheduled service from running on another Oracle ATG Web Commerce server.

Writing a Schedulable Component

The component needs to be configured with two properties:
scheduler
Points to a Scheduler such as the standard Oracle ATG Web Commerce Scheduler.
schedule
Points to the standard Oracle ATG Web Commerce Scheduler. The schedule property can be set in a wide variety of formats, which Oracle ATG Web Commerce interprets through the PropertyEditor that is defined for the Schedule type. For more information on format options, see the next section, Schedule Settings.
For example:
scheduler=/atg/dynamo/service/Scheduler
schedule=every 10 seconds
This section describes how to write a component that schedules itself to perform a task according to different schedules. In this case, the task to be performed is to write Hello to the console.
Such a component might look like this:

import atg.nucleus.*;
import atg.service.scheduler.*;

public class HelloJob extends GenericService implements Schedulable
{
  public HelloJob () {}

  // Scheduler property
  Scheduler scheduler;
  public Scheduler getScheduler () { return scheduler; }
  public void setScheduler (Scheduler scheduler)
  { this.scheduler = scheduler; }

// Schedule property
  Schedule schedule;
  public Schedule getSchedule () { return schedule; }
  public void setSchedule (Schedule schedule)
  { this.schedule = schedule; }

  // Schedulable method
  public void performScheduledTask (Scheduler scheduler,
                                    ScheduledJob job)
  { System.out.println ("Hello"); }

  // Start method
  int jobId;
  public void doStartService () throws ServiceException
  {
    ScheduledJob job = new ScheduledJob ("hello",
                                         "Prints Hello",
                                         getAbsoluteName (),
                                         getSchedule (),
                                         this,
                                         ScheduledJob.SCHEDULER_THREAD);
    jobId = getScheduler ().addScheduledJob (job);
  }

  // Stop method
  public void doStopService () throws ServiceException
  {
    getScheduler ().removeScheduledJob (jobId);
  }
}

Notice that this component extends GenericService, which allows it to be notified of start and stop conditions through doStartService and doStopService. The component also implements Schedulable by defining the performScheduledTask method to print Hello. The component also requires the schedulerand schedule to be set as properties.
When the component is started, it constructs a ScheduledJob from the schedule property, and also specifies that the job should run in the Scheduler’s thread. The component then adds the job to the Scheduler, and stores the job ID returned by the Scheduler. When the component is stopped, it removes the scheduled job by passing the ID of the job.

ScheduledJob Thread Methods

A ScheduledJob component has a threadMethod property that indicates what threading model should be used to execute the scheduled job. ThethreadMethod property can have one of the following values:
SCHEDULER_THREAD
The job is run in the Scheduler’s own thread. This is the most efficient thread method, but it blocks the Scheduler from performing any other jobs until the job is complete. Therefore, use this thread method only for jobs that do not take a long time to run. Jobs that use I/O should probably avoid using this option.
SEPARATE_THREAD
Each time the job is triggered, a new thread is created to run the job. The thread is destroyed when the job completes. If a job is set to run periodically at a rate that is faster than the job itself can run, new threads are created to handle those jobs.
REUSED_THREAD
A separate thread is created to handle the job. Whenever the job is triggered, that thread is directed to run the job. When the job completes, the thread stays around waiting for the next time the job is triggered. If the job is still running when it is scheduled to begin to run again, it does not start again until the next time around. With this method, the Scheduler thread is not blocked by executing jobs, and threads do not multiply out of control if the job is triggering too quickly.

Schedule Settings

The schedule property of a Schedulable component can be set in a variety of formats, which Oracle ATG Web Commerce interprets through thePropertyEditor that is defined for the Schedule type.
The different types of Schedules can also be created programmatically by creating instances of RelativeSchedule, PeriodicSchedule, orCalendarSchedule.
You can set a schedule property to a PeriodicSchedule and RelativeSchedule alone or in combination:
·         PeriodicSchedule specifies a task that occurs at regular intervals, in this format:
schedule=every integer time-unit[ with catch up]
·         RelativeSchedule specifies a time relative to the current time, in this format:
schedule=in integer time-unit
with catch up
You can qualify a PeriodicSchedule with the string with catch up, which determines whether the PeriodicSchedule tries to catch up on missed jobs.
By specifying with catch up, you can force execution of the missed jobs:
schedule=every 2 seconds with catch up
CalendarSchedule
A CalendarSchedule schedules a task to run at designated points on the calendar. For example, you might schedule a task for 2:30am each Sunday, or a specific date such as January 1. The format for a CalendarSchedule looks like this:
schedule=calendar mos dates wkdays mo-occurs hrs mins


Running the Same Schedulable Service on Multiple Servers

The SingletonSchedulableService, a subclass of the standard SchedulableService, works in conjunction with a client lock manager to guarantee that only one instance of a scheduled service is running at any given time throughout a cluster of cooperating Oracle ATG Web Commerce servers.
Configuring a SingletonSchedulableService
SingletonSchedulableService is an abstract class that extends SchedulableService and implements the performScheduledTask method in a way that tests for other instances of the service before proceeding.
To implement a SingletonSchedulableService, create a subclass of this class, and then create a component based on that subclass. Configure the component with a reference to a client lock manager, a lock name, and a timeout period. For example:

#Thu Aug 09 19:15:14 EDT 2001
$class=myclasses.MySingletonSchedulableService
$scope=global
clientLockManager=/atg/dynamo/service/ClientLockManager
lockName=ReportingLockManager
lockTimeOut=2000

Monitoring the Scheduler

To see a list of scheduled jobs in your application, navigate to the /atg/dynamo/service/ Scheduler component in dynamo admin.

No comments:

Post a Comment