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)

Friday, October 11, 2013

Installing and Starting Adobe Experience Manager as a Windows Service

 

Note:

  1. Your need to login as Administrator or start/run these steps using Run As Administrator command prompt. 
  2. If you don’t follow the above instruction, you will get Access denied error while completing steps.

Steps:

  1. Open the crx-quickstart\opt\helpers\instsrv.bat file in a text editor.
  2. If you are configuring a 64-bit Windows server, replace all instances of prunsrv with one of the following commands, according to your operating system:
    prunsrv_amd64
    prunsrv_ia64
    This command invokes the appropriate script that starts the Windows service daemon in 64-bit Java instead of 32-bit Java. 
  3. To prevent the process from forking into more than one process, increase the maximum heap size and the PermGen JVM parameters. Locate the set jvm_options command and set the value as follows:

    set jvm_options=-XX:MaxPermSize=256M;-Xmx1792m

  4. Open Command Prompt, change the current directory to the crx-quickstart/opt/helpers folder of the AEM installation, and enter the following command to create the service:

    instsrv.bat cq5

    To verify that the service is created, open Services in the Administrative Tools control panel or type start services.msc in Command Prompt. The cq5 service appears in the list.

  5. Start the service by doing one of the following:
    1. In the Services control panel, click cq5 and click Start.
      StartServices
    2. In the command line, type net start cq5
      StartCommandprompt
  6. Windows indicates that the service is running. AEM starts and the prunsrv executable appears in Task Manager.

    prunsrv

  7. Note: The property values in the instsrv.bat file are used when creating the Windows service. If you edit the property values in instsrv.bat, you must uninstall and then re-install the service.

  8. To uninstall the service, either click Stop in the Services control panel or in the command line, navigate to the folder and type instsrv.bat -uninstall cq5. The service gets removed from the list in the Services control panel or from the list in the command line when you type net start.

Ref: http://dev.day.com/docs/en/cq/current/getting_started/download_and_startworking.html#Installing%20and%20Starting%20Adobe%20Experience%20Manager%20as%20a%20Windows%20Service

Sunday, September 15, 2013

How to get Service in JSP?

Below are the two easiest ways to get Service:

1. Using the slingScriptHelper     

<sling:defineObjects />

<%

      ServiceType service = sling.getService(ServiceType.class);

%>

2. Using adaptTo()

adaptTo() method that will translate the object to the class type being passed as the argument.

Example:

Node node = resource.adaptTo(Node.class);

More Info on Adaptors: http://dev.day.com/docs/en/cq/current/developing/sling-adapters.html

Handy URLs–AEM 5.6

URLs

/crx/explorer/index.jsp  - CRX explorer

/crx/de/index.jsp – CRXDE Lite url

/damadmin     - DAM

/libs/cq/search/content/querydebug.html – Query debug tool

/libs/granite/security/content/admin.html – New user manager standalone ui  [5.6 only?]

/libs/cq/contentsync/content/console.html – Content sync console

/system/console/bundles – Felix web admin console

/system/console/jmx/com.adobe.granite.workflow%3Atype%3DMaintenance - Felix web admin console JMX / Workflow maintenance tasks

/system/console/jmx/com.adobe.granite%3Atype%3DRepository - Felix web admin console JMX / Repository maintenance tasks

/system/console/depfinder – This new 5.6 tool will help you figure out what package exports a class and also prints a Maven Dependency for the class.

/libs/granite/ui/content/dumplibs.rebuild.html?rebuild=true – Helpful link for debugging caching problems. Wipes the clientlibs and designs and forces it to rebuild it. Thanks to Mark Ellis for this link.

/system/console/adapters – This link shows you the Adapters are registered in the system. This helps you figure out what you can adaptTo() from resource to resource.

Params

wcmmode=DISABLED - This handy publisher parameter turns off CQ authoring features so you can preview a page cleanly

Thursday, September 5, 2013

How to get Administrative Resource Resolver in jsp?

 

Generic Code to get service from the OSGI service registry:

================================================================

If you are in a JSP Script you can do

<cq:defineObjects />

<%

      ServiceType service = sling.getService(ServiceType.class);

   %>

==================================================================

Get Administrative Resource Resolver :

<%!

      /**
           @Parms: ResourceResolverFactory
          returns ResourceResolver , Admin resource resolver will be return
    */
    public ResourceResolver getRR(ResourceResolverFactory resolverFactory)
    {

        ResourceResolver rr=null;
        try{

            rr= resolverFactory.getAdministrativeResourceResolver(null);
        }catch(Exception e)
        {
            System.out.println("RRF Exception:"+e.getMessage());
        }
        return rr;
    }

%>

<%

//Get ResourceResolverFactory service from OSGI service Registry

org.apache.sling.api.resource.ResourceResolverFactory  rrFactory = sling.getService(org.apache.sling.api.resource.ResourceResolverFactory.class);

          Resource r = getRR(rrFactory);  

%>

Wednesday, July 31, 2013

How to get Resource?

In OSGI Service/Compoment
You can access a resource through the JcrResourceResolverFactory service:

@Reference
private SlingRepository repository;

@Reference
private JcrResourceResolverFactory resolverFactory;

public void myMethod() {
    Session adminSession = null;   
    try {       
         String resourcePath = "path/to/resource";       
         adminSession = repository.loginAdministrative(null);       
         ResourceResolver resourceResolver = resolverFactory.getResourceResolver(adminSession);       
         Resource res = resourceResolver.getResource(resourcePath);    
    } catch (RepositoryException e) {
        log.error("RepositoryException: " + e);   
    } finally {       
        if (adminSession != null && adminSession.isLive()) {
           adminSession.logout();          
                adminSession = null;       
         }    
     }
}
In JSP

<sling:defineObjects>
<%
String resourcePath = "path/to/resource";
Resource res = resourceResolver.getResource(resourcePath);
%>
 

Monday, July 29, 2013

What is the notation of translation site to be created? (Managing Different Language Versions of a Website)

1. In the Websites tab, in the left pane, select the site.

2. Add a new language branch to the site:

    a. Click New..

    b. In the dialog, specify the Title and the Name.

        The Name needs to have the following format:
<language-code> or <language-code>_<country-code>
        - the supported language code is lower-case, two-letter code as defined by ISO-639-1
        - the supported country code is lower-case or upper-case, two-letter code as defined by ISO 3166
Examples: en, en_US, en_us, en_GB, en_gb.

        Select the Template and click Create.   

file

3. In the Websites tab, in the left pane, select the site.

4. In the Tools menu, select Language Copy.

file

5. The Language Copy dialog opens. It displays a matrix of the language versions available for individual pages. An x in a language column means that the page is available within the language tree.

file

6. To copy an existing page or page tree to a specific language first select the appropriate empty cell. Then click the arrow and select the type of copy in the drop-down menu.

Type of language copy
Description

auto
Uses the behavior from parent pages

ignore
Cancels the copy for this page and its children

<language>+ (e.g. French+)
Copies the page and all its children from that language

<language> (e.g. French)
Copies only the page from that language

file

7. Click OK to close the dialog.

8. In the next dialog, click Yes to confirm the copy.

Wednesday, July 24, 2013

How to create AEM Groups package including ACLs?

Download the custom package from : http://www.wemblog.com/2011/11/how-to-create-package-based-on-xpath-in.html
1) Install package using package manager
2) go to <host>:<port>/apps/tools/components/createPackage/run.html
3) Give your Xpath in xpath value
4) You can also add comma separate exclude path that you don't want to add to package.
5) Click on Create config package
6) Now Download the package and also be saved under /etc/packages/CQSupportTool
For example if you have to create package of all ACL to migrate from one CQ instance to another you can use xpath query for package as //element(*,rep:ACL)

Example:

Ref: http://www.wemblog.com/2011/11/how-to-create-package-based-on-xpath-in.html

Wednesday, July 10, 2013

How can we hide the CMS Console Buttons

 

How can we hide some of the CMS consoles / tabs (like the Site Admin, DAM Admin, Tools, Security, Workflow and Tagging) via permissions?

Answer:  Uncheck the READ permission for groups/users on the corresponding console node.

Ref: http://helpx.adobe.com/cq/kb/CQ53HowToHideCQNavigationButtons.html

Monday, July 8, 2013

Syntax while executing Shell Script in windows

Error Type:

./script.sh: line 1: syntax error near unexpected token '$'do\r''

Or ...

./script.sh: line 1: $'\r': command not found

Solution:  http://www.jwgoerlich.us/blogengine/post/2007/06/08/Tip-Bash-scripting-in-Cygwin-without-5cr-syntax-errors.aspx

How to take Thread Dumps from a JVM

Step 1: Get the PID of your java process

The java JDK ships with the jps command which lists all java process ids.

You can run this command like this: jps –l

8112
1396 sun.tools.jps.Jps
3576 crx-quickstart\app\cq-quickstart-5.6.0-standalone.jar

Step 2 : Request a Thread Dump from the JVM

In windows:

1. Install cygwin to run shell script

2. set path to the environment variable list.

3. Add following script in the <name>.sh

#!/bin/bash
if [ $# -eq 0 ]; then
    echo >&2 "Usage: jstackSeries <pid> <run_user> [ <count> [ <delay> ] ]"
    echo >&2 "    Defaults: count = 10, delay = 0.5 (seconds)"
    exit 1
fi
pid=$1          # required
user=$2         # required
count=${3:-10}  # defaults to 10 times
delay=${4:-0.5} # defaults to 0.5 seconds
while [ $count -gt 0 ]
do
    jstack -F $pid >jstack.$pid.$(date +%H%M%S.%N)
    sleep $delay
    count=`expr $count - 1`
    echo -n "."
done

          4. You can run this shell script like:

               sh  <name>.sh <Process Id of AEM> <Intervals> <No.of Threads>

              Eg:  sh TrheadDump.sh  4321 10 5

              Result: It takes 5 thread dumps at an intervals of 10 sec.

Note: Running CQ on UNIX ?

           Reference: http://helpx.adobe.com/cq/kb/TakeThreadDump.html 

 

Friday, June 28, 2013

How to check whether the payload is subjected to the workflow or not?

You can use “com.adobe.granite.workflow.status.WorkflowStatus” API to check the WF status of the payload.

      Eg:

WorkflowStatus wfState = <payload object>.adaptTo(WorkflowStatus.class);

          boolean status=false;
          status = wfState.isInRunningWorkflow(true);

HTTP Authentication for HttpURLConnection

Here is the piece of code which you can use for HTTP Authentication while connecting to CQ url:

                final String login ="admin";
                final String password ="admin";
               
                Authenticator.setDefault(new Authenticator() {
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication (login, password.toCharArray());
                    }
                });

              String webPage ="http://localhost:8502/etc/workflow/models/translation?path=test";
              URL url = new URL(webPage);
              URLConnection urlConnection = url.openConnection();

Saturday, June 22, 2013

OSGi Events

Every OSGi framework sends (asynchronously) a number of events that can be captured by any bundle.

Framework Events
  • org/osgi/framework/BundleEvent/STARTED
  • org/osgi/framework/BundleEvent/ERROR
  • org/osgi/framework/BundleEvent/PACKAGES_REFRESHED
  • org/osgi/framework/BundleEvent/STARTLEVEL_CHANGED
  • org/osgi/framework/BundleEvent/WARNING
  • org/osgi/framework/BundleEvent/INFO
Bundle Events
  • org/osgi/framework/BundleEvent/INSTALLED
  • org/osgi/framework/BundleEvent/STARTED
  • org/osgi/framework/BundleEvent/STOPPED
  • org/osgi/framework/BundleEvent/UPDATED
  • org/osgi/framework/BundleEvent/UNINSTALLED
  • org/osgi/framework/BundleEvent/RESOLVED
  • org/osgi/framework/BundleEvent/UNRESOLVED

The followig properties are always present in a bundle event object:

  • bundle.id
  • bundle.symbolicName
Service Events
  • org/osgi/framework/ServiceEvent/REGISTERED
  • org/osgi/framework/ServiceEvent/MODIFIED
  • org/osgi/framework/ServiceEvent/UNREGISTERING

The following properties are always present in a service event object:

  • service
  • service.id
  • service.pid

Ref: http://felix.apache.org/site/apache-felix-event-admin.html

Tuesday, June 18, 2013

How to disable options like ‘Activate’, ‘Delete’, ‘move’ and etc.. to user/group?

 

Disable options

For example, How to disable/remove ‘Activate’ or ‘Deactivate’ option to the specific user/group.

Solution:

1. Go to the CQ useradmin

2. Select the user/group and disable read permissions under (/libs/wcm/core/content/siteadmin/actions).

Thursday, June 13, 2013

How to impersonate the seesion in the workflow?

Here is the piece of code to impersonate the session:

@Reference
SlingRepository repo;

Session adminSession = repo.loginAdministrative(null);
Session userSession = adminSession.impersonate (new SimpleCredentials("<userId>",new char[0]));

          log.debug(“Session is: {}”, userSession.getUserID());

Tuesday, June 11, 2013

Parallel content authoring in AEM/CQ

Q: What if there are two groups of marketing users that want to author the same site/page at the same time but have a different release schedule? How would you solve this problem?

Ans: We can create two launches for each release and various teams can author content and release at different times. Launches is a new feature in AEM(5.6) and documentation can be found here.

Friday, June 7, 2013

Performance Tuning Tips

Performance problems in CQ can be due to many things in combination. Here are few performance tuning tips which improve your CQ performance.

http://helpx.adobe.com/cq/kb/performancetuningtips.html

How to remove features from welcome screen

Question: How do you remove features from the welcome screen, so that only restricted users can access what is allowed? (Eg. Deny a user from accessing the siteadmin Or damadmin).

Solution


You can remove read permission to any of the following nodes in order to deny users from seeing these features in the welcome screen (To deny read permission, please use the security admin console with a superuser) -
1. Modules
Disabling Read Permissions at below levels will disable all the CQ 'Modules' from the welcome screen as well as deny access to the direct urls..

Eg: Disabling Read permissions at ' /libs/wcm/core/content/siteadmin' will Remove 'Websites' option from the welcome screen as well as http://<host>:<port>/siteadmin.html will not be accessible.

Websites - /libs/wcm/core/content/siteadmin
Digital Assets - /libs/wcm/core/content/damadmin
Communities - /libs/collab/core/content/admin
Campaigns - /libs/mcm/content/admin
Inbox - /libs/cq/workflow/content/inbox
Users - /libs/cq/security/content/admin
Tools - /libs/wcm/core/content/misc
Tagging - /libs/cq/tagging/content/tagadmin

2. Resources

Cloud Services -
         Welcome Screen  -  /libs/cq/core/content/welcome/resources/cloudservices
         Url  -  /etc/cloudservices
Workflows
         Welcome Screen  - /libs/cq/core/content/welcome/resources/workflows
          Url   -  /libs/cq/workflow/content/console
Task Management
         Welcome Screen - /libs/cq/core/content/welcome/resources/taskmanager
          Url   -  /libs/cq/taskmanagement/content/taskmanager
Replication
         Welcome Screen  - /libs/cq/core/content/welcome/resources/replication
         Url  -  /etc/replication
Reports
         Welcome Screen  - /libs/cq/core/content/welcome/resources/reports
         Url   -  /libs/wcm/core/content/misc
Publications
        Welcome Screen  - /libs/cq/core/content/welcome/resources/publishingadmin
        Url   -  /libs/media/publishing/admin/content/admin
Manuscripts
       Welcome Screen  - /libs/cq/core/content/welcome/resources/manuscriptsadmin
       Url    - /libs/media/articles/admin/content/admin


3. Docs
Documentation
        Welcome Screen - /libs/cq/core/content/welcome/docs/docs
Developer Resources
        Welcome Screen - /libs/cq/core/content/welcome/docs/dev

4. Features
CRXDE Lite
        Welcome Screen  - /libs/cq/core/content/welcome/features/crxde
         Url  - As per my knowledge, we need to deny access at dispatcher level/ need to write custom service.
Packages
        Welcome Screen - /libs/cq/core/content/welcome/features/packages
        Url  -  libs/crx/cor/content/welcome/core/crx
Package Share
         Welcome Screen - /libs/cq/core/content/welcome/features/share
Clustering
        Welcome Screen  - /libs/cq/core/content/welcome/features/cluster
        Url  -  /libs/granite/cluster/content/admin
Backup 
       Welcome Screen - /libs/cq/core/content/welcome/features/backup
       Url   - /libs/granite/backup/content/admin
OSGi Console
      Welcome Screen - /libs/cq/core/content/welcome/features/config
       Url -  Can't be accessible withour credentials..so there won't be any issue..
OSGi Console Status Dump
       Welcome Screen - /libs/cq/core/content/welcome/features/statusdump
        Url  - /libs/crx/core/content/welcome/osgi/statusdump

Ref:  http://helpx.adobe.com/cq/kb/remove-features-welcome-screen.html









xtypes in CQ

 

http://wem.help.adobe.com/enterprise/en_US/10-0/wem/developing/widgets.html

Wednesday, June 5, 2013

Handy Urls

URLS

/crx/explorer/index.jsp  - CRX explorer

/crx/de/index.jsp – CRXDE Lite url

/libs/cq/search/content/querydebug.html – Query debug tool

/libs/granite/security/content/admin.html – New user manager standalone ui  [5.6 only?]

/libs/cq/contentsync/content/console.html – Content sync console

/system/console/bundles – Felix web admin console

/system/console/jmx/com.adobe.granite.workflow%3Atype%3DMaintenance - Felix web admin console JMX / Workflow maintenance tasks

/system/console/jmx/com.adobe.granite%3Atype%3DRepository - Felix web admin console JMX / Repository maintenance tasks

/etc/reports/diskusage.html?path=/content/dam – To know the size of the repository

Params

wcmmode=DISABLED - This handy publisher parameter turns off CQ authoring features so you can preview a page cleanly

/system/console/depfinder – This new 5.6 tool will help you figure out what package exports a class and also prints a Maven Dependency for the class.

If you have more handy URL’s and or parameters that you think others should know about please comment on this blog entry and I will add them to the list.

Tuesday, June 4, 2013

How to create a custom xtype element for Dialogs ? How to make it as a replicant ?

We can create a custom xtype using the out of the box xtypes from AEM. We can do it using the compositeField. Composite field allows a number of form Fields to be rendered on the same row. We use EXT JS to extend Composite Field and add all the required fields into it as a list. Then, we can register this Class as a custom xtype.

Any user who needs this list of fields together can directly use this custom xtype while developing dialogs instead of creating them individually.  We can use this custom xtype as a mutilfield to make it as a replicant.
Code and Steps are given below.

1) Registering the Custom Component :  Create a Javascript file in Client Lib folder and add that into the Component JSP. This Javascript file is used to create the custom xtype and then register it to with EXT JS , so that it can be used in Dialogs.

CustomPathField.js
----------------------------------------------------------------------------------------------------------------------------------
/**
* @class MyClientLib.CustomPathFieldWidget
* @extends CQ.form.CompositeField
* This is a custom path field with a Link Text and a Link URL
* @param {Object} config the config object
*/
/**
* @class Ejst.CustomWidget
* @extends CQ.form.CompositeField
* This is a custom widget based on {@link CQ.form.CompositeField}.
* @constructor
* Creates a new CustomWidget.
* @param {Object} config The config object
*/

CQ.form.CustomMultiField = CQ.Ext.extend(CQ.form.CompositeField, {
/**
* @private
* @type CQ.Ext.form.TextField
*/
hiddenField: null,
/**
* @private
* @type CQ.Ext.form.TextField
*/
linkText: null,
/**
* @private
* @type CQ.Ext.form.PathField
*/
linkURL: null,
/**
* @private
* @type CQ.Ext.form.CheckBox
*/
openInNewWindow: null,

constructor: function (config) {
config = config || {};
var defaults = {
    "border": true,
    "labelWidth": 75,
    "layout": "form"
};
config = CQ.Util.applyDefaults(config, defaults);
CQ.form.CustomMultiField.superclass.constructor.call(this, config);
},
initComponent: function () {

    CQ.form.CustomMultiField.superclass.initComponent.call(this);
    // Hidden field
    this.hiddenField = new CQ.Ext.form.Hidden({
         name: this.name
    });
    this.add(this.hiddenField);

// Text TextField to enter Title
    this.linkText = new CQ.Ext.form.TextField({
        cls: "customwidget-1",
        maxLength: 100,
        emptyText: "Enter Title",
        maxLengthText: "A maximum of 100 characters is allowed for the Link Text.",
        width: 335,
        allowBlank: true,
        name : "item",
        listeners: {
        change: {
        scope: this,
        fn: this.updateHidden
    }
    }
    });
    this.add(this.linkText);

// Link PathField to map a URL
  this.linkURL = new CQ.form.PathField({
        cls: "customwidget-2",
        allowBlank: true,
        emptyText: "Enter Title URL",
width: 335,
        listeners: {
         change: {
            scope: this,
            fn: this.updateHidden
        },    
        dialogclose: {
            scope: this,
            fn: this.updateHidden
        }
       }
    });
    this.add(this.linkURL);

    // Link openInNewWindow
    this.openInNewWindow = new CQ.Ext.form.Checkbox({
        cls: "customwidget-3",
        boxLabel: "New window",
        listeners: {
        change: {
        scope: this,
        fn: this.updateHidden
        },
        check: {
        scope: this,
        fn: this.updateHidden
    }
    }
    });
    this.add(this.openInNewWindow);
},
processInit: function (path, record) {
    this.linkText.processInit(path, record);
    this.linkURL.processInit(path, record);
    this.openInNewWindow.processInit(path, record);
},
setValue: function (value) {
    var link = JSON.parse(value);
    this.linkText.setValue(link.text);
    this.linkURL.setValue(link.url);
    this.openInNewWindow.setValue(link.openInNewWindow);
},
getValue: function () {
    return this.getRawValue();
},
getRawValue: function () {
    var link = {
    "url": this.linkURL.getValue(),
    "text": this.linkText.getValue(),
    "openInNewWindow": this.openInNewWindow.getValue()
    };
    return JSON.stringify(link);
},
updateHidden: function () {
this.hiddenField.setValue(this.getValue());
}
});
CQ.Ext.reg("CustomMultiField", CQ.form.CustomMultiField);
----------------------------------------------------------------------------------------------------------------------------------
When this Javascript is executed you should have the CustomMultiField as xtype.

2) Using the Custom Component in Dialog: Use this xtype in the Dialog to see all the 3 fields ( Text Field, Link Field , Open in New Window )  displayed as a set.  For example, if we want to display them as a multifield, here is how the dialog.xml should look like.

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:Dialog"
    width="550"
    xtype="dialog">
    <items
        jcr:primaryType="cq:Widget"
        xtype="tabpanel">
        <items jcr:primaryType="cq:WidgetCollection">
            <tab1
                jcr:primaryType="cq:Panel"
                title="Links Component">
                <items jcr:primaryType="cq:WidgetCollection">
                    <links
                        jcr:primaryType="cq:Widget"
                        border="false"
                        fieldDescription="Press + to add more links"
                        fieldLabel="Links"
                        hideLabel="true"
                        name="./links"
                        xtype="multifield">
                        <fieldConfig
                            jcr:primaryType="cq:Widget"
                            xtype="CustomMultiField"/>
                    </links>

                </items>
            </tab1>
        </items>
    </items>
</jcr:root>


Monday, June 3, 2013

Frequently Used CQ URLs

http://cq-ops.tumblr.com/post/21045033313/frequently-used-cq-urls

What are usual CQ Maintenance operations?

The following is the sequence recommended by Adobe.  A sample RHEL 6.3 shell script that invokes these operations using curl is available for download here.

ONCE PER DAY
——————————

BACKUP

1) Backup

OPTMIZATION

The elapsed times reported below are for a virgin CQ “author” instance with about 70,000 nodes and about 350,000 properties hosted on an SSD.

2) Tar Index Merge

3) Tar Optimization (~ 2 minutes)

This defragments the repository Tar files.  For massive DAM ingestion operations, here is a model that can predict how long this would take.

4) Tar Index Merge (again)

The automatically scheduled Tar optimization does in fact do an index merge, Tar optimize, and a second index merge.

FOR DEV Environment:

5) Consistency Check (~ 3 seconds)

6) Traversal Check (~ 4 seconds)

In addition, the following CQ Knowledge Base article discusses ways to prevent repository inconsistencies from occurring.  Here are links to the sample (v5.6)repository.xml, workspace.xml and start.bat (Windows).  Please note that these settings do slow down CQ startup times, the bigger your repository, the longer the startup.

ONCE PER WEEK
———————————

1) Datastore Garbage Collection (~ 4 minutes)

This removes orphaned files in the datastore that are no longer referenced from within the repository.  The bigger the data store, the longer this operation will take.  See this for a model to predict this.

If your repository is large, you can choose to start the following operations at a level lower than at the top (/ which represents the root of the hierarchical Java Content Repository).  E.g. /content/dam/MySite1Assets for Start Path.

Source: http://cq-ops.tumblr.com/post/29627149909/recommended-sequence-of-cq-maintenance-operations

Search Queries to Determine the Size of CQ’s Repository

CQ comes with a page that can be used to query its repository at http://server:port/crx/explorer/ui/search.jsp

Copy-paste them into the “Query” field and hit the ‘Search Now’ button.  Scroll to the bottom of the page to see total reported numbers.

Make sure you are logged in to CQ as “admin”.  

Total number of nodes

// * order by @jcr:score

Total number of CQ pages

// element(*, cq:Page) order by @jcr:score

Number of audit events

// element(*, cq:AuditEvent) order by @jcr:score

Number of digital assets in DAM

// element(*, dam:Asset) order by @jcr:score

Number of images

// metadata[jcr:like(@dam:MIMEtype, ‘image/%’)] order by @jcr:score

Number of tags

// element(*, cq:Tag) order by @jcr:score

Number of workflow instances

// element(*, cq:Workflow) order by @jcr:score

Number of websites that are “Live Copies” of other websites

// * [@cq:master and not(@jcr:frozenUuid)] order by @jcr:score

Source: http://cq-ops.tumblr.com/post/29906959491/search-queries-to-determine-the-size-of-cqs-repository

How to really delete assets from DAM?

In CQ DAM, files larger than a configurable size (4 KB by default) are kept in a separate “DataStore”.  This DataStore can be located on a separate disk or disk array for performance reasons.

When digital assets are deleted from CQ DAM, they are only “marked” for deletion.  The real cleanup of the DataStore happens during a process called “DataStore Garbage Collection” (DS-GC).  This can be triggered from the Apache Felix OSGi Console (JMX tab) - click on the “Repository” MBean.

How long the DataStore Garbage Collection takes depends on the size of your CQ DAM repository. A property called  ’DataStoreGarbageCollectionDelay’ controls how long (in milliseconds) this process pauses after processing 10 JCR nodes.  By default, this is 10 milliseconds.

For example, if your JCR has 25 million nodes (the result of about 250,000 assets), the scan will take (25 million nodes/10 nodes) x 10 milliseconds = about 7 hours.  The scan happens twice during a single DS-GC run - so the delay would be about 14 hours.

Testing by Adobe’s Server Performance Lab shows that the duration of this garbage collection can be significantly reduced by changing the value for ‘DataStoreGarbageCollectionDelay’ from the default “10” milliseconds to a lower number.  On one lab machine, setting this to 0 caused the duration of DS-GC to go from about 2 hours down to 7 minutes.  Of course, on a busy PRODUCTION system, 0 is a bad idea.

To change the value, just click on the 10.

Source: http://cq-ops.tumblr.com/post/35642664963/speeding-up-cq-dam-datastore-garbage-collection

Best Practices for Component Development in AEM

Good practicing standards on how to develop components including the most flexible folder structure are given below. 

Friday, May 31, 2013

How to configure custom mappings based on run mode?

 

Scenario: Having a requirement where we need to configure sling mappings based on run mode.

Example: Assume that we’ve three different environments called ‘author’, ‘preprod’ and ‘prod’

When we access http://<hostname>:<port>/projects   It has to redirect to three different urls based on run modes.

In author instance it should be redirected to  /content/test/author.html

In preprod instance it should be redirected to /content/test/preprod.html

In prod instance it should be redirected to /content/test/prod.html

Steps:

1.  Create different config.<runmode> nodes (of type sling:Folder) inside /apps/system/

Eg:    config.author     type    Sling:Folder

config.preprod    type    Sling:Folder

config.prod         type     Sling:Folder

2.   Create a new node of type Sling:OsgiConfig inside configuration folders.

       node name:   org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl

       type:            Sling:OsgiConfig

      2.a:    Add following properties to the node:

          1.  property name:     resource.resolver.map.location

     type:    String

              value:    /etc/map.<runmode>

2. property name: resource.resolver.manglenamespaces

    type: Boolean

    value: true

3. property name: resource.resolver.default.vanity.redirect.status

    type: Decimal

    value: 302

4. property name:  resource.resolver.mapping

   type: String []

   value: /-/

5. property name:  resource.resolver.searchpath

   type: String []

   value: "/apps","/libs","/apps/foundation/components/primary","/libs/foundation/components/primary"

6. property name: resource.resolver.required.providers

   type: String[]

   value:  org.apache.sling.jcr.resource.internal.helper.jcr.JcrResourceProviderFactory

7. property name: resource.resolver.allowDirect

   type: Boolean

   value: true

8. property name: resource.resolver.virtual

   type: String[]

   value: /:/

3.    Create different map configurations inside /etc.

       In our example, we can create Sling:Folders with following names:

       a.    map.author

       b.   map.preprod

       c.   map.prod

4.    Create configuration node for sling mapping inside /etc/map.<runmode>

     Eg:      Node name:     test

                 type:     Sling:OsgiConfig

       4.1  Add following properties to the config node

              a.   property name:    sling:match

                    type:    String

                   value:    <Some regular expression/match>

b.    property name: sling:redirect

      type: String

                value: <Some regular expression/match>

5.   Test it..

Whats new in CQ 5.6?

The list of all new features in  CQ 5.6, click here 

Thursday, May 30, 2013

Issue while initiating workflow

 

Problem: I've deleted 'instances' folder inside /etc/workflow/ directory.  When I initiate the workflow, the folder 'instances' is automatically created under /etc/workflow/ but the workflow is not triggered on the payload.

Solution:

  • Make sure to delete the instances folder.
  • Save the changes
  • Create a instances node of type sling:folder
  • To the instances node add a property sling:resourceType with value equal to ‘cq/workflow/components/instances’

        Also add property jcr:title Instances

  • Restart the workflow bundle from felix console or restart the instance.

How to provide access to the groups for felix console?

 

1. Go to http://<hostname>:<port>/system/console/configMgr

2. Edit the configuration called “Apache Sling Web Console Security Provider”

Security Console

3. Add groups names to which you wanted to provide felix access.

4. Save.

How to migrate huge number of assets from one AEM instance to another?

 

We’ve found following best process:

1. Installed ‘recap’ package (rsync for CRX).

    More Info about Recap: http://aemtips.blogspot.in/2013/05/rsync-for-aem.html

2. Go to http://<cqhost>:<port>/system/console/components

3. Disable following workflow launcher bundles:

com.adobe.granite.workflow.core.launcher.WorkflowLauncherImpl

com.adobe.granite.workflow.core.launcher.WorkflowLauncherListener

4.  Go to http://<cqhost>:<port>/recap

    Create address , update fields as required and continue.

Note: Enable workflow launchers once the migration is done.

One of the important coding standard for fronted developers to speed up page loading time

https://developers.google.com/speed/docs/best-practices/rtt#PutStylesBeforeScripts

Wednesday, May 29, 2013

How To Use Apache Maven to Build and Deploy OSGi Bundles to CQ?

Apache Maven is a successor to Apache Ant and is a key tool for CQ development.  Most of the heavy lifting in CQ is done by Java POJOs built and packaged as OSGi bundles and deployed to Apache Felix, which is CQ’s OSGi runtime framework.

There’s an outstanding 8-part introductory video tutorial series on Maven by Koushik Kothagal on YouTube.  That’s a great place to start to learn about Maven.

Here are the steps to get you set up:

1) If you haven’t done so yet, install and configure a 1.6 JDK.  Instructions here.

2) Download Apache Maven

3) Unzip to a folder.  Eg.  C:\Programs\Apache\Maven

4) Create separate folder for the Maven Repository - separate so that you can update Maven with a newer version without affecting the repo.  Eg. C:\Programs\Apache\Maven\local_repo

5) Configure system environment variables M2_HOME(C:\Programs\Apache\Maven\apache-maven-3.0.4) and M2_REPO(C:\Programs\Apache\Maven\local_repo)

6) Add the /bin folder of Maven to the beginning of the existing system environment variable Path as e.g. %M2_HOME%\bin;

7) Start a command prompt and test whether maven is working.

mvn —version

You should get a response such as this:

Apache Maven 3.0.4 (r1232337; 2012-01-17 03:44:56-0500)
Maven home: C:\Programs\Apache\Maven\apache-maven-3.0.4
Java version: 1.6.0_31, vendor: Sun Microsystems Inc.
Java home: C:\Programs\Java64-6\jre
Default locale: en_US, platform encoding: Cp1252
OS name: “windows 7”, version: “6.1”, arch: “amd64”, family: “windows”

8) Copy the Maven configuration file settings.xml from C:\Programs\Apache\Maven\apache-maven-3.0.4\conf\ to your Windows user profile.  Eg. C:\Users\JAYAN\.m2\

7) Edit settings.xml to configure the local repository.  Eg:

<localRepository>C:\Programs\Apache\Maven\local_repo</localRepository>

8) Sample Maven settings for Adobe’s public repository is available here.  Also see this from Adobe on integrating Adobe CQ FileVault and Apache Maven.

9) As a next step, see Craig Dickson’s article on the CQ Blueprints Maven Repository, developed by headwire.com.

Source: http://cq-ops.tumblr.com/post/31404223822/how-to-use-apache-maven-to-build-and-deploy-osgi

The Adobe CQ Blog Community

Adobe’s CQ Web Content Management System has a significant blogging community around it.  This attempts to document it.  It will be updated as new information becomes available.

Adobe

Partner

Customer

How to set up Run modes in AEM

 

Recommendation

Run modes allow you to tune your CQ instance for a specific purpose; for example author, publish or development. This is done by defining collections of configuration parameters for each run mode. A basic set is applied for all run modes, additional sets are each tuned to the purpose of your specific environment.

All configuration settings are stored in the one repository and activated by setting the Run Mode.

Standard run modes are:

  • author
  • publish

You can also create environment specific run mode such as,

  • author, development
  • publish, test
  • author, intranet, us or as required...

There are two mechanisms for setting standard and environment specific run mode for your instance:

  • To set up standard run mode Use the naming convention:
   cq-<standard-run-mode>-<port-number>

For example, set a standard run mode by naming the jar file cq-author-4502 or cq-publish-4503


  • To set up environment specific run mode there are two methods,

Method 1:

Through <cq-installation-dir>/crx-quickstart/config/sling.properties Add the following properties (following example is for author, prod, marketing):

   sling.jcrinstall.folder.name.regexp=.*/(install|config)?
sling.run.modes=author,prod,marketing

In above case config.author.prod.marketing will get picked up (Or whatever with maximum match)

Method 2:

Through <cq-installation-dir>/crx-quickstart/config/sling.properties and system property (In start script):

 sling.jcrinstall.folder.name.regexp=.*/(install|config)?      #<------ In sling.properties file
-Dsling.run.modes=publish,prod,marketing #<----- In start script or system property

In above case config.publish.prod.marketing will get picked up (Or whatever with maximum match)

Configuration values for the run modes are saved in the repository. You can store all configurations in one repository as the run mode is indicated by a suffix on the folder name; for example:

 config, applicable for all run modes
config.author, used in author run mode
config.publish, used in publish run mode
config.<standard-run-mode>.<env-specific-mode>, used in the applicable run mode
References:

http://www.wemblog.com/2012/01/how-to-set-up-run-mode-in-cq-wem.html
http://dev.day.com/docs/en/cq/current/deploying/configure_runmodes.html
http://helpx.adobe.com/cq/kb/RunModeSetUp.html
http://helpx.adobe.com/cq/kb/RunModeDependentConfigAndInstall.html


 

 

Customize column control

 

OOTB provides components related to the  column controls, but If we directly drag and drop the components on to the page, we can't find such number of columns in the column control. Because we need to add styles to define different columns:
Here you go..
Customize column control:
---------------------------------------------------------------------------
Add the following styles in css:
/* layout 0 : 50% 50%  i.e., two columns wiht 50% , 50%*/
div.cq-colctrl-lt0 { }
div.cq-colctrl-lt0-c0 { width: 340px; margin-right:10px}
div.cq-colctrl-lt0-c1 { width: 340px; margin-left: 10px}
/* layout 1 : 33% 33% 33%  Three columns */
div.cq-colctrl-lt1 { }
div.cq-colctrl-lt1-c0 { width: 220px; margin-right: 10px;}
div.cq-colctrl-lt1-c1 { width: 220px; margin-left: 10px; margin-right: 10px;}
div.cq-colctrl-lt1-c2 { width: 220px; margin-left: 10px; }
Add follwoing colctrl design mode:
---------------------------------------------------------------------------
2;cq-colctrl-lt0      2 Columns (50%, 50%)
3;cq-colctrl-lt1      3 Columns (33%, 33%, 33%)


so that we can get options for two & three columns.

What Happens when a video is uploaded to DAM?

When a video is uploaded to CQ DAM, the same workflow (“DAM Update Asset”) that kicks in for PDFs (described here) also kicks in.

However, the following two worksteps are specific to video ingestion:

For these to work, ffmpeg needs to be downloaded and installed (CQ does NOT come packaged with it).  See here for instructions.

The workstep “FFmpeg thumnails” uses the built-in process “Create Video Thumbnails”.  It extracts video frames and uses them as thumbnails.  See below:

The ‘Arguments’ count:4,index:2,[140:100],[48:48],[319:319] means that 4 key frames will be extracted (count:4), the third extracted key frame (index:2, 0-based index) will be used to generate 3 thumbnails of dimensions140x100 pixels, 48x48 pixels, and 319x319 pixels.  More documentation on this available here.

The server.log will report all of this.  Example below:

*INFO* [JobHandler: /etc/workflow/instances/2012-11-10/model_788493259155:/content/dam/s7/IMG_0268.MOV/jcr:content/renditions/original] com.day.cq.dam.handler.ffmpeg.FFMpegWrapper **** Exec (info): [C:\Programs\FFMPEG\bin\ffmpeg.exe -i C:\Programs\Adobe\CQ_5.5\author\java_io_tmpdir\cqdam7954583360797884766.tmp\IMG_0268.MOV]

*INFO* [JobHandler: /etc/workflow/instances/2012-11-10/model_788493259155:/content/dam/s7/IMG_0268.MOV/jcr:content/renditions/original] com.day.cq.dam.handler.ffmpeg.FFMpegWrapper **** Exec (thumbs): [C:\Programs\FFMPEG\bin\ffmpeg.exe -ss 0.0 -i C:\Programs\Adobe\CQ_5.5\author\java_io_tmpdir\cqdam7954583360797884766.tmp\IMG_0268.MOV -vframes 1 -y C:\Programs\Adobe\CQ_5.5\author\java_io_tmpdir\cqdam7954583360797884766.tmp\tempthumb.1352590934080.0.jpg]

As you can see, there is disk I/O happening to the folder configured as the Java temp directory.  You can control this with the JVM init argument in CQ’s start.bat.  Example: -Djava.io.tmpdir=E:\CQ_5.5_temp

…..

*INFO* [JobHandler: /etc/workflow/instances/2012-11-10/model_788493259155:/content/dam/s7/IMG_0268.MOV/jcr:content/renditions/original] com.day.cq.dam.handler.ffmpeg.FFMpegWrapper created 4 thumbnails

The workstep “FFmpeg transcoding” uses the built-in process “Transcode Video” to create additional renditions of the original video.

The arguments profile:firefoxhq,profile:hq,profile:flv means that all the three video profiles defined in CQ will be used. firefoxhq will create a highquality .ogg rendition, hq will create a high quality H.264 (.m4v) rendition andflv will create a low quality (320x240 pixels) Flash Video rendition.  To see these video profiles, navigate to Tools->DAM->Video Profiles (/miscadmin#/etc/dam/video).  See below:

You can edit these video profiles to fit your needs.

I recently shot a 1:26 minute video using a Canon EOS 5D MK III.  Shot in 1920x1080 at 30 frames per second, the file size was 955,114,640 bytes and in the .MOV format.  The video details, as listed by MediaInfo is shown below:

Upon ingestion to CQ DAM, metadata got extracted, thumbnails got generated (140 pixels x 100 pixels, 319x319, and 48x48), and two additional video renditions were generated (OGG and FLV at 320 pixels x 240 pixels).

—————————

The OGG rendition was available at /jcr:content/renditions/cq5dam.video.firefoxhq.ogg

The server.log reported this:

*INFO* [JobHandler: /etc/workflow/instances/2012-11-10/model_788493259155:/content/dam/s7/IMG_0268.MOV/jcr:content/renditions/original] com.day.cq.dam.handler.ffmpeg.FFMpegWrapper **** Exec: [C:\Programs\FFMPEG\bin\ffmpeg.exe -i C:\Programs\Adobe\CQ_5.5\author\java_io_tmpdir\cqdam7155082853427817219.tmp\IMG_0268.MOV -b 4096k -r 24000/1001 -bt 4069k -acodec libvorbis -ac 2 -ar 44100 -ab 128k -y C:\Programs\Adobe\CQ_5.5\author\java_io_tmpdir\cqdam7155082853427817219.tmp\IMG_0268.out.ogg]

—————————-

The FLV rendition was available at /jcr:content/renditions/cq5dam.video.flv.320.240.flv  The server.log reported this:

*INFO* [JobHandler: /etc/workflow/instances/2012-11-10/model_788493259155:/content/dam/s7/IMG_0268.MOV/jcr:content/renditions/original] com.day.cq.dam.video.FFMpegTranscodeProcess processVideo: creating video using profile [flv]

*INFO* [JobHandler: /etc/workflow/instances/2012-11-10/model_788493259155:/content/dam/s7/IMG_0268.MOV/jcr:content/renditions/original] com.day.cq.dam.handler.ffmpeg.FFMpegWrapper **** Exec (info): [C:\Programs\FFMPEG\bin\ffmpeg.exe -i C:\Programs\Adobe\CQ_5.5\author\java_io_tmpdir\cqdam7155082853427817219.tmp\IMG_0268.MOV]

*INFO* [JobHandler: /etc/workflow/instances/2012-11-10/model_788493259155:/content/dam/s7/IMG_0268.MOV/jcr:content/renditions/original] com.day.cq.dam.handler.ffmpeg.FFMpegWrapper **** Exec: [C:\Programs\FFMPEG\bin\ffmpeg.exe -i C:\Programs\Adobe\CQ_5.5\author\java_io_tmpdir\cqdam7155082853427817219.tmp\IMG_0268.MOV -s 320x240 -b 200k -r 12 -acodec libmp3lame -ac 1 -ar 22050 -ab 56k -y C:\Programs\Adobe\CQ_5.5\author\java_io_tmpdir\cqdam7155082853427817219.tmp\IMG_0268.out.flv]

——————-

The H.264 rendition failed with the following error messages:

*INFO* [Thread-85] com.day.cq.dam.handler.ffmpeg.FFMpegWrapper FFMPEG Exec: Unrecognized option ‘directpred’

*INFO* [Thread-85] com.day.cq.dam.handler.ffmpeg.FFMpegWrapper FFMPEG Exec: Failed to set value ‘3’ for option ‘directpred’

*ERROR* [JobHandler: /etc/workflow/instances/2012-11-10/model_788493259155:/content/dam/s7/IMG_0268.MOV/jcr:content/renditions/original] com.day.cq.dam.video.FFMpegTranscodeProcess Process exited with an error: 1(Exit value: 1) java.io.IOException: Process exited with an error: 1(Exit value: 1)

To fix this, remove the custom ffmpeg arguments for the H.264 video profile, and set the audio codec as alac, as described here.

———————

The M4V rendition will be available at /jcr:content/renditions/cq5dam.video.hq.m4v  The server.log will report this:

*INFO* [JobHandler: /etc/workflow/instances/2012-11-10/model_8772044570710:/content/dam/s7/IMG_0268.MOV/jcr:content/renditions/original] com.day.cq.dam.video.FFMpegTranscodeProcess processVideo: creating video using profile [hq]

*INFO* [JobHandler: /etc/workflow/instances/2012-11-10/model_8772044570710:/content/dam/s7/IMG_0268.MOV/jcr:content/renditions/original] com.day.cq.dam.handler.ffmpeg.FFMpegWrapper **** Exec (pass1): [C:\Programs\FFMPEG\bin\ffmpeg.exe -i C:\Programs\Adobe\CQ_5.5\author\java_io_tmpdir\cqdam3621509705265785387.tmp\IMG_0268.MOV -b 6144k -r 24000/1001 -bt 8192k -vcodec libx264 -acodec alac -ac 2 -ar 44100 -ab 128k -y -pass 1 C:\Programs\Adobe\CQ_5.5\author\java_io_tmpdir\cqdam3621509705265785387.tmp\IMG_0268.out.m4v]

If everything is successful, the following JCR structure will be created (3 thumbnails, 3 video renditions + original video).

The metadata JCR node contained multiple properties, representing the metadata extracted from the original video:

Source: http://cq-ops.tumblr.com/post/35446114362/what-happens-when-a-video-is-uploaded-to-cq-dam

API differences b/t CQ5.5 & 5.6

 

While developing workflows in AEM 5.6, please keep in mind that com.day.cq.workflows.* has been updated with com.adobe.granite.workflows.*

Note: Still com.day.cq.workflows API works in AEM 5.6 but you will face some issue with it..

Example: Participant step will not avail in participant chooser step in the workflow model.

Ref: http://dev.day.com/docs/en/cq/current/diff-previous/changes.html

How to Efficiently Copy Large Amounts of Content Between CQ Repositories?

There are multiple options available in CQ to move content from one CQ instance to another.  These include “replication” (author->publish), create package->export->install elsewhere, VLT rcp command line and recap.

The File Vault (vlt) tool has a Remote Copy (rcp) option as well - one that is especially useful if you are moving GB or TB of digital assets (JCR node type dam:Asset) from DEV to STAGING to PRODUCTION.  Run all renditions workflows once on a very powerful DEV machine with large numbers of CPU cores and high throughput local storage.  Once done, perform vlt rcp to STAGING and PRODUCTION environments after turning off renditions workflows on those.

Since it streams data between online repositories, it does not use the Durbopackaging used by replication.  Tests by Adobe Performance Architect Gardner Buchanan shows that this is more storage efficient and avoids storage bloat (2:1 in the case of replication).

Gardner also recommends running multiple instances of vlt rcp against separate source tree structures to parallelize the whole operation.  To avoid unnecessary network traffic, run vlt rcp on one of the participant instances, not on a remote, third instance.

Also, tests indicate that the default batch size of 1000 should be reduced to 100 for better throughput.

Assuming that vlt is set up and configured, the following command will copy a large content tree at /content/dam/JJK-Folder-1 on one CQ “author” instance to another “author” instance.  In this case, both are running on the local machine but they can be remote.  Also, both don’t have to be in the same run mode.  Content can be remote copied from an “author” instance to a “publish instance.

vlt rcp -b 100 -r -u -n http://admin:admin@localhost:4502/crx/-/jcr:root/content/dam/JJK-Folder-1 http://admin:admin@localhost:4503/crx/-/jcr:root/content/dam/JJK-Folder-1

A test with 1,000 (1 MB) 1680 x 1050 JPG images copied 20,304 (dam:Asset) nodes (2,690,706,251 bytes) in 573,117 milliseconds - a throughput of 36 JCR nodes/second or 16 GB/hr.

In another test, I copied 44,802 (cq:Page) nodes (5,017,126 bytes) in 461,925 ms - that is a throughput of 97 JCR nodes/second or 37 MB/hr.

The process is differential, meaning only changed nodes are actually copied.  However, each and every source JCR node needs to be checked against each and every destination JCR node.

Source: http://cq-ops.tumblr.com/

How to get a Resource object when we have node path?

In Java:
@Reference
private ResourceResolverFactory resourceResolverFactory;
ResourceResolver resolver=null;
resolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
Resource res=null;
res= resolver.getResource("PATH");


In JSP:
Resource res= resourceResolver.getResource("PATH");

How to get a Node, Get node property, Add/Update node property:
Node node = res.adaptTo(Node.class);

Get property:
String prop= node.getProperty("Prop_name").getValue().getString();
String prop = node.setProperty("Prop_name","Value");
Note: Don't forget to save the session when the node is updated.

Update Node using PersistableValueMap:
Resource resource = resolver.getResource("Node Path");
if(resource !=null)
{
PersistableValueMap valueMap= resource.adaptTo(PersistableValueMap.class);
valueMap.put("propname","value");
valueMap.save();
}


How to get a JackRabbit session in the Workflow:
final JackrabbitSession jackrabbitSession = (JackrabbitSession) wfsession.getSession();
UserManager userManager = jackrabbitSession.getUserManager();

Difference between jsp include, cq include and sling include

Refer these links:

http://dev.day.com/content/ddc/blog/2010/09/crx_gems_using_slin.html

http://helpx.adobe.com/cq/kb/CQIncludes.html

  • When developing AEM components, Adobe recommends that you use <cq:include>.

  • <cq:include> allows you to directly include script files by their name when using the script attribute. This takes component and resource type inheritance into account, and is often simpler than strict adherence to Sling's script resolution using selectors and extensions.

Difference between Dialog and Design_Dialog

dialog:
The Dialog is a special kind of window with a form in the body and a button group in the footer. It is typically used to edit content, but can also just display information.
design_dialog:


    design_dialog (nt:unstructured) -specifies the design editing options for this component.
=============================================
1. How to retrieve values read from dialog (widget) to jsp?
Sol: String var= properties.get("<name of widget>","");
2. How to retrieve values from design_dialog to jsp?
Sol: String var= currentStyle.get("<name of widget>","");
==============================================

How to get NODE properties?

Below is the sample code :

<%@page import="javax.jcr.Session,javax.jcr.Node,org.apache.sling.jcr.resource.JcrResourceUtil,
com.day.cq.tagging.Tag,
com.day.cq.tagging.TagManager,com.day.cq.tagging.JcrTagManagerFactory"
%>
<%
     //Node node;
    Session session = slingRequest.getResourceResolver().adaptTo(Session.class);
    TagManager tagManager =   sling.getService(JcrTagManagerFactory.class).getTagManager(session);
    Tag tag = tagManager.resolve("/apps/webexample_siva/components/content/contact");
    //specify the path which you want to get
    Node node = tag.adaptTo(Node.class);
    String name= node.getName();
%>
//Iterate node properties and displays node property name and value
<%
     for(PropertyIterator propeIterator = node.getProperties() ; propeIterator.hasNext();)
     {
         Property prop= propeIterator.nextProperty();
         if(!prop.getDefinition().isMultiple())
         {
             %>
             <%=prop.getName() %> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<%=prop.getString() %> <br />
             <%
         }
     }
%>

How to retrieve configuration details in jsp/class

@Reference
    ConfigurationAdmin configAdmin;
Configuration config = configAdmin.getConfiguration("com.day.cq.mailer.DefaultMailService");
Dictionary<?, ?> d = config.getProperties();
log.debug("Configurations Dictionary:{}"+d);
String hostName= (String) d.get("smtp.host");

Configuring Email Notification

In order to send email from CQ, the Day CQ Mail Service needs to be configured properly.
Procedure: 1. Go to felix web console (http://<host-name>:<port>/system/console/configMgr)
2. Search for Day CQ Mail Service
3. Edit and configure as follows:
a.  The SMTP server port must be 25 or higher.
b.  The SMTP server host name must not be blank.
c.  The "From" address must not be blank. 
Screen shot:

Simple code to send an email
There are difference ways to send an email.
Method 1: Using SimpleEmail
        SimpleEmail email = new SimpleEmail();
        email.setHostName('smtp.gmail.com");
email.addTo("mail@gmail.com", "John Doe");
email.setFrom("yourmail@gmail.com", "Me");
        email.setSubject("Test message");
        email.setMsg("This is a simple test of commons-email");
email.send();
Method 2: Using HtmlEmail without using MessageGateway
        HtmlEmail email = new HtmlEmail();
        email.setHostName("smtp.gmail.com");
        email.addTo("mail@domain.com", "John Doe");
        email.setFrom("yourmail@domain.com", "Me");
        email.setSubject("Test email with inline image");
        // set the html message //
        email.setHtmlMsg("<html>The apache logo - <img src=\"cid:"
        +cid+"\"></html>");
        // set the alternative message
        email.setTextMsg("Your email client does not support HTML messages");
        email.send();
Note: We can also read smtp details from the felix console configurations instead of passing smtp details directly.
Ref: http://www.blogger.com/blogger.g?blogID=8547815981944994348#editor/target=post;postID=3901523167605550399

Participant step is NOT shown in the workflow participant step dropdown list + AEM 5.6


Issue: Wrote a custom participant in AEM 5.6. When I go to workflow model/participant step, the custom participant is not listed in the participant chooser drop down list.
participant issue

Fix:  update API
Use com.adobe.granite.workflow.* instead com.day.cq.workflow.*

Workflows Issue with AEM5.6 + JAVA 1.7

 

Issue: Workflow Process implementation is not found.

Exception:

02.05.2013 11:25:23.305 *ERROR* [JobHandler: /etc/workflow/instances/2013-05-02/model_79635435153979:/content/test 1] com.adobe.granite.workflow.core.job.JobHandler Process implementation not found: com.test.workflowtest.Test com.adobe.granite.workflow.WorkflowException: Process implementation not found: com.test.workflowtest.Test

          at com.adobe.granite.workflow.core.job.HandlerBase.executeProcess(Handle rBase.java:221)

          at com.adobe.granite.workflow.core.job.JobHandler.process(JobHandler.jav a:139)

          at org.apache.sling.event.jobs.JobUtil$1.run(JobUtil.java:272)

          at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

          at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

          at java.lang.Thread.run(Unknown Source)

 

Fix:

Add -XX:-UseSplitVerifier option to the JVM

Example, if you’re starting AEM using start.bat, then you need to update JVM options in start.bat file.

::* default JVM options
if not defined CQ_JVM_OPTS set CQ_JVM_OPTS=-Xmx1024m -XX:MaxPermSize=256M -Djava.awt.headless=true -XX:-UseSplitVerifier

How to Convert a jar File into an OSGi Bundle?

Refer this link: http://dev.day.com/content/kb/home/cq5/Development/ApacheFelix/ConvertAJarIntoOsgiBundle.html

How to find out CURL command for any CQ operation?

  1. Use FireFox, open the FireBug
  2. Click on “Net” tab in FireBug, click “Enable”
  3. Perform CQ operation. For ex: Felix->JMX->com.adobe.granite.ldap->syncUser->enter user string. Ex: CN=Manoj Miryala,OU=ParkRidge,OU=User and Group Accounts,DC=us,DC=ad,DC=hertz,DC=com
  4. Click “invoke”
  5. In FireBug, you will see the whole request URL when you point the mouse on top of “POST java.lang.String” shown below. Copy that along with parameters from “Post” tab under it.
  6. clip_image002
  7. Post tab shows you the parameters that you need to pass to the CURL command.
  8. clip_image004
  9. Example curl command for JMX’s Syncuser operation is as follows

curl -d "user=CN=Manoj Miryala,OU=ParkRidge,OU=User and Group Accounts,DC=us,DC=ad,DC=hertz,DC=com" --user admin:admin http://hertz614:5402/system/console/jmx/com.adobe.granite.ldap%3Ahost%3DHertz00.US.AD.HERTZ.COM%2Cport%3D389%2Ctype%3DTools/op/syncUser/java.lang.String --trace-ascii debugdump.txt

Conclusion: The same procedure can be done to find out the exact URL for the request with parameters and then use CURL to perform the same operation. This is very useful to automate CQ operations.

GET and POST operations using CURL

  1. To create a property of a new node or modify the existing node, use the below,

curl -u admin:admin -F"text=modified Hello World" http://localhost:4502/content/sample

  1. To read a property of a node, use the below. Here /content/sample is the node and text is the property.

curl -u admin:admin -G http://localhost:4502/content/sample/text

How to use JMX console with AEM?

1. Change <crx-quickstart>/opt/helpers/instsrv.bat file with the following:

set jvm_mx=2048m( Default value is 1024)

set jvm_options=-Dcom.sun.management.jmxremote;-Dcom.sun.management.jmxremote.port=9010;-Dcom.sun.management.jmxremote.local.only=false;-Dcom.sun.management.jmxremote.authenticate=false;-Dcom.sun.management.jmxremote.ssl=false;-XX:MaxPermSize=256m;-Xdebug;-Xrunjdwp:transport=dt_socket,server=y,address=35402,suspend=n

2. Reinstall CQ windows service by running commands instsrv.bat -uninstall CQ55, instsrv.bat CQ55 and start CQ

3. Go to Command prompt, type “jconsole”. Select “Remote Process” radio button and enter “localhost:9010” and click “Connect”.

How to stop default Email Notifications?

1. Go to /system/console/configMgr

Eg: http://<hostname>:<port>/system/console/configMgr

2. Edit the configuration called 'Day CQ workflow Email Notification Service'

3. Disable 'Notify on Abort' and 'Notify on Complete' options.

DAM asset upload guidelines

Q:Is it good a have a folder/Asset name contains spaces.

Ans: It is not recommended to name folders/files with spaces in it. - and _ are the only special characters that are recommended.

Q:What is the max size limit of an Asset?

Ans: 10 to 30 MB size is recommended, but there is no limit to the size, in general.

Q: What is the maximum number of Assets that can be uploaded in a folder?

Ans: Adobe recommends not more than 200 to 250 at one level. The more the number of assets, the slower that AEM/DAM UI will load.

Note: Following approach is recommended when we have too many ( i.e., >250) Assets in a single dam folder:

1. Categorized the assets if possible lets say based upon your business areas or anything similar. Based on that create your high level of folders in DAM.

2. Now under all these folders create sub folders hierarchy like a, aa, ab ac... and b, ba, bb, bc ... and c, ca, cb, cc and after some level of depth store your assets which makes each folder to have assets in between 100-200.

Example:

DAM Structure.png

Q:What is the recommendation for DAM structure

A: Here is a typical structure of DAM assets <WEBSITE>

Ex: <POS> or <DIALECT> or <COUNTRY/LANGUAGE>

Ex: enUS
         <SECTION> EX: specialoffers
             <Subsections> Ex: banners, logos, misc etc.,

Don’t like new AEM 5.6 Touch based UI?

There is a way to set your own GUI(old or new). Follow this link and configure “Day Root Mapping” in Felix as explained here

Setting up WEBDAV on Windows vista,7 clients

WebDav can be configured on Windows vista and 7 operating systems, but there is a registry change that is required. Personally, I don’t feel comfortable changing any thing in the Windows registry. To avoid that, I usually use some of the open source tools such as “BitKinex” or “NetDrive”.

  1. How to configure WEBDAV on Windows vista, 7 or any other, follow this link.
  2. NetDrive can be downloaded here
  3. image
  4. BitKinex can be downloaded here. Follow the below steps to access AEM/CRX.
    • Configure your AEM instance's connection parameters by using "File->Quick Connect". URL: http://localhost:7402/crx/repository/crx.default
    • Go to "Datasource->Properties->Server->SiteMap", select Directory(WebDAV-complaint) from the dropdown "The Location Specifics" and click "OK"
    • It would show the CRX folders/files