Profile based Deployment using Maven In AEM (CQ5)

This presume Maven skeleton has been already created.

  • UI
  • Bundle
  • root pom.xml files.

Update/create  this entries specific to your environment in root pom.xml

Step 1.

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!– Development/Integration Server properties –>
<!– Author –>
<cq.devint.author.host>10.29.136.192</cq.devint.author.host>
<cq.devint.author.port>4502</cq.devint.author.port>
<cq.devint.author.username>admin</cq.devint.author.username>
<cq.devint.author.password>admin</cq.devint.author.password>
<!– Publish –>
<cq.devint.publish.host>10.29.136.194</cq.devint.publish.host>
<cq.devint.publish.port>4503</cq.devint.publish.port>
<cq.devint.publish.username>admin</cq.devint.publish.username>
<cq.devint.publish.password>admin</cq.devint.publish.password>
</properties>

Step2 .

Create below profile entry in same pom.xml or where ever you want.

<profile>
<id>dev-int</id>
<build>
<plugins>
<plugin>
<groupId>com.day.jcr.vault</groupId>
<artifactId>maven-vault-plugin</artifactId>
<configuration>
<failOnError>true</failOnError>
</configuration>
<executions>
<execution>
<id>install-package-author</id>
<goals>
<goal>install</goal>
</goals>
<configuration>
<packageFile>${project.build.directory}/${project.build.finalName}.zip</packageFile>
<targetURL>http://${cq.devint.author.host}:${cq.devint.author.port}/crx/packmgr/service.jsp</targetURL>
<userId>${cq.devint.author.username}</userId>
<password>${cq.devint.author.password}</password>
</configuration>
</execution>
<execution>
<id>install-package-publish</id>
<goals>
<goal>install</goal>
</goals>
<configuration>
<packageFile>${project.build.directory}/${project.build.finalName}.zip</packageFile>
<targetURL>http://${cq.devint.publish.host}:${cq.devint.publish.port}/crx/packmgr/service.jsp</targetURL>
<userId>${cq.devint.publish.username}</userId>
<password>${cq.devint.publish.password}</password>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

and finally run this command from command line or any CI Server profile.

mvn clean install -P dev-int

Advertisement

AEM 5.6.1 with Dispacther on IIS 7 Content not displayed

I came across a very unique problem today during one of my production deployment.

IIS with dispatcher on Windows Server and AEM 5.6.1

All Set up and networks good, however when hitting some CQ5 page on web server URL, not showing correct content/synced up content.

  1. Dispatcher.any, Logs, publish agent , Flush agent, accessed  URL directly on browser.
  2. then finally realized DefaultAppPool setting is needed to be increased for this problem to be resolved and it worked.

Reverse Replication AEM/CQ5 Pros and Cons [User Generated, User Profiles and as restful Service]

All Commercial products offers solution as larger aspect of enterprise that’s where it is critical for  Architect/solution developer to understand the nitty gritty of out of box module in relation with business requirement. You would fins many helpful posting regarding reverse replication .

http://helpx.adobe.com/experience-manager/kb/HowToUseReverseReplication.html
http://www.cqtutorial.com/courses/cq-admin/cq-admin-lessons/configure-cq-replication/cq-reverse-replication
http://docs.adobe.com/docs/en/cq/current/deploying/replication.html#Replicating%20from%20Publish%20to%20Author
This is one of the most comprehensive one http://www.wemblog.com/2011/10/how-to-set-up-usergroupprofile-reverse.html

You need to ask a question why you need Reverse Replication , Please verify your requirements on this?

1. User profiles needed to be reverse replicated because has some user preference data, Does that moderation needed on author side?
2. Is it anonymous data ?
3. How many Publish you have in your setup? is it Non-Cluster setup or clustered setup amongst publish?
4. what’s volume of content in typical working hours (>10000 or <10000).

Let us come on Solution now

Solution 1.

If your publish is non-cluster and you think user generated node might go more than 10000 in a days, hold your hand and this is going to cause trouble for you, you need to use restful Service and store user generated data on one location. You can have separate Solr Data repository or have one additional publish  server and use that only for user data repository + service. Don’t go on reverse replication path out of box of AEM/CQ5.

Solution 2.

If Publish are clustered , Even more than 10000 user generated data would not be a issue.

Reverse replication can be implemented in couple of way

1. Enable outbox on publish
2.Enable Reverse replication agent on Author to poll user generated content so that it could retrieve data.
3. Create or use out of box activate workflow through Workflow Launcher as soon as new content is available on auhtor to push it across other publish in network

 

 

 

 

 

 

 

 

 

 

AEM/CQ5 On/Off Time vs Activate Later On Content and Understanding

Activate later and On-Off Time of Content are two different behavior in CQ5/AEM 6. When you apply activate later on any content , that content gets activated at given time and exist in publish instance until it is deactivated or deleted.
On-Off time is little different . It adds additional attribute as properties to the content but it does not activate content. To make it available on publish, it has to be activated. The On and Off Time gets applied on publish site. When Off time matches or greater than current time , CQ5 OSGI Services consider that content as dead and if you try to access using HTTP, CQ5 would return 404 error.

However that content resides in JCR opposite to deactivate feature that deletes content from Publish JCR.That’s the catch and generally Developer thinks  that off time would make content disappear but that’s not the fact.

Off time related content can be checked in CQ5 Component like this.

<% currentPage.isValid()%> or You can use ResourceUtil Class that will return false because Off time has been applied and even that exist in Publish JCR would be considered as dead content.

Replication

CQ5 Query Builder API, Debugging and troubleshooting

Helpful for CQ5 developers who want to know How Felix works in terms of saving Configuration, OSGI Properties, How query  builder API works, Production vs Lower environment etc.

http://help-forums.adobe.com/content/adobeforums/en/experience-manager-forum/adobe-experience-manager.topic.forum__gigg-there_is_osgijavac__urlm-damapth_propertywas._s_1_tosp.html/forum__gigg-there_is_osgijavac.html#forum__gigg-there_is_osgijavac__urlm-damapth_propertywas

ConfigurationAdmin Through OSGI Component Service

One of the fundamental requirement to create a OSGi service to read OSGI config to read  configurable properties .

1. Create Osgi Config Node under your apps  and read that through Service like this

2. Sample OSGI Component reads default com.day.cq.mailer.DefaultMailService PID.

package com.abc.ch.service;
import java.io.IOException;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
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(immediate=true)
@Service(AbcOsgiConfigService.class)
public class AbcOsgiConfigService {
    
    private final Logger LOGGER = LoggerFactory
            .getLogger(AbcOsgiConfigService.class);
    
    @Reference
    ConfigurationAdmin configurationAdmin;
    
    public void activate(ComponentContext ctx){
        LOGGER.info(” activating “);
        BundleContext bundleCtx=ctx.getBundleContext();
        ServiceReference ref = bundleCtx.getServiceReference(ConfigurationAdmin.class.getName());
        
        if (ref != null) {
            configurationAdmin = (ConfigurationAdmin) bundleCtx.getService(ref);
            Configuration config;
            try {
              config = configurationAdmin.getConfiguration(“com.day.cq.mailer.DefaultMailService”);
              LOGGER.info(” Got the Config”+config.getProperties().get(“smtp.host”).toString());
            } catch (IOException e) {
                LOGGER.error(“Error trying to look up datasource configuration”, e);
            }
          }       
    }   
}

 

Spring WS WebServiceTransportException: Not Found [404]

The main reason for that error to be thrown is endpoint is not correct when your Web Service client is making a call to service based on SOAP.

Error log.
———————————————————–

org.springframework.ws.client.WebServiceTransportException:NotFound[404]
    at org.springframework.ws.client.core.WebServiceTemplate.handleError(WebServiceTemplate.java:626)
    at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:550)
    at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:501)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:350)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:344)
    at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:336)

How to fix it.

1. if you are making a call from java class and passing Default Web Service URI  of End Point , please check URL that’s incorrect that’s why you get 404 error.

2. if you passing from application context.xml. correct there.

Code snippet.

JAVA

final SoapActionCallback soapActionCallback = new SoapActionCallback(“http://ws.cdyne.com/WeatherWS/GetCityForecastByZIP&#8221;);

XML:
<beans:bean id=”weatherServiceTemplate” class=”org.springframework.ws.client.core.WebServiceTemplate”>
        <beans:constructor-arg ref=”messageFactory” />
        <beans:property name=”marshaller” ref=”weatherServiceMarshaller”></beans:property>
        <beans:property name=”unmarshaller” ref=”weatherServiceMarshaller”></beans:property>        
        <beans:property name=”defaultUri” value=”http://wsf.cdyne.com/WeatherWS/Weather.asmx&#8221; />
    </beans:bean>

 

 

 

   

 

 

AEM/CQ5 e-Commerce and Hybris get Started

It took couple of week for me to get started Adobe CQ5 and Hybris together on my local desktop since Adobe Wiki is very useful but i think has not been updated for some time. Hybris is eCommerce platform now by SAP and to get the license is not easy either you have to be customer or partner. Thanks to Adobe they have created OSGI Package of Hybris server and shared in package share and also Geomtrixx outdoor eCommerce related product content.

Day wiki http://dev.day.com/docs/en/cq/current/ecommerce/eCommerce-hybris.html is usefull but need to be updated with new information.

This is really cool if you want to start up AEM eCommerce Integration framework.
https://seminars.adobeconnect.com/_a227210/p85ixyvw3zp/?launcher=false&fcsContent=true&pbMode=normal

Brief synopsis to get started.

If you have CQ5 running instance  i.e 5.6.1, please create a Adobe CQ share package credentials and login into that and download    Hybris 500 MB+ package that has inbuilt Hybris server and also hybris content that has hybris importer and certain content.

Install both packages in your local package manager and can access hybris  console on this http://localhost:9001/hmc/hybris.and your CQ on 4502.

Image

By default outdoor catalog would be available in hybris, you can manually synchronize that content from here http://localhost:4502/etc/importers/hybris.html that will recreate product catalog here /etc/commerce/products. Remember untill you are not customer or Partner with Hybriss you would not get any resource or document about Hybris for functional knowledge.

Generate MVN Project

mvn -Padobe-public archetype:generate     -DarchetypeRepository=http://repo.adobe.com/nexus/content/groups/public/     -DarchetypeGroupId=com.day.jcr.vault     -DarchetypeArtifactId=multimodule-content-package-archetype     -DarchetypeVersion=1.0.2

Provide all other information i.e artifict id, name, group and folders and say yes in the last and finally your maven structure would be created.

Import Project in Eclipse

Download code from github https://github.com/paolomoz/cq-commerce-impl-sample in this case you don’t need to create archetype and maven project creation etc. build and deploy it to your local CQ.  Changed ecommorce provide in JCR for Geomtrexx_outdoor and your code would work..

 

 

JCR Content Model Some Key Rule

Data Store

The data store holds large binaries. On write, these are streamed directly to the data store and only an identifier referencing the binary is written to the Persistence Manager (PM) store. By providing this level of indirection, the data store ensures that large binaries are only stored once, even is they appear in multiple locations  within the content in the PM store. In effect the data store is an implementation detail of the PM store. Like the PM, the data store can be configured to store its data in a file system (the default) or in a database. The minimum object length default is 100 bytes;; smaller objects are stored inline(not in the data store). The maximum value is 32000 because Java does not support strings longer than 64 KB in writeUTF.

Cluster Journal

Whenever CRX writes data it first records the intended change in the journal. Maintaining the journal helps ensure data consistency and helps the system to recover quickly from crashes. As with the PM and data stores, the journal can be stored in a file system (the default) or in a database.

Persistence Manager
Each workspace in the repository can be separately configured to store its data through a specific persistence manager (the class that manages the reading and writing of the data). Similarly, the repository-wide version store can also be
independently configured to use a particular persistence manager. A number of different persistence managers are available, capable of storing data in a variety of file formats or relational databases.

Query Index

CRX’s inverse index is based on Apache Lucene. This allows for:

Most index updates are synchronous. Long full text extraction tasks are handled in background. Other cluster nodes will update their indexes at next cluster sync Everything indexed by default. You can tweak the indexing configuration for improvements in indexing functionality, performance and disk usage. There is one index per workspace (and one for the shared version store) Indexes are not shared across a cluster, indexes are local to each cluster node.

Jackrabbit
The Apache Jackrabbit™ content repository is a fully conforming implementation of the Content Repository for Java Technology API (JCR, specified in JSR 170 and JSR 283. Note the next release of the JCR specification is JSR 333, which is currently under work.