Friday, June 26, 2015

Performance Tuning: Hybris eCommerce Platform

Performance Tuning: Hybris eCommerce Platform



Thursday, June 25, 2015

Install Adobe Experience Manager(AEM) package through CURL command

Install Adobe Experience Manager(AEM) package through CURL command

curl -u <<User Name>>:<<Password>> -F file=@"<<Package Path>>" -F name="<<Package Name>>" -F force=true -F install=true http://<<Server Host Name>>:<<Port>>/crx/packmgr/service.jsp

e.g

curl -u admin:admin -F file=@"/appserver/package/package-1.0.1-SNAPSHOT.zip" -F name="package-1.0.1-SNAPSHOT" -F force=true -F install=true http://localhost:4502/crx/packmgr/service.jsp


If the Adobe Experience Manager(AEM) server is behind the proxy then execute the below command to set the proxy server

export http_proxy=http://<<Proxy Server Host Name>>:<<Port>>


Wednesday, June 17, 2015

Deploying bundles/packages to different environments through Maven: Adobe AEM/Adobe CQ5

Deploying bundles/packages to different environments through Maven: Adobe AEM/Adobe CQ5

Create a folder cq-sample-all(projectname-all) under cq-sample(parent folder)
Create cq-sample-all/pom.xml and configure the environment specific properties, module dependencies and different profiles - refer the sample below

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLotrion="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>
<parent>
             <groupId>my-group-id</groupId> <!-- Change the groupid and artifactId of the paraent -->
             <artifactId>cq-sample</artifactId>
             <version>1.0-SNAPSHOT</version>
        </parent>

<artifactId>cq-sample-all</artifactId> <!-- Change the artifcatId -->
<packaging>content-package</packaging>
<name>${project.groupId} - ${project.artifactId}</name>

<properties>
<cq.dev.author.server>aem-dev-author</cq.dev.author.server>
<cq.dev.author.host>localhost</cq.dev.author.host>
<cq.dev.author.port>4502</cq.dev.author.port>
<cq.dev.author.protocol>http</cq.dev.author.protocol>
<cq.dev.publisher1.server>aem-dev-publisher</cq.dev.publisher1.server>
<cq.dev.publisher1.host>localhost</cq.dev.publisher1.host>
<cq.dev.publisher1.port>4503</cq.dev.publisher1.port>
<cq.dev.publisher1.protocol>http</cq.dev.publisher1.protocol>
<!-- Add the other server details-->
</properties>
<!-- Add all the  bundle/content modules as part of dependency. Change the artifactId of the modules-->

<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>cq-sample-content</artifactId>
<version>${project.version}</version>
<type>content-package</type>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>cq-sample-bundle</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>com.day.jcr.vault</groupId>
<artifactId>maven-vault-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>package</goal>
</goals>
<configuration>
<embeddedTarget>/apps/cq-sample/install</embeddedTarget> <!-- change the folder name(cq-sample) accordingly -->
<embeddeds>
<embedded>
<groupId>${project.groupId}</groupId>
<artifactId>cq-sample-bundle</artifactId>
<filter>true</filter>
</embedded>
<!-- Add additional bundle modules here as embedded -->
</embeddeds>
<subPackages>
<subPackage>
<groupId>${project.groupId}</groupId>
<artifactId>cq-sample-content</artifactId>
<filter>true</filter>
</subPackage>
<!-- Add additional content modules here as subPackage -->
</subPackages>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

<profiles>
<!-- Profile for Development deployments -->
<!--Create the profile for different environments -->
<profile>
<id>Development</id>
<build>
<plugins>
<plugin>
<groupId>com.day.jcr.vault</groupId>
<artifactId>content-package-maven-plugin</artifactId>
<executions>
<execution>
<id>install-content-package-author</id>
<phase>install</phase>
<goals>
<goal>install</goal>
</goals>
<configuration>
<failOnError>true</failOnError>
<useProxy>false</useProxy>
<packageFile>${project.build.directory}/${project.build.finalName}.zip</packageFile>
<targetURL>${cq.dev.author.protocol}://${cq.dev.author.host}:${cq.dev.author.port}/crx/packmgr/service.jsp</targetURL>
<serverId>${cq.dev.author.server}</serverId>
</configuration>
</execution>
<execution>
<id>install-content-package-publisher1</id>
<phase>install</phase>
<goals>
<goal>install</goal>
</goals>
<configuration>
<failOnError>true</failOnError>
<useProxy>false</useProxy>
<packageFile>${project.build.directory}/${project.build.finalName}.zip</packageFile>
<targetURL>${cq.dev.publisher1.protocol}://${cq.dev.publisher1.host}:${cq.dev.publisher1.port}/crx/packmgr/service.jsp</targetURL>
<serverId>${cq.dev.publisher1.server}</serverId>
</configuration>
</execution>
<!-- Add execution for additional publisher with different id(increment the last digit)-->
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>




How to disable Geolocation feature : Adobe AEM/Adobe CQ5

How to disable Geolocation feature : Adobe AEM/Adobe CQ5

The Geolocation feature can be disabled for all the sites by renaming the following component to different name

Rename /libs/cq/personalization/components/contextstores/geolocation to /libs/cq/personalization/components/contextstores/geolocation_new




Unresolveable build extension: Error resolving version for plugin 'com.day.jcr.vault:maven-vault-plugin' / Unknown packaging: content-package while deploying through Maven : Adobe AEM/Adobe CQ5

Unresolveable build extension: Error resolving version for plugin 'com.day.jcr.vault:maven-vault-plugin' / Unknown packaging: content-package while deploying through Maven : Adobe AEM/Adobe CQ5

We are getting the below exception while deploying the package to Adobe AEM/Adobe CQ5 through Maven.

[ERROR] Unresolveable build extension: Error resolving version for plugin 'com.day.jcr.vault:maven-vault-plugin' from the repositories
[local (D:\Albin\Projects\.m2\repository), adobe (http://repo.adobe.com/nexus/content/groups/public/),
central (http://repo.maven.apache.org/maven2)]: Plugin not found in any plugin repository -> [Help 2]
[ERROR]     Unknown packaging: content-package @ my-group-id:cq-sample-all:[unknown-version],
D:\Albin\SW\apache-maven-3.2.2-bin\apache-maven-3.2.2\bin\cq-sample\cq-sample-all\pom.xml, line 13, column 13
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
[ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/PluginVersionResolutionException

To resolve this issue add the vault plugin to parent pom.xml

<plugin>
<groupId>com.day.jcr.vault</groupId>
<artifactId>maven-vault-plugin</artifactId>
<version>0.0.10</version>
<configuration>
<verbose>true</verbose>
</configuration>
</plugin>


Friday, June 5, 2015

Enabling basic authentication for specific website in dispatcher : Adobe CQ5/Adobe AEM

Enabling basic authentication for specific website in dispatcher : Adobe CQ5/Adobe AEM

Create a file dispatcher.htaccess in dispatcher.
Create the required users by using the following commands.

htpasswd -c /etc/httpd/conf/dispatcher.htaccess user1

Add the following configurations to the httpd.conf, change the site URL and AuthUserFile accordingly:

# unsets authorization header when sending request to AEM
RequestHeader unset Authorization
SetEnvIf Request_URI ^/content/en* auth=1
AuthName "Please login to access english part"
AuthType Basic
AuthUserFile /etc/httpd/conf/dispatcher.htaccess
# first, allow everybody
Order Allow,Deny
Satisfy any
Allow from all
Require valid-user
# then, deny only if required
Deny from env=auth

This will enable the the basic authentication for the website path starts with /content/en

If the site is enabled for https then add the following content to the ssl.conf file

<Location />
# unsets authorization header when sending request to AEM
RequestHeader unset Authorization
SetEnvIf Request_URI ^/content/en* auths=1
AuthName "Please login to access english part"
AuthType Basic
AuthUserFile /etc/httpd/conf/dispatcher.htaccess
# first, allow everybody
Order Allow,Deny
Satisfy any
Allow from all
Require valid-user
# then, deny only if required
Deny from env=auths
</Location>


Monday, June 1, 2015

Performance Tuning: Adobe CQ5/Adobe AEM

Performance Tuning: Adobe CQ5/Adobe AEM



Saturday, May 23, 2015

How to get all the configurations from a configurationFactory - Adobe CQ5/Adobe AEM

How to get all the configurations from a configurationFactory - Adobe CQ5/Adobe AEM

@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY, policy = ReferencePolicy.STATIC)
private ConfigurationAdmin configAdmin;
try {
Configuration[] confArray = configAdmin.listConfigurations("(service.factoryPid= com.service.config.impl.ConfigFactoryServiceImpl)");

//Retrieve the configurations - Iterate through confArray
final Configuration conf = confArray[0];
final String property1 = (String) conf.getProperties().get("property1");

} catch (Exception e) {

}

service.factoryPid:





Adobe CQ/Adobe AEM: Configuration Services for Multiple Sites through configurationFactory

Adobe CQ/Adobe AEM: Configuration Services for Multiple Sites through configurationFactory

Sometimes, we have to define configuration services that will differ only with configuration values. For e.g we will have different sites that will use the same configuration service but with different configuration values specific to sites.

In this scenario, we have to create a site specific configuration service for all the sites (multiple services) but OSGI provides the concept of ServiceFactories, the service factory can be used to create configuration services with same set of properties and different values.

As an example let’s assume, we have two different sites that will use the same configuration service but require site specific configuration values. The configurationFactory can be used to create configuration service for different sites.

configurationFactory to create site specific cconfigurations and to retrieve the site specific configuration properties.

import java.util.Dictionary;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.ConfigurationPolicy;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.service.cm.Configuration;
import org.osgi.service.cm.ConfigurationAdmin;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(configurationFactory = true, policy = ConfigurationPolicy.REQUIRE, immediate = true, label = "Config Factory Service", description = "Global configuration Factory Service", metatype = true)
@Properties({ @Property(name = Constants.SERVICE_DESCRIPTION, value = "Common Configuration Factory Service") })
@Service(value = ConfigFactoryServiceImpl.class)
public class ConfigFactoryServiceImpl{

private static final Logger LOG = LoggerFactory.getLogger(ConfigFactoryServiceImpl.class);

private static ResourceResolverFactory resourceResolverFactory;
private static BundleContext bundleContext;

@Reference
private ResourceResolverFactory resourceResolverFactoryInit;

private static final String SERVICE_PID = "service.pid";

private static final String DEFAULT_CONFIG = "DEFAULT";

private static Map<String, String> svcPIDMap = new HashMap<String, String>();

@Property(label = "Site Root Path", value = "DEFAULT", description = "Root path for site (e.g. - /content/sample).")
public static final String SITE_ROOT_PATH = "siteRootPath";

@Property(label = "Property1", value = "Property1: ", description = "Property1.")
public static final String PROPERTY1 = "PROPERTY1";

@Property(label = "Property2", value = "Property2: ", description = "Property2.")
public static final String PROPERTY2 = "PROPERTY2";

@Property(label = "Property3", value = "Property3: ", description = "Property3.")
public static final String PROPERTY3 = "PROPERTY3";

protected String getSiteRootPath() {
return SITE_ROOT_PATH;
}

protected void activate(ComponentContext context) {
try {
bundleContext = context.getBundleContext();
resourceResolverFactory = resourceResolverFactoryInit;
// Get the current config
Dictionary<?, ?> props = context.getProperties();
// Save the service.pid to static map
String servicePID = (String) props.get(SERVICE_PID);
setServicePID(props, servicePID);
} catch (Exception e) {

}
}

private void setServicePID(Dictionary<?, ?> props, String servicePID) {
String siteRootPath = (String) props.get(getSiteRootPath());
if(!siteRootPath.equals("DEFAULT") && !siteRootPath.startsWith("/"))
{
siteRootPath="/"+siteRootPath;
}
if (!StringUtils.isEmpty(siteRootPath)) {
svcPIDMap.put(siteRootPath, servicePID);
}
}

public static String getConfig(HttpServletRequest request, String key) {
return getConfig(request, null, key);
}

public static String getConfig(HttpServletRequest request, String uri,String key) {
String property = null;
Object configObj = null;
try {
configObj = getConfigObj(request, uri, key);
} catch (Exception e) {

}
if (null != configObj) {
property = configObj.toString();
}
return property;
}

public static Object getConfigObj(HttpServletRequest request,String pagePath, String key) {
Configuration conf;
String resourcePath = null;
try {
if (!("DEFAULT").equals(pagePath)) {
resourcePath = getResourcePath(request, pagePath);
conf = locateConfiguration(resourcePath);
} else {
conf = locateConfiguration(DEFAULT_CONFIG);
}

if (null != conf && null != conf.getProperties()) {
Object obj = conf.getProperties().get(key);
return obj;
} else {
throw new Exception("Could not find matching configuration");
}
} catch (Exception e) {

}
return null;
}

private static Configuration locateConfiguration(String resourcePath) {
Configuration locatedConfig = null;
try {
String siteRootPath = getSiteRootPath(resourcePath);
String svcPID = svcPIDMap.get(siteRootPath);
ConfigurationAdmin bundleConfigAdmin = (ConfigurationAdmin) bundleContext.
getService(bundleContext.getServiceReference(ConfigurationAdmin.class.getName()));
locatedConfig = bundleConfigAdmin.getConfiguration(svcPID);
} catch (Exception e) {

}
return locatedConfig;
}

protected static String getResourcePath(HttpServletRequest request,String pagePath) {
String resourcePath = null;
String uri = request.getRequestURI();
ResourceResolver resourceResolver = null;
try {
resourceResolver = resourceResolverFactory.getResourceResolver(null);
Resource resolvedResource;
if (null == pagePath) {
resolvedResource = resourceResolver.resolve(request, uri);
} else {
resolvedResource = resourceResolver.resolve(request, pagePath);
}
resourcePath = resolvedResource.getPath();
} catch (Exception e) {

} finally {
if (null != resourceResolver) {
resourceResolver.close();
}
}

return resourcePath;
}

protected static String getSiteRootPath(String resourcePath) {
if (StringUtils.isEmpty(resourcePath)) {
return null;
}

if (resourcePath.equalsIgnoreCase(DEFAULT_CONFIG)) {
return resourcePath;
}

String siteRootPath = null;
String[] path = resourcePath.split("/");
if (path.length > 2) {
siteRootPath = "/" + path[1] + "/" + path[2];
LOG.error("siteRootPath= "+siteRootPath);
}

return siteRootPath;
}
}



Friday, May 22, 2015

how to Delete/Disable the users through Java API in Adobe Experience Manager(AEM)

how to Delete/Disable the users through Java API in Adobe Experience Manager(AEM)

This post will explain how to Delete/Disable the users through Java API in Adobe Experience Manager(AEM).

 @Reference
 ResourceResolverFactory resolverFactory;

 ResourceResolver adminResolver = null;
 Session adminSession=null;

 try {  
adminResolver = resolverFactory.getAdministrativeResourceResolver(null);
        adminSession = adminResolver.adaptTo(Session.class);
        final UserManager userManager= adminResolver.adaptTo(UserManager.class);
             
      Authorizable authorizable = userManager.getAuthorizable("userName");
      if (authorizable instanceof User) {
         User user = (User)authorizable;
         user.remove(); //Remove the user

        user.disable() // Disable the user.
    }
                       
 } catch (Exception e) {
e.printStackTrace();
 } finally {
        if (adminResolver != null) adminResolver.close();              
 }


Thursday, May 7, 2015

Enabling Multi Site supports in Adobe Experience Manager(AEM) through Dispatcher and publisher configurations

Enabling Multi Site supports in Adobe Experience Manager(AEM) through Dispatcher and publisher configurations



Invalidate dispatcher cache after successfull jenkins build - AEM/Adobe CQ5

Invalidate dispatcher cache after successful Jenkins build - AEM/Adobe CQ5

This post will explain how to invalidate the cache in Adobe Experience Manager after successful Jenkins build.

Login to Jenkins console
Open the job and click on configuration
Add post-build step of type  “Execute Shell” and select “Run only if build succeeds”


Enter the below script and click on  - Change the dispatcher host name accordingly.

/usr/bin/curl -H "CQ-Action: DELETE" -H "CQ-Handle:/" -H "Content-Length: 0" -H "Content-Type: application/octet-stream" --noproxy .com http://<<dispatcher host name>>/dispatcher/invalidate.cache


If multiple dispatcher are configured then configure the dispatchers as shown below in the script.

/usr/bin/curl -H "CQ-Action: DELETE" -H "CQ-Handle:/" -H "Content-Length: 0" -H "Content-Type: application/octet-stream" --noproxy .com http://{dispatcher1, dispatcher2, dispatcher3, dispatcher4}.com/dispatcher/invalidate.cache


Thursday, April 30, 2015

Dispatcher caching issue while displaying the image renditions in Adobe Experience Manager(AEM)

We are using the image renditions to display the images for different devices in Adobe Experience Manager(AEM).

The HTML5 Adaptive image is used as shown below to display the images for different devices.

<img src="/content/dam/Albin/Untitled.jpg" srcset="/content/dam/Albin/Untitled.jpg/jcr:content/renditions/cq5dam.thumbnail.319.319.png 1x,/content/dam/Albin/Untitled.jpg" alt="Sample Image">

/content/dam/Albin/Untitled.jpg - Original image
/content/dam/Albin/Untitled.jpg/jcr:content/renditions/cq5dam.thumbnail.319.319.png - Rendition for 1x devices.

If the image is first accessed from the mobile devices then Untitled.jpg folder is created to cache the renditions image(rendition images will be matched for mobile devices) - /content/dam/Albin/Untitled.jpg/jcr:content/renditions/cq5dam.thumbnail.319.319.png

While the image is getting accessed from desktop browsers then dispatcher will try to return the folder Untitled.jpg as image(/content/dam/Albin/Untitled.jpg - original image will be matched for desktop browsers) so the image link will be broken in browser.

In other hand, if the image is first accessed from desktop browser then dispatcher caches Untitled.jpg as image. The subsequent request to the renditions image will not find the images in dispatcher cache so the image will be retrieved from publisher for rendering(rendition images will not be cached in this scenario as untitled.jpg is created as a image).

 Refer the following post To resolve the issue

https://www.albinsblog.com/2015/04/how-to-use-html5-adaptive-image-in-AdobeCQ5.html



Monday, April 27, 2015

Different approaches to define vanity URL in Adobe Experience Manager(AEM)

Different approaches to define vanity URL in Adobe Experience Manager(AEM)



Sunday, April 19, 2015

How to send the HTML email using Velocity template in AEM/Adobe CQ5

How to send the HTML email using Velocity template in Adobe CQ5

This post will explain the steps required to send HTML email in Adobe CQ5 using Velocity template.

Configure mail service:

Go to the Felix Console - http://localhost:4502/system/console/configMgr
Search for Day CQ Mail Service
Enter the email server details as shown below and Save the data (Here I am using Gmail server details).


Email Template:

Create the email template as html file and store it in repository - /etc/email/template/emailTemplate.html (change the path accordingly)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <body>
       Hi ${firstName} ${lastName}</br>
       This is the sample mail.
       <ul>
  #foreach( $data in $dataList )
    <li>$data</li>
  #end
       </ul>
    </body>
</html>

Maven dependencies to the POM.xml:

<dependency>
  <groupId>com.day.cq</groupId>
  <artifactId>cq-mailer</artifactId>
  <version>5.4.0</version>
  <scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.6.2</version>
</dependency>

Import-Package configuration in POM.xml bundle plugin:

        *,
org.apache.xerces.dom;resolution:=optional,org.apache.xerces.parsers;resolution:=optional,
oracle.xml.parser;resolution:=optional, oracle.xml.parser.v2;resolution:=optional,
org.jaxen;resolution:=optional, org.jaxen.jdom;resolution:=optional,
org.apache.xml.resolver;resolution:=optional,org.apache.xml.resolver.helpers;resolution:=optional,
org.apache.xml.resolver.tools;resolution:=optional,org.apache.tools.ant.launch;resolution:=optional,
org.apache.tools.ant.taskdefs.optional;resolution:=optional,org.apache.tools.ant.util.optional;resolution:=optional,
org.apache.avalon.framework.logger;resolution:=optional,sun.misc;resolution:=optional,
sun.rmi.rmic;resolution:=optional,sun.tools.javac;resolution:=optional,org.apache.bsf;resolution:=optional,
org.apache.env;resolution:=optional,org.apache.bcel.classfile;resolution:=optional,kaffe.rmi.rmic;resolution:=optional,
com.sun.jdmk.comm;resolution:=optional,com.sun.tools.javac;resolution:=optional,javax.jms;resolution:=optional,
antlr;resolution:=optional,antlr.collections.impl;resolution:=optional,org.jdom;resolution:=optional,
org.jdom.input;resolution:=optional,org.jdom.output;resolution:=optional,com.werken.xpath;resolution:=optional,
org.apache.tools.ant;resolution:=optional,org.apache.tools.ant.taskdefs;resolution:=optional,
org.apache.log;resolution:=optional,org.apache.log.format;resolution:=optional,org.apache.log.output.io;resolution:=optional,



Saturday, April 4, 2015

How to craete/manage the groups and users through Java API in AEM/Adobe CQ5?

How to create/manage the groups and users through Java API in AEM/Adobe CQ5?

This post will explain how to create/manage the groups and users through Java API in Adobe Experience Manager(AEM).

import java.io.IOException;
import java.security.Principal;

import javax.jcr.PropertyType;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.servlet.Servlet;

import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Service(value = Servlet.class)
@Component(immediate = true, metatype = true)
@Properties({
@Property(name = "sling.servlet.paths", value = "/services/manageGroupsAndUsers"),
@Property(name = "service.description", value = "ManageGroupsAndUsers"),
@Property(name = "label", value = "ManageGroupsAndUsers") })

public class ManageGroupsAndUsers extends SlingAllMethodsServlet{

/**
*
*/
private static final long serialVersionUID = 1L;

@Reference
ResourceResolverFactory resolverFactory;

private static Logger logger = LoggerFactory.getLogger(ModifyCartServlet.class);

protected final void doPost(final SlingHttpServletRequest request,
final SlingHttpServletResponse response) throws IOException {

String groupName="sampleGroup";
String userName="sampleUser";
String password="sampleUser";

ResourceResolver adminResolver = null;
Session adminSession=null;
try {
      adminResolver = resolverFactory.getAdministrativeResourceResolver(null);
      adminSession = adminResolver.adaptTo(Session.class);
      final UserManager userManager= adminResolver.adaptTo(UserManager.class);
         
     if(null==userManager.getAuthorizable(groupName)){
   
     Group group=userManager.createGroup(groupName,new SimplePrincipal(groupName),"/home/groups/test");
   
     Value value=adminSession.getValueFactory().createValue("Sample Group", PropertyType.STRING);
     group.setProperty("./profile/givenName", value);
   
     value=adminSession.getValueFactory().createValue("Test Group", PropertyType.STRING);
     group.setProperty("./profile/aboutMe", value);
   
     value=adminSession.getValueFactory().createValue("[email protected]", PropertyType.STRING);
     group.setProperty("./profile/email", value);    
         
      }else{
     response.getWriter().write("Group already exist..");
      }
   
     if(userManager.getAuthorizable(userName)==null){
     User user=userManager.createUser(userName, password,new SimplePrincipal(userName),"/home/users/test");
     Value value=adminSession.getValueFactory().createValue("Issac", PropertyType.STRING);
     user.setProperty("./profile/familyName", value);
   
     value=adminSession.getValueFactory().createValue("Albin", PropertyType.STRING);
     user.setProperty("./profile/givenName", value);
   
     value=adminSession.getValueFactory().createValue("Test User", PropertyType.STRING);
     user.setProperty("./profile/aboutMe", value);
   
     value=adminSession.getValueFactory().createValue("[email protected]", PropertyType.STRING);
     user.setProperty("./profile/email", value);    
   
      }else
      {
      response.getWriter().write("User already exist..");
      }
   
   
     Group group = (Group)(userManager.getAuthorizable(groupName));
     group.addMember(userManager.getAuthorizable(userName));
                     
} catch (Exception e) {
e.printStackTrace();
response.getWriter().write("Not able to perform User Management.."+resolverFactory);
} finally {
      if (adminResolver != null) adminResolver.close();
         
}

}

protected final void doGet(final SlingHttpServletRequest request,
final SlingHttpServletResponse response) throws IOException {
doPost(request, response);
}



Friday, April 3, 2015

How to create different renditions for the Image in AEM/Adobe CQ5?

How to create different renditions for the Image in AEM/Adobe CQ5?

While uploading the images to DAM,Adobe Experience Manager(AEM) will create renditions of an image that include different sizes of the same image.This can be helpful when we need to create thumbnails or smaller views of large, high-resolution images.



We can configure the DAM Update Asset workflow to create the different renditions.
  • Login to http://localhost:4502/etc/workflow/models/dam/update_asset.html
  • In the workflow model select the thumbnail creation step and edit, in the process tab of the step we can add custom rendition values.
  • Save the workflow




How to use HTML5 adaptive image in AEM/Adobe CQ5?

How to use HTML5 adaptive image in AEM/Adobe CQ5?

This post will explain how to use HTML5 adaptive image in Adobe Experience Manager(AEM)

The srcset attribute in HTML5 <img> element, allows us to specify different images for varying viewport widths and pixel densities. This allows us to load a larger image for new high resolution devices while displaying lower resolution images for others

<img src="image-src.png" srcset="image-1x.png 1x, image-2x.png 2x,image-3x.png 3x, image-4x.png 4x">

The width also can be specified to select the images.

<img src="small.jpg" srcset="medium.jpg 1000w, large.jpg 2000w" alt="Sample Image">

While uploading the images to DAM, Adobe CQ5 will create renditions of an image that include different sizes of the same image.This can be helpful when we need to create thumbnails or smaller views of large, high-resolution images.


The original or different rendition images can be used in HTML5 Adaptive image to display the images based on pixel density of the device,  browser will serve the image based on the resolution of the client.

<img src="/content/dam/Albin/Untitled.jpg/jcr:content/renditions/original" srcset="/content/dam/Albin/Untitled.jpg/jcr:content/renditions/cq5dam.thumbnail.319.319.png 1x,/content/dam/Albin/Untitled.jpg/jcr:content/renditions/original" alt="Sample Image">


Saturday, March 28, 2015

NullPointerException: currentDesign.getDoctype(currentStyle).toRequest(request) - AEM/Adobe CQ5

NullPointerException:  currentDesign.getDoctype(currentStyle).toRequest(request) - AEM/Adobe CQ5

We were getting the NullpoiterException while accessing the pages in Adobe Experience Manager(AEM)

Caused by: java.lang.NullPointerException
at org.apache.jsp.apps.sample.design.components.pages.pageShell.pageShell_jsp._jspService(pageShell_jsp.java:227)
at org.apache.sling.scripting.jsp.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.apache.sling.scripting.jsp.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:502)
... 117 more

NullpointerException is thrown while getting the Doctype of the page design.

if (currentDesign != null) {
        currentDesign.getDoctype(currentStyle).toRequest(request);
    }

This issue was getting resolved after restarting the server.

After analysis the currentDesign  and currentStyle objects are not null and getDoctype method is throwing NullpoiterException.

The currentStyle  refers to the path (currentStyle.getPath())- /etc/designs/default.

By default /etc/designs/default/jcr:content path will not have cq:doctype property specified.

To resolve the issue we have added the  cq:doctype - html_5 property to /etc/designs/default/jcr:content

doctype_html5

If the property is already available then delete the same and add again.


Saturday, March 14, 2015

How to get the UserInfo through Java API in AEM/Adobe CQ5

How to get the UserInfo through Java API in AEM/Adobe CQ5

The below Java API helps to get the UserInfo details in Adobe Experience Manager(AEM)
@Reference
ResourceResolverFactory resolverFactory;

ResourceResolver adminResolver = null;
try {
       adminResolver = resolverFactory.getAdministrativeResourceResolver(null);
       final Session adminSession = adminResolver.adaptTo(Session.class);
       final UserManager userManager = adminResolver.adaptTo(UserManager.class);
       final User user = (User) userManager.getAuthorizable(adminSession.getUserID());
         
       logger.info("user.getID().."+user.getID());
       logger.info("user.isAdmin().."+user.isAdmin());
       logger.info("user.getPrincipal().getName().."+user.getPrincipal().getName());

       String lastName=user.getProperty("./profile/familyName")!=null?user.getProperty("./profile/familyName")[0].getString():null;
     String firstName=user.getProperty("./profile/givenName")!=null?user.getProperty("./profile/givenName")[0].getString():null;
     String aboutMe=user.getProperty("./profile/aboutMe")!=null?user.getProperty("./profile/aboutMe")[0].getString():null;
     String email=user.getProperty("./profile/email")!=null?user.getProperty("./profile/email")[0].getString():null;
   
     logger.info("lastName.."+lastName);
     logger.info("firstName.."+firstName);
     logger.info("aboutMe.."+aboutMe);
     logger.info("email.."+email);
         
       Iterator<Group> itr=user.memberOf();
       while(itr.hasNext())
       {
         Group group=(Group)itr.next();
          logger.info("group.getID().."+group.getID());
           logger.info("group.getPrincipal().getName().."+group.getPrincipal().getName());
        }        
                             
} catch (Exception e) {
        e.printStackTrace();
} finally {
       if (adminResolver != null) adminResolver.close();
}