Monday, June 1, 2015

AEM 6 MongoDB: Is it time to migrate to Mogodb?



Based on findings, there are still a lot of issues with mongodb as persistence layer for AEM 6. Few points to be noted:


  1. "Sharding" feature of Mongodb is not supported by AEM yet. So horizontal scaling of Mongodb Primary is not possible yet to use with AEM.
  2. Performance of AEM with mongodb is not as good as compared to TarMK. 
  3. TarMK is the best practice still by Adobe support team. AEM replication can be used to sync content from one data center to other to have DR center ready with TarMK and publish content to multiple publish instances.

References:
http://docs.adobe.com/docs/en/aem/6-0/deploy/recommended-deploys.html
http://docs.adobe.com/docs/en/aem/6-0/deploy/upgrade/microkernels-in-aem-6-0.html
http://docs.mongodb.org/manual/administration/sharded-clusters/


Thursday, April 23, 2015

How to take Thread Dump in windows

There are different ways to take thread dumps. 

Procedure 1:  Use Powershell
Procedure 2:  Use jstack

Powershell:

1. Download "PsExec.exe" and save it.

2. Go to Start->Run and type "powershell",


3. Powershell will be opened.

4. Navigate to the path where the "PsExec.exe" exist and type following command
    “PsExec.exe -s jstack PID > Dump.txt”

5. Dump file will be created.

Procedure 2:
Create sample Threaddump.java class  and run.


public class Threaddump {

/**
* @param args
*/
public static void main(String[] args) {
int count =10;
ExecCommand myExc= new ExecCommand();
while(count >0)
{
myExc.ExecCommand("jstack -F 6072 > jstack."+count);
Thread.sleep(5000);
count--;
}
}

}

Note: Change PID and file paths.
===========================================================================
 ExecCommand class

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;

public class ExecCommand {
private Semaphore outputSem;
private String output;
private Semaphore errorSem;
private String error;
private Process p;
private int exitValue;

private class InputWriter extends Thread {
 private String input;


 public InputWriter(String input) {
  this.input = input;
 }

 public void run() {
  PrintWriter pw = new PrintWriter(p.getOutputStream());
  pw.println(input);
  pw.flush();
 }
}

private class OutputReader extends Thread {
 public OutputReader() {
  try {
  outputSem = new Semaphore(1);
  outputSem.acquire();
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
 }

 public void run() {
  try {
  StringBuffer readBuffer = new StringBuffer();
  BufferedReader isr = new BufferedReader(new InputStreamReader(p
   .getInputStream()));
  String buff = new String();
  while ((buff = isr.readLine()) != null) {
   readBuffer.append(buff);
   System.out.println(buff);
  }
  output = readBuffer.toString();
  outputSem.release();
  } catch (IOException e) {
  e.printStackTrace();
  }
 }
}

private class ErrorReader extends Thread {
 public ErrorReader() {
  try {
  errorSem = new Semaphore(1);
  errorSem.acquire();
  } catch (InterruptedException e) {
  e.printStackTrace();
  }
 }

 public void run() {
  try {
  StringBuffer readBuffer = new StringBuffer();
  BufferedReader isr = new BufferedReader(new InputStreamReader(p
   .getErrorStream()));
  String buff = new String();
  while ((buff = isr.readLine()) != null) {
   readBuffer.append(buff);
  }
  error = readBuffer.toString();
  errorSem.release();
  } catch (IOException e) {
  e.printStackTrace();
  }
  if (error.length() > 0)
  System.out.println(error);
 }
}

public ExecCommand(String command, String input) {
 try {
  p = Runtime.getRuntime().exec(makeArray(command));
  new InputWriter(input).start();
  new OutputReader().start();
  new ErrorReader().start();
  p.waitFor();
 } catch (IOException e) {
  e.printStackTrace();
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
}

public ExecCommand(String command) {
 try {
  p = Runtime.getRuntime().exec(makeArray(command));
  new OutputReader().start();
  new ErrorReader().start();
  p.waitFor();
  exitValue=p.exitValue();
 } catch (IOException e) {
  e.printStackTrace();
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
}

public int getExitValue(){
return exitValue;
}
public String getOutput() {
 try {
  outputSem.acquire();
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 String value = output;
 outputSem.release();
 return value;
}

public String getError() {
 try {
  errorSem.acquire();
 } catch (InterruptedException e) {
  e.printStackTrace();
 }
 String value = error;
 errorSem.release();
 return value;
}

private String[] makeArray(String command) {
 ArrayList<String> commandArray = new ArrayList<String>();
 String buff = "";
 boolean lookForEnd = false;
 for (int i = 0; i < command.length(); i++) {
  if (lookForEnd) {
  if (command.charAt(i) == '\"') {
   if (buff.length() > 0)
   commandArray.add(buff);
   buff = "";
   lookForEnd = false;
  } else {
   buff += command.charAt(i);
  }
  } else {
  if (command.charAt(i) == '\"') {
   lookForEnd = true;
  } else if (command.charAt(i) == ' ') {
   if (buff.length() > 0)
   commandArray.add(buff);
   buff = "";
  } else {
   buff += command.charAt(i);
  }
  }
 }
 if (buff.length() > 0)
  commandArray.add(buff);

 String[] array = new String[commandArray.size()];
 for (int i = 0; i < commandArray.size(); i++) {
  array[i] = commandArray.get(i);
 }

 return array;
}
}









Wednesday, April 8, 2015

Better to disable XML rendering to prevent your source code

It would be a better to disable xml rendering to prevent your source code /apps being stolen:
Ref:
http://crxdelight.com/2012/03/26/preventing-your-source-code-in-apps-from-being-stolen/

Saturday, July 5, 2014

How to enable logging for JSP pages?

JSPs are compiled into a package called org.apache.jsp with the script path converted to further package parts.

Example: 











You can configure below log name to enable logging for title.jsp

log Name:   org.apache.jsp.apps.demo.components


Friday, July 4, 2014

What is Replication in CQ5 & the process.

Replication is the mechanism used to:

Publish (activate) content from an author to publish environment.
Explicitly flush content from the Dispatcher cache.
Return user input (eg, form input) from publish environment to the author environment (under control of the author environment)

REPLICATION PROCESS:

1)    First, the author requests that certain content to be published (activated).
2)    The request is passed to the appropriate default replication agent.
3)    Replication agent packages the content and places it in the replication queue.
4)    the content is lifted from the queue and transported to the publish environment using the   configured protocol.
5)    a servlet in the publish environment receives the request and publishes the received content, the default servlet is http://localhost:4502/bin/receive.

Sunday, December 15, 2013

Guidelines - Assets Upload into CQ DAM

Here are the few guidelines suggested by CQ Experts (from google groups):

1. Folder/Asset Naming convention

    a. Is it good a have a folder/Asset name contains underscore ( _ ).

        Eg:  /content/dam/Test/Advanced_buttons

    Is CQ providing any best naming conventions.

2. Assets (Images/pdf/docs whatever)

     a. What is the max size limit of an Asset?

3. What is the max number of Assets that we can upload in a dam folder.

Comments:

1. Yes folders can have underscores. I didn't see any issue till now.

2. Max size limit I am not sure but I injected around 10 to 30 MB size with out any issues.

3. There should not be much issue even if you inject 100 to 150 gigs of assets. we migrated around 130 gigs with out much issues. In terms of number of assets inside a particular folder (Number of nodes at one level) Adobe recommends dont use more than 200 to 250 at one level. If it is more than that front end DAM UI will slows down (still repository doesn't show any issue)