Friends, this blog post might be somewhat tricky and thought-provoking . The questions which are mentioned below are basically business scenarios which are asked in an interview and you are required to ponder over it and come up with the most feasible solution. The answers to these questions might differ approach to approach. There could be a possibility that you may come up with a better solution or maybe the answers which I have written below might broaden the scope of your thinking. Do let me know if you have a better solution for them. I would be happy to add it here.
Q1.) How would you design a global implementation of Header and Footer?
Headers and Footers are like the first and foremost thing we design for a website based on a requirement and need of the client. I would like to share few of the handy approaches which might help you design it better:
- Site Content Hierarchy Component: For this approach, you have to build up a Header/Footer component which will pick up the Site hierarchy as defined and showcase it in the Header / Footer Menu. The authors can define a content path below which all the pages are picked and displayed based on the page depth. You may also allow authors to define the max page depth for the navigation.
- Global Configuration Page: The idea behind this approach is to develop a global configuration page wherein CQ-authors can define the Navigation based on primary, secondary and tertiary (etc.) levels and then that configuration may be picked for all the pages in the site. This approach gives a very good restriction for the site navigation as the specific Global Configuration Page can be made accessible to limited Admin users only. The second advantage of this design is that site hierarchy is not acting any role and authors can define any of the pages links to be displayed in Navigation.
- Template Specific Design: This approach uses design dialog wherein either the component defined in Approach 1 above OR a different component where users can add links and pages as per requirement could be dropped. This will make the Navigation fixed for a particular template only and not for the complete site.
- Global Design with iParsys: This approach uses iParsys in addition to the component defined in Approach 1 above OR a different component where users can add links and pages as per requirement could be dropped. This will make the Navigation applicable for the complete site and if the user needs a different Navigation to be displayed he can just Disable inheritance and author a different Navigation component for its child pages. This is by far the easiest and widely used approach.
Q2.) You have a lot of brands – Nike, Adidas etc and in your AEM content structure, there are a lot of pages of these brands. You cannot segregate the site hierarchy for these brands. The client is expecting a different theme for all these brands. How would your solution be?
I would approach the problem with a few solutions I can think of:
- Global Configuration Page ( Assuming Dynamic CSS): Make a Global Configuration Page wherein users can specify which brand has what CSS/theme included. This configuration page could be used to select a particular brand, its CSS (either path of CSS file already fixed or include a zip package), its logo or any other changes particular to a brand. All the pages would pick the CSS file from this global configuration page and would apply that theme based on that brand. The brand could be identified either by using Tags on the page, selectors for particular brands or by using pre-specified path.
- Considering Fixed CSS: If we have fixed CSS file, we may map them directly with the Tags on the page. If a particular Tag is present on the page (e.g. Nike, Adidas), the CSS would be included directly on that specific page. The Tags could be authored by CQ authors from the Page properties. We can also approach the problem using selectors.
- Segregation: A better and ideal scenario would be if we could have segregated the brands in a particular site hierarchy so that one theme could be applied for all the pages under a node for a particular brand.
Q3.) You might be aware that whenever I upload a DAM asset in AEM, a back-end workflow gets triggered. Now I have to upload approx 3000 dam assets of various sizes in my AEM instance and I don’t want to burden my instance with thousands of workflows at once. How shall I go about it?
- Transfer from FileSystem to CQ instance: In order to bulk upload a large number of assets, generally WebDav is used. There is a great blog post which explains graphically regarding the steps involved in that.
- Transfer from one CQ Instance to another: There are multiple options available in CQ to move content from one CQ instance to another. These include “replication” (author->publish), and create package->export->install elsewhere. 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. Just make sure you disable DAM workflow while transferring DAM assets from one instance to another. Read More
Q4.) You have the data stored in an external database which has a lot of tables. Your task is to import that data into CQ5. How will you approach the scenario?
In general, the default TarPM persistence manager gives better performance than most RDBMS alternatives for the typical CRX use cases (involving web content and user management). But in certain situations, with certain use cases, performance with TarPM can take a hit. The most common problem? Big Flat Lists.
Although read performance remains good, write performance can suffer in the case where you need to store, say, thousands of sibling nodes under one parent node. This has to do with the fact that TarPM is an append-only store in which objects are immutable and never overwritten, only rewritten. What it means is that the cost of adding (or updating) Node No. N-thousand-plus-one can be quite high.
- Divide and Conquer: Break the nodes up into smaller groups, preferably hierarchical groups. Suppose you have a large number of users whose user-data you want to store in CRX, and you’d like to be able to store users by name. The naive way would be to store Joe Smith under a node named users/joe_smith, Lee Jones under users/lee_jones, etc. But after a thousand names or so, performance will start to suffer noticeably as new entries are written to the repository. Far better performance will result if container nodes (buckets) are created for each letter of the alphabet, and for each Last Name, so that you can add Joe Smith as /users/S/Smith/Joe, for example.
- Hash user IDs: A more sophisticated approach would be to hash user IDs and chunk the hash to form an ad-hoc hierarchy. For example, “Joe Smith” might give a hash of ab12cd34. The user data for Joe Smith can be stored at users/ab/12/cd/34. When the time comes to look up data for Joe Smith, you would first hash the name (to obtain ab12cd34), then create the necessary path from the hash, and look up the data.
- BTreeManager: As it turns out, the Jackrabbit API offers yet another alternative for efficient hierarchical storage of arbitrary data, in the form of the BTreeManager. This class provides B+ tree-like behavior in allocating subtrees of nodes that are always balanced, with a fixed limit on how many siblings any given node can have. (You provide the limit as an argument in the constructor.)
I wrote a very short test script (in ECMAScript) to show how the BTreeManager operates, as shown below:
The real lesson here is: If your content is hierarchical, by all means, capitalize on that fact! Don’t try to treat your content as a Big Flat List, especially if you’ll be doing a lot of updates. (If you’re doing mostly reads and few writes, on the other hand, it doesn’t much matter.) Introducing a bit of hierarchy to your content organization scheme will go a long way toward promoting fast update performance.
Q5.) You have 2 environment – dev and test. There are group permissions which are authored in dev environment and need to be passed onto the test. How will you approach the scenario?
It is common to have multiple CQ Publisher instances in different environments (DEV, QA, PROD, etc.). When you make user administration and security changes toward users and groups on the production server, you may want to bring them down to the lower DEV and QA environments so they don’t go out of sync. In such scenario, you have to copy over both user/group definition and the permission definition. This post shows you how to copy users and groups you set up on one CQ instance (source CQ) to another instance (destination CQ), and how to bring over the permissions (resource-based ACLs) from the source CQ to the destination CQ.
Follow the below steps to do so:
- If source application is cq5.3/cq5.4 this package has to be uploaded and installed at A.
- If source application is cq5.5, this package has to be installed at A.
- go to <host>:<port>/apps/tools/components/createPackage/run.html
- Give your Xpath in xpath value – //element(*,rep:ACL)
- ACL Behaviour – select overwrite
- Give a name to package – say ‘migrateACL’
- Click on Create config package
- Now Download this package and also be saved under /etc/packages/CQSupportTool
- Upload the package at ‘B’
- Install the package at ‘B’
Other ways to do so are explained in detail here.