Thursday, December 29, 2011

How to check if some one has replication rights for a path in CQ5 / WEM

You can use following code

import javax.jcr.security.AccessControlManager;
import javax.jcr.security.Privilege;
import com.day.cq.replication.Replicator;
import javax.jcr.Session;

public static boolean canReplicate(String path, Session session) throws RepositoryException {
AccessControlManager acMgr = session.getAccessControlManager();
return session.getAccessControlManager().hasPrivileges(path, new Privilege[] {acMgr.privilegeFromName(Replicator.REPLICATE_PRIVILEGE)});
}

In fact you can use this code to check any rights. Just replace privilege with any privilege in http://jackrabbit.apache.org/api/1.5/org/apache/jackrabbit/api/jsr283/security/Privilege.html

For example


privilegios[0] = acMgr.privilegeFromName(Privilege.JCR_READ);
privilegios[1] = acMgr.privilegeFromName(Privilege.JCR_ADD_CHILD_NODES);
privilegios[2] = acMgr.privilegeFromName(Privilege.JCR_REMOVE_CHILD_NODES);
.. More

Friday, December 23, 2011

How to rebuild index in CQ5 / WEM

Prerequisite: You have to stop your CQ instance (Except for AEM6 onward)

Also read

http://www.wemblog.com/2011/09/which-index-is-what-in-cqcrx.html

http://www.wemblog.com/2011/09/how-to-reindex-large-repository.html

For CQ5.2X or CQ5.3 or upgraded CQ5.4 remove or rename following files or folder

1) /crx-quickstart/repository/version/copy/index*.tar
2) /crx-quickstart/repository/workspaces/crx.default/copy/index*.tar
3) /crx-quickstart/repository/workspaces/crx.default/index
4) /crx-quickstart/repository/repository/index


In some cases you can also recreate indexes by deleting or renaming following folders and files (Some of the files and folder has nothing to do with index, they are just removed for cleaning purpose

1) /crx-quickstart/repository/shared/journal
2) /crx-quickstart/repository/workspace/crx.default/index
3) /crx-quickstart/repository/workspace/crx.default/copy
4) /crx-quickstart/repository/workspace/version/copy/index*
5) /crx-quickstart/repository/index
6) /crx-quickstart/repository/shared/journal/control
7) /crx-quickstart/repository/shared/version/control
8) /crx-quickstart/repository/shared/workspace/crx.default/control
9) /crx-quickstart/logs

For CQ5.4 / CRX2.2 / CQ5.5 / CRX2.3 remove or rename following files and folders

1) /crx-quickstart/repository/workspaces/crx.default/index
2) /crx-quickstart/repository/workspaces/crx.default/index*.tar
3) /crx-quickstart/repository/version/index*.tar
4) /crx-quickstart/repository/tarJournal/index*.tar
5) /crx-quickstart/repository/repository/index

For AEM6 onward (If you are using oak MK), Rebuilding indexes can happen while system is running (Note that query would not run faster if you do reindex)

Please read https://docs.adobe.com/docs/en/aem/6-0/deploy/upgrade/queries-and-indexing.html and https://docs.adobe.com/docs/en/aem/6-1/deploy/best-practices/best-practices-for-queries-and-indexing.html before doing re indexing.

I think best way to do reindexing in AEM6 is to use this tool http://adobe-consulting-services.github.io/acs-aem-commons/features/oak-index-manager.html

for doing full indexing of repo in AEM6 you can set reindex to true at oak:index node. More info is here http://jackrabbit.apache.org/oak/docs/query.html

If you don't have access to install this tool then you can manually go to crxde repo and set reindex property to true for property you want to reindex (This is expensive operation, don't do it if you don't know what you are doing).

In some cases you need to stop your system remove/rename repository/index folder and then start instance again



Note: In some cases if your repository size is huge, It could take days to rebuild Lucene index. So Before you rebuild your index, make sure that you can afford that much of downtime.

Wednesday, December 21, 2011

How to add a supported language to the CQ / WEM

1) You need to overlay/overwrite /libs/cq/security/widgets/source/widgets/security/Preferences.js to change the list of available languages (used in security admin)
and overlay /libs/cq/security/content/tools/userProperties (inside change language list under items/common/items/lang/options - similar dialog to Preferences.js) (used for user drop-down in the top right on admin consoles)

2) Then you need to add the new language somewhere in the repo, e.g. /apps/yourapp/i18n, following the layout as under /libs/wcm/core/i18n (see also the above section on the translator UI). Stuff under /libs must not be changed!

3) Here is a sample package:
cq-i18n-add-language-sample.zip

4) adds /apps/test/i18n with translation of "New..." in zh-cn ("simplified") and zh-tw ("traditional") languages
overlays /apps/cq/security/content/tools/userProperties and /apps/cq/security/widgets/source/widgets/security/Preferences.js to add the zh-tw language

5) to check, set the current user's language to "Traditional Chinese" and look in the siteadmin: the first button in the toolbar should now be "traditional" instead of "New..."

Thanks Alexander Klimetschek from Adobe for this information.

How to use multi language translation in JSP in CQ / WEM

Use Case: You want to display certain text in page based on page language

Prerequisite: http://sling.apache.org/site/internationalization-support-i18n.html

Solution: You can use i18n bundle approach for this

Suppose you want to display certain text for a component in different language based on page language or URL. Take an example of /apps/geometrixx/components/homepage component.

1) Create a i18n node under /apps/geometrixx/components/homepage of type sling:Folder
2) create a node of type sling:Folder under i18n of mixin type mix:language
3) Add a property called jcr:language and assign value of lang code or lang_COUNTRY

Structure would be like

/apps/myApp
+-- English (nt:folder, mix:language)
| +-- jcr:language = en
| +-- mx (sling:messageEntry)
| +-- sling:key = "msgXXX"
| +-- slign:message = "An Application Text"
+-- Deutsch (nt:folder, mix:language)
+-- jcr:language = de
+-- mx (sling:messageEntry)
+-- sling:key = "msgXXX"
+-- slign:message = "Ein Anwendungstext"



4) Then on jsp page use following code

<cq:setContentBundle/>
<%
Locale pageLocale = currentPage.getLanguage(false);
//If above bool is set to true. CQ looks in to page path rather than jcr:language property.
ResourceBundle resourceBundle = slingRequest.getResourceBundle(pageLocale);
I18n i18n = new I18n(resourceBundle);
%>
I am printing using I18n <%=i18n.get("updateLocations") %>
I am printing using fmt:message now <fmt:message key="updateLocations"/>
I found page locale is <%=pageLocale.toString() %>

You can also test language using grid under http://localhost:4502/libs/cq/i18n/translator.html
More Info: http://labs.sixdimensions.com/blog/dklco/2012-05-25/adobe-cq5-translator

To change what languages are shown in the translator's grid, create a multi-value string property /etc/languages/languages (node structure must be created), containing the iso language codes (e.g. ["de", "fr", …]). The default is hard coded in the translator and maps the ootb CQ languages: ['de', 'fr', 'it', 'es', 'ja', 'zh-cn']


Some More Good blog Post on this:

http://blogs.adobe.com/dekesmith/2012/10/21/internationalization-within-sling-and-cq



How to manage bundle using curl command

Get bundle Symbolic Name:

(You can use jsawk tool to parse this data as well https://github.com/micha/jsawk)

curl -u admin:admin http://localhost:4502/system/console/bundles</bundlenumber>.json

Start
curl -u admin:admin -F action=start http://localhost:4502/system/console/bundles/$bundle symbolic name

Stop
curl -u admin:admin -F action=stop http://localhost:4502/system/console/bundles/$bundle symbolic name

Update
curl -u admin:admin -F action=update http://localhost:4502/system/console/bundles/$bundle symbolic name

Refresh
curl -u admin:admin -F action=refresh http://localhost:4502/system/console/bundles/$bundle symbolic name

Unistall
curl -u admin:admin -F action=uninstall http://localhost:4502/system/console/bundles/$bundle symbolic name
Or
curl -XDELETE -u user:pass http://.../apps/${app}/install/${bundle-file-name}

Install
curl -X POST -v -F action=install -F bundlestart=start -F bundlestartlevel=20 -F bundlefile=/path/to/jar/file.jar http://admin:admin@localhost:4502/system/console/bundles
OR
curl -u admin:admin -F action=install -F bundlestartlevel=20 -F bundlefile=@"/path/of/jar" http://localhost:9002/system/console/bundles


Here is some example with jswak (Here is how you can install jswak on MAC)
How to check if a CQ bundle is Active

curl -u admin:admin http://localhost:4502/system/console/bundles/<bundle number or symbolic name>.json | jsawk -n 'if(this.data[0].state=="Active")' | echo "Bundle is Active"


How to check if All bundles are active

curl -u admin:admin http://localhost:4502/system/console/bundles/<bundle number or symbolic name>.json | jsawk -n 'if(this.s[3] + this.s[4] > 0)' | echo "There is some problem not all bundle is active"

Find all Bundle having some problems

curl -u admin:admin http://localhost:4502/system/console/bundles.json | jsawk -n 'for(var i=0;i<this.data.length;i++) {if(this.data[i].state!="Active" && this.data[i].state!="Fragment") out("Bundle " + this.data[i].symbolicName+"  is "+ this.data[i].state)}'


 

Sunday, December 11, 2011

How to transfer file from one CRX to other modified after certain date using CURL in CQ / WEM / CRX

Use case: You want to copy all files modified after certain date and time from one instance to another. this is also use ful for migration projects.

Solution You can use following unix script to do that (Example refer /var/dam) change it based on your requirement

Approach: Initially I thought, I will build list of all the pages and then use vlt rcp. But problem with this approach is, on destination you might not have Path (Subfolder) and in that case you will get path not found exception using vlt. Instead you can use reciprocal approach and find all pages created "before" certain date and then exclude them (Good for smaller size folder, not good for huge data) from all vlt copy from parent folder (Make sure that that exist in destination).

Prerequisite make sure that you have VLT configured. Please see http://dev.day.com/docs/en/crx/current/how_to/how_to_use_the_vlttool.html for that

Solution

#!/bin/bash
# Author: upadhyay.yogesh@gmail.com

# The host and port of the source server
SOURCE="localhost:4504"

# The user credentials on the source server (username:password)
SOURCE_CRED="admin:admin"

# The host and port of the target server
TARGET="localhost:4508"

# The user credentials on the target server (username:password)
TARGET_CRED="admin:admin"

#Filter path
FILTER_PATH="/var/dam"

#Root Path
ROOT_PATH="/var/dam"

FILTER_COUNT=0

SPACE=" "
#############################################################################

#Query to get all files uploaded after certain date
#echo "Creating path list"
ALL_PATHS=`curl -s -u $SOURCE_CRED "$SOURCE/bin/querybuilder.json?path=$FILTER_PATH&type=nt:file&&p.limit=-1&daterange.property=jcr:created&daterange.upperBound=2011-11-11&daterange.upperOperation=<&orderby=jcr:created&orderby.sort=desc" | tr ",[" "\n" | grep path | awk -F \" '{print $4 "\n"}'`
echo "$ALL_PATHS"
for SINGLE_PATH in $ALL_PATHS
do
EXCLUDE=${EXCLUDE}${SINGLE_PATH}${SPACE}
done
vlt rcp -e '$EXCLUDE' -r http://$SOURCE_CRED@$SOURCE/crx/-/jcr:root$ROOT_PATH http://$TARGET_CRED@$TARGET/crx/-/jcr:root$ROOT_PATH
echo "vlt rcp -e \"$EXCLUDE\" -r http://$SOURCE_CRED@$SOURCE/crx/-/jcr:root$ROOT_PATH http://$TARGET_CRED@$TARGET/crx/-/jcr:root$ROOT_PATH"

Monday, December 5, 2011

How to use CURL command to find pending and blocking job in the replication Queue in CQ5.4 / WEM

Use case : You want to write monitoring script to find all pending and blocking job in the replication queue and do some action.

Solution : Use following curl commands (Change server name, Port, UID and PWD)

To find all pending Jobs
curl -s -u admin:admin "http://localhost:4504/bin/querybuilder.json?&path=/var/eventing/jobs&type=slingevent:Job&p.limit=-1&fulltext=/com/day/cq/replication/job&fulltext.relPath=@slingevent:topic&property.and=true&property=slingevent:finished&property.operation=not&orderby=slingevent:created&orderby.sort=asc" | tr ",[" "\n" | grep path | awk -F \" '{print $4 "\n"}'

To find all Blocking Jobs
curl -s -u admin:admin "http://localhost:4504/bin/querybuilder.json?path=/var/eventing/jobs/anon&type=slingevent:Job&rangeproperty.property=event.job.retrycount&rangeproperty.lowerBound=1" | tr ",[" "\n" | grep path | awk -F \" '{print $4 "\n"}'

Once you have blocking jobs, You can go to CRX and remove blocking entry (Before that make sure that blocking entry is causing problem).

You can also use replication clean up script (It is custom script I wrote to remove one entry) to remove one entry from the queue and then if necessary activate them again.

Blocking replication queue can happen because,

1) There is some problem with sling eventing and queue is not getting processed (For that restart sling event support bundle from felix console)

2) There is a blocking job in the queue (For that find blocking entry in the queue using above curl command and remove it)

3) There is some problem with publish server (503 or OOM etc, In that case restarting publish server should resolve the issue)