Saturday 21 December 2013

Request Processing in ATG

In every web application request plays a very important role.User(browser) need to send request to server to access any web resource.

ATG performs below steps to process requests it receives.
  1. When a user requests a page(send request to server).Web server parses the request and holds in an HTTPServletRequest object.
  2. The Web server passes the HTTPServletRequest to the application server.It wraps the request in its own flavor of request around the generic one before passing it to the Web application.
  3. If you defined custom filters and the request is for a JHTML page, the filters execute in the order you specified.
  4. Any custom J2EE servlets are processed.
  5. The Web application calls one of the following resources.
  •  DynamoProxyServlet( DAS servlet pipeline for JHTML requests).
  •  PageFilter (DAF servlet pipeline for JSP requests).

     6. The request is passed on to a pipeline of servlets.
     7. If you created custom filters and a JSP is being requested, they execute after the last pipeline servlet, but before the request returns to the application server.
     8. After the servlet pipeline reaches the end, it returns the request to the application server for final processing. 

Below diagram illustrates ATG request processing.
 


Note : DAS pipeline is invoked in the case of JHTML.Because JHTML is a proprietary language, it relies on the page compiler provided in the DAS servlet pipeline to generate JHTML into a servlet that is rendered as HTML by the application server.

Monday 2 December 2013

Encrypting strings using java

Encryption : Encryption is the science of encoding and decoding secret messages.The message or information (referred to as plain text) is encrypted using an encryption algorithm, turning it into an unreadable cipher text . This is usually done with the use of an encryption key, which specifies how the message is to be encoded. Any adversary that can see the cipher text should not be able to determine anything about the original message. An authorized party, however, is able to decode the cipher text using a decryption algorithm, that usually requires a secret decryption key, that adversaries do not have access to. 

Here is the idea,how this can be done , for example password encryption.

  • First accept user password.
  • Encrypt password using random salt.
  • Store the salt and encrypted password.
  • For verification accept password from user.
  • Fetch and decode salt for user.Already stored above.
  • Encrypt user entered password using decoded salt.
  • Now compare encrypted password with already stored encrypted password.Then take the action accordingly.

Below code demonstrates how to encrypt strings(password) using java.

package com.test;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * This class contains code for encryption demo. 
 * 
 * @author Jagdev
 * 
 */

public class EncryptionTest {

/**
* @param args
* @throws NoSuchAlgorithmException
* @throws IOException
*/
public static void main(String[] args) throws NoSuchAlgorithmException,
IOException {
// String password
String password = "Jagdev";
// Hash function iterations
int iterationNb = 5000;
// SecureRandom object that implements the SHA1PRNG Random Number
// Generator (RNG) algorithm
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
// Salt generation 64 bits long
byte[] bSalt = new byte[8];
random.nextBytes(bSalt);
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update(bSalt);
byte[] input = digest.digest(password.getBytes("UTF-8"));

for (int i = 0; i < iterationNb; i++) {
input = digest.digest(input);
}

BASE64Encoder endecoder = new BASE64Encoder();
// encode the password using BASE64Encoder
String encodedPassword = endecoder.encode(input);
System.out.println("Encoded password is " + encodedPassword);
System.out.println("Salt is = " + new String(bSalt));
// encode the salt using BASE64Encoder
String encodedSalt = endecoder.encode(bSalt);
                //Code for encode string using decoded salt.
BASE64Decoder decoder = new BASE64Decoder();
// decode the encodedSalt
byte[] decodedSalt = decoder.decodeBuffer(encodedSalt);
// reset the digest
digest.reset();
// update the digest using decoded salt
digest.update(decodedSalt);
input = digest.digest(password.getBytes("UTF-8"));

for (int i = 0; i < iterationNb; i++) {
input = digest.digest(input);
}

String encodedpassword = endecoder.encode(input);
System.out.println("Encoded password is " + encodedpassword);
System.out.println("Decoded salt is = " + new String(decodedSalt));
}

}





Endeca “Failed to obtain lock” indexing error solution

While running baseline or partial indexing,you may encounter the below error.

INFO:Checking definition from AppConfig.xml against existing EAC provisioning.
INFO:Definition has not changed.
INFO:Starting baseline update script.
WARNING:Failed to obtain lock. 
Below is the reason behind this.
If running script breaks halfway through its execution due to an unhandled exception, or is manually interrupted 
by a user pressing Ctrl-C while it is running, the lock remains set within the EAC.  
To resolve this use below commands.
On Windows: .\runcommand.bat LockManager releaseLock update_lock
On UNIX: ./runcommand.sh LockManager releaseLock update_lock

Now run the indexing,it will work.

Friday 15 November 2013

Endeca environment variables


Here I will explain how to set Endeca environment variables.Before discussing Endeca environment variables,I would like to introduce the term Environment variable. 

Environment variable
An environment variable is a dynamic "object" on a computer that stores a value, which in turn can be referenced by one or more software programs.It can be said that environment variables help to create and shape the environment  where a program runs.

Endeca environment variables

Below are the four types of the Endeca evironment variables.

1. MDEX Engine variables

  • ENDECA_MDEX_ROOT : Path of the MDEX Engine root directory(default ../MDEX/version)


2. Platform Services variables

  • ENDECA_ROOT : Path of the Platform Services root directory(default ../PlatformServices/version)


  • ENDECA_CONF : Path of the workspace directory for the Endeca Http Service(default  ../PlatformServices/workspace)


3. Endeca Workbench variables

  • ENDECA_TOOLS_ROOT : Path of the Endeca Workbench root directory(default ../Workbench/version). In latest installers \ToolsAndFrameworks\<version>.


  • ENDECA_TOOLS_CONF : Path of the workspace directory for the Endeca Tools Service(default ../Workbench/workspace). In latest installers \ToolsAndFrameworks\<version>\server\workspace.


4. Other variables(Set and used by the Endeca Deployment Template)

  • ENDECA_PROJECT_DIR : Path of the deployed application.(Default user supplied input at installation time).
  • ENDECA_PROJECT_NAME : Project name that is used.(Default user supplied input at installation time).

Setting the environment variables ensures that the different Endeca components can communicate with each other properly.

Run  below scripts to set Endeca environment variables.
1. Windows Platform Script
On windows platform, Platform Services and Oracle Endeca Workbench environment variables are set at the time of installation.

You only need to set the MDEX Engine environment variable(ENDECA_MDEX_ROOT).Run the below script to achieve this.

\Endeca\MDEX\<version>\mdex_setup.bat

2. Linux Platform Scripts.
On Linux platform run the below scripts.
For MDEX Engine variables.
   source /endeca/MDEX/<version>/mdex_setup_sh.ini
For Platform Services variables.
   source /endeca/PlatformServices/workspace/setup/installer_sh.ini
For Endeca Workbench variables.
  source /endeca/Workbench/workspace/setup/installer_sh.ini

Thursday 24 October 2013

Locale sensitive sorting using java collator

Below example demonstrates how to achieve locale sensitive sorting using  java Collator.

Locale sensitive sorting -  Sort strings in language-specific order not just by ASCII code.It is based on different weights for comparisons between different characters.

Example code sorts list of Person objects based on their names.


Person.java


package com.test.sort;


import java.text.CollationKey;


/**

 * Holds information related to person.
 * 
 * @author Jagdev
 * 
 */
public class Person implements Comparable<Person> {

/**

* Holds name of the person.
*/
private String name;

/**

* Holds age of the person.
*/
private int age;
/**
* Holds collation key used for sorting.
*/
private CollationKey sortKey;

/**

* Default constructor.
*/
public Person() {

}


/**

* Parameterized constructor.

* @param sortKey
*            of type CollationKey
*/
public Person(CollationKey sortKey) {
this.setSortKey(sortKey);
}

/**

* @return name
*/
public String getName() {
return name;
}

/**

* @param name
*            of type String
*/
public void setName(String name) {
this.name = name;
}

/**

* @return age
*/
public int getAge() {
return age;
}

/**

* @param age
*            of type int
*/
public void setAge(int age) {
this.age = age;
}

/**

* @param sortKey
*            of type CollationKey
*/
public void setSortKey(CollationKey sortKey) {
this.sortKey = sortKey;
}

/**

* @return sortKey of type CollationKey
*/
public CollationKey getSortKey() {
return sortKey;
}

/*

* (non-Javadoc)

* @see java.lang.Object#toString()
*/
public String toString() {
return "Name = " + name + " Age = " + age;
}

@Override

public int compareTo(Person person) {
return sortKey.compareTo(person.getSortKey());
}

}

CollatorSortMain.java

package com.test.sort;

import java.text.CollationKey;
import java.text.Collator;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

/**
 * Contains code to demo sorting of collection of the objects using collator
 * @author Jagdev
 *
 */
public class CollatorSortMain {

/**
* @param args
*/
public static void main(String[] args) {
CollatorSortMain collatorSortMain = new CollatorSortMain();
collatorSortMain.testEnglishSort();
collatorSortMain.testPortugseSort();
}

/**
* Create collator using language and Country
* @param language
* @param country
* @return collator
*/
private Collator createCollator(String language, String country) {
Locale locale = new Locale(language, country);
Collator collator = Collator.getInstance(locale);
collator.setStrength(Collator.PRIMARY);
return collator;
}

/**
* Verifies the portuguese sorting using collator
*/
private void testPortugseSort() {
Collator collator_en_US = createCollator("pt", "PT");
List<Person> personListEng = new LinkedList<Person>();
CollationKey collationKey1 = collator_en_US.getCollationKey("céu");
Person p1 = new Person(collationKey1);
p1.setName("céu");
p1.setAge(30);
CollationKey collationKey2 = collator_en_US.getCollationKey("lívido");
Person p2 = new Person(collationKey2);
p2.setName("lívido");
p2.setAge(20);
CollationKey collationKey3 = collator_en_US.getCollationKey("vermelho");
Person p3 = new Person(collationKey3);
p3.setName("vermelho");
p3.setAge(10);
personListEng.add(p3);
personListEng.add(p2);
personListEng.add(p1);
System.out.println("Before Sort " + personListEng);
Collections.sort(personListEng);
System.out.println("After Sort " + personListEng);
}

/**
* Verifies the english sorting using collator
*/
private void testEnglishSort() {
Collator collator_en_US = createCollator("en", "US");
List<Person> personListEng = new LinkedList<Person>();
CollationKey collationKey1 = collator_en_US.getCollationKey("Blue");
Person p1 = new Person(collationKey1);
p1.setName("Blue");
p1.setAge(30);
CollationKey collationKey2 = collator_en_US.getCollationKey("White");
Person p2 = new Person(collationKey2);
p2.setName("White");
p2.setAge(20);
CollationKey collationKey3 = collator_en_US.getCollationKey("Red");
Person p3 = new Person(collationKey3);
p3.setName("Red");
p3.setAge(10);
personListEng.add(p3);
personListEng.add(p2);
personListEng.add(p1);
System.out.println("Before Sort " + personListEng);
Collections.sort(personListEng);
System.out.println("After Sort " + personListEng);

}
}

Here is the Collator javadoc.

Below is the advantage of using collator over compareTo (lexicographically).


For comparing Strings exactly once, the compare method provides the best performance. When sorting a list of Strings however, it is generally necessary to compare each String multiple times. In this case, CollationKeys provide better performance. The CollationKey class converts a String to a series of bits that can be compared bitwise against other CollationKeys. A CollationKey is created by a Collator object for a given String.