Quantcast
Channel: Infrastucture – Adobe Experience Manager Podcast
Viewing all 36 articles
Browse latest View live

A CQ Infrastructure for the EC2 Environment

0
0

What is EC2, and why do we use it?
EC2 or the Amazon Elastic Compute Cloud allows users to rent virtual servers hosted in Amazon’s network architecture. As a networking architecture, it is a powerful force multiplier for systems administrators who need the ability to scale things up or down with short notice. For instance, just a handful of commands in the EC2 environment allow you to add a new server, or quadruple the processing capacity of an existing server, in just a matter of minutes.

It is especially appealing to Axis41, as an agency that offers a full suite of services strategically defining, creatively designing and intelligently deploying content for our customers. It allows us to focus core competency on the aspects of the customer’s needs that have to be tailor-made, and leave the actual physical administration of servers to someone else.

How do we use EC2 with AEM?
Our architecture focuses on a few things:

  1. The site should be available to end users with as near to 100 percent uptime as we can reasonably manage.
  2. We should offer the shortest possible window of time from first request through completed response.
  3. The authoring environment should be reasonably responsive during peak periods of content creation.
  4. In the event of catastrophic failure, we should have a recovery plan in place that focuses on getting the content back in front of users as quickly as possible, without sacrificing the recoverability of the master data.

Adobe’s ideal deployment scenario for customers involves:

  • Two author instances running on separate EC2 “m1.large” instances
  • Two publish instances running on separate EC2 “m1.large” instances
  • Two dispatchers running on separate EC2 “EBS-Optimized” instances
  • An Elastic Load Balancer

So what do those terms mean, and why this architecture?
Amazon offers a wide range of “instance types,” each of them optimized for specific usage scenarios. The “m1.large” instance type is the virtual equivalent of a dual CPU server with about 8GB of RAM and decent network performance. We like this option because AEM can be a bit of a memory hog, but it also needs reliable disk performance for the CRX-backed datastore. Meanwhile, the dispatchers don’t require very much processing power, but their I/O throughput needs are much more sensitive than those of the CRX. Therefore, we recommend this “EBS-Optimized instance” option, which allows us dedicated throughput between the EC2 and the EBS instance (which is where the data actually ends up being stored).

The Elastic Load Balancer is a special EC2 offering you can use to distribute incoming traffic across your Amazon EC2 instances, while maintaining the ability to support “sticky user sessions” and SSL termination two of the largest issues people typically face when trying to do their own custom load balancing solutions.

As we mentioned earlier, our focuses are availability, reliability, recoverability and performance. This architecture gives us a lot of flexible options we can tune and optimize to handle each customer’s specific workloads, and it also prevents us from having a single point of failure outside of the EC2 service as a whole. For the rare customer who is willing to accept a dramatic increase in price to remove that single point of failure, there are other options we can bring to the table as well.

Is there anything else about EC2 you should know?
Because we don’t have to focus on the physical servers and networking of these instances, we can spend our resources customizing the working environments to the specific needs of AEM, and to the requirements of each individual customer. In a future blog post, we will cover backup and recovery techniques, and how we use EC2 to provide for some of AEM’s unique needs in those areas.

One of the things we’re really excited about at Axis41 is Amazon’s new Virtual Private Cloud service. We are investigating how we can best utilize this new offering from Amazon to deliver a great experience to our customers and their end users.

The EC2 environment in conjunction with AEM is an excellent resource to Axis41 as we continue to offer several robust services that focus on custom-made solutions for customers. Through this EC2/AEM architecture, we continue to focus on reliability, availability, recoverability and performance as we look toward future technologies.


How to Configure AEM Dispatcher to Redirect Based on Geolocation

0
0

There are many reasons you might want to take action on your Adobe Experience Manager website based on the physical location from which your users are coming. For example, you might have multiple language versions of your site and want to provide users from France with the French version of the site by default, or perhaps you want to block everyone from a specific region from even being able to reach your site. Whatever the case may be, mod_geoip is here to help.

We’ll assume you’ve already installed Apache. mod_geoip2 from MaxMind allows you to perform traffic shaping based on the geographical location of the IP address from which a client request originates. Axis41 generally uses a RedHat-like Linux distribution, where this module is available in the “EPEL” repository under the name mod_geoip.

If you haven’t set up the EPEL repository, you can enable it with a command such as this:

sudo yum-config-manager --enable epel

Once the EPEL repo is enabled, you can instruct your package manager to download and install mod_geoip, as well as the GeoIP data and some related libraries like so:

sudo yum install GeoIP GeoIP-devel zlib-devel mod_geoip

MaxMind, the company behind GeoIP, regularly updates its database files; we recommend creating a cron job to update to the latest version of these files on a regular basis.  Here we present a series of commands to create a bash script to perform these steps, which will most likely require root privileges. Our example is based on the free “GeoLite” data files; if you have a license from MaxMind to the commercial version, you can replace the URLs as appropriate:

#Create shell script to update database files
cd /usr/share/GeoIP/
#On other distros this could be in /var/lib/GeoIP/
#Do not quote the heredoc terminator on RHEL environments
cat > geoipupdate.sh <<'EOT'
#Download Maxmind GeoIP databases
GEOIP_PATH="/usr/share/GeoIP/"
CUR_DATE=`date +%m-%d-%y`

cd ${GEOIP_PATH}

wget -q  http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
wget -q http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz

if [[ ! -s GeoIP.dat.gz ]] || [[ ! -s GeoLiteCity.dat.gz ]]; then
        echo "Zero Byte File Detected, exiting..."
        exit
fi

for i in GeoIP.dat GeoLiteCity.dat; do
        mv -f ${i} ${i}.${CUR_DATE}
        gunzip ${i}.gz
done

EOT

Change the permissions on your script so it has the correct rights and add it to your crontab:

chmod 750 geoipupdate.sh
#Edit your crontab to run this script every 3rd day of the month:
(crontab -l ; echo "0 0 3 * * /usr/share/GeoIP/geoipupdate.sh")| crontab -

Edit the configuration file /etc/httpd/conf.d/geoip.conf and change the path of the database. Use your system’s facility for enabling an Apache module to activate the geoip module; in our case, we will be adding the “LoadModule” line directly to the geoip.conf file (see below).  (GeoLiteCity.dat also returns the City Names and the geographic locations):

LoadModule geoip_module modules/mod_geoip.so

<IfModule mod_geoip.c>
  GeoIPEnable On
  GeoIPDBFile /usr/share/GeoIP/GeoIP.dat
</IfModule>

Now create or edit your vhosts file. For example, if you want to block clients from Russia and China, you might use the following example:

SetEnvIf GEOIP_COUNTRY_CODE CN BlockCountry
SetEnvIf GEOIP_COUNTRY_CODE RU BlockCountry
Deny from env=BlockCountry

If you want to redirect based on the country using mod_rewrite in combination with mod_geoip, your vhosts file could look like this:

RewriteEngine on
#Redirects based on country
RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^FR$
RewriteCond %{REQUEST_URI} !/content/yoursite/fr
RewriteRule ^(.*)$ /content/yoursite/fr$1 [R,L]

RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^DE$
RewriteCond %{REQUEST_URI} !/content/yoursite/de
RewriteRule ^(.*)$ /content/yoursite/fr$1 [R,L]

RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^UK$
RewriteCond %{REQUEST_URI} !/content/yoursite/uk
RewriteRule ^(.*)$ /content/yoursite/fr$1 [R,L]

Restart Apache:

service httpd restart

For more on what mod_geoip2 can do for your Adobe Experience Manager Website, visit the MaxMind website, where you can find more information on how to serve up meaningful content to users based on their preferences, location, and other data. And if you need help configuring or fine tuning your Adobe Experience Manager infrastructure (Dispatcher, Publish, or Author) to your needs then please contact us or send us an email info@aempodcast.com.

Hosting Adobe Experience Manager in the Cloud – Adobe Managed Services

0
0

At the end of November 2014, Axis41 upgraded CMO.com to Adobe Experience Manager 6.0 from CQ 5.5 and had the opportunity to migrate the site to Adobe Managed Services (AMS). It was a challenging process to manage the moving parts given the coordination between four distinct teams (Axis41, CMO.com, Adobe@Adobe, and Adobe Managed Services). While we have talked about the process or what it means to host a site on AEM “in the Cloud” before, we wanted to take a few minutes to discuss what it means to host in the Cloud with Adobe Managed Services. I want to emphasize that I am not an expert in Adobe Managed Services offerings but wanted to share our experiences in working with them on the CMO.com project. And, a special thanks to Patrick Kynaston, who was my principal contact and the Customer Success Engineer for CMO.com at Adobe Managed Services, and helped us through the migration from our system to AMS.

AMS uses Amazon Web Services for its hosting platform, which is actually what Axis41 uses when we host a website in the cloud. We like its feature set and its ability to scale up and down very easily. Because CMO was set to go live a week before Thanksgiving, we chose to have them host the site on a larger instance, so it would compensate for any unforeseen possible issues (no one wants to get a call during their vacation). We made that change with the proverbial flick of the wrist, without the need to wait for new hardware.

Similar to Axis41’s Systems Support team, AMS controls the Production environment—and the only action they allow in that environment is authoring. Everyone other than an AMS employee is locked out of System Console, CRXDE Lite, and Package Manager. However, they will create a mirror of Production called Stage, which is a complete copy of Production. As changes or fixes are worked on in the respective development environments, they can be brought up to Stage and then thoroughly tested to ensure they will work correctly when deployed to Production.

Pre-Launch Activities
Because of how new this process was for us, to work with Adobe Managed Services procedures, I felt that it would be a good idea to walk through a variety of the pre-launch activities that the AMS team requires their customers to go through in order to certify that a site is ready to be hosted on their systems. There are other areas that I will not cover because we are highlighting the major areas of coordination we had to go through. Your experience may differ.

RunBook
The RunBook is an evolving document that must be completed before AMS can deploy the site live. It is the heart of a site for the AMS team, as it contains all the relevant documentation about the site. A customer of the AMS team must document all of the necessary features, integrations, etc., that are critical for the site to run. The general idea is that anyone working within AMS should be able to be brought on board to the project, read the RunBook, and have the relevant information to manage the site infrastructure. The process of documenting all areas of the site for the RunBook allowed us to see potential areas of deprecation and resolve issues prior to deployment. The Runbook is probably the toughest requirement in working with AMS because of its complexity and requirement for high detail. Deficiencies in documentation at this point will only lead to frustration and confusion down the line, potentially at a critical period of time.

Review of Packages, OSGI Bundles, and Backend Linkages
The Runbook contains some areas that needed more in-depth review than others, and were divided into three categories: (1) responsibility of the AMS lead (Maintenance, System Monitoring), (2) AMS client responsibility (Cloud Services, Custom Packages, Custom Bundles, and Backend Linkages), and (3) mutual responsibility (dispatcher configs, DNS, Events and Responses). Let me briefly focus on the areas of biggest concern to us: Packages, Custom Bundles, and Backend Linkages.

We had to spend quite a bit of time documenting and preparing for a deployment to a new environment. As anyone who has worked with AEM is aware, Packages are where you put the components, content, styles, and other front-end logic for your site. Without them, you don’t have a site. As in any other systems development, over the years the site had accumulated some services and packages that were unnecessary and needed to be removed.

Custom Bundles provide the underlying services that drive the packaged components, as well as interact with external services and provide configuration specific to the site’s needs. As with the packages, we found that in some instances, the service was no longer relevant; in other cases, we needed to alter some OSGi configurations to align them with AEM 6.0, and to improve the process in general.

Backend Linkages are a listing of the third-party systems that the site calls upon to either bring in data or run a particular function. These backend linkages include things like Adobe Marketing Cloud products, reCAPTCHA, etc. All third-party integrations and external communications had to be documented, with the endpoints identified. In some cases, this required us working with external vendors to get information that was not readily available to the public, in order for the AMS team to understand how things were working.

User Acceptance Testing (UAT)
Adobe Managed Services requires that you prepare a User Acceptance Test set of test cases and ensure that the site passes these test cases. This is a good practice, regardless of hosting location. AMS did not require a completely robust set of test cases, only the critical areas of primary site control and authoring. In our case, we developed the test cases and did the testing for the customer.

Performance Testing
Another of our responsibilities was load performance testing to validate servers would handle a larger than normal load, which ensures reliability during traffic spikes and other unusual patterns. Although the AMS team would be responsible for the server, the responsibility for load testing the delivered platform fell to Axis41 and our Systems Support team. We used Apache JMeter to perform this testing, creating several scenarios—varying from a sustained load at more than double our previous peak traffic, to spikes of up to four times peak traffic. After we conducted testing, the process proved positive as we were able to see some areas of improvement that needed to be implemented in the out-of-the-box AEM list component and cache process.

Change Approval Board (CAB Process)
The process to move new code or configurations up to the Production environment is via a Change Approval Board, or CAB. The general rationale is when new changes are ready to be introduced to a site, the AMS team needs to be able to review and understand the updates and implications. The main function of the CAB is to certify that any changes have been tested and documented. Any bugs, errors, or issues are the responsibility of the AMS customer, not AMS. AMS will indicate that the customer had tested it in the Stage environment.

When you submit a CAB, you must also complete a document that explains what the deployment is fixing or enhancing. The document must include definitions of what is being done, indicate its risk assessment, give the step-by-step process for the AMS individual deploying the code, and lastly outline the reversion plan in case there is an issue at deployment. The document is submitted to the AMS lead and they begin the approval process. AMS has at least five individuals on their side that must review the document and provide approval or denial. The customer can also add additional people from their side to review things, such as a development supervisor, but this depends on how involved the customer wants to be. Because of the long-standing relationship of trust that the CMO.com team has with Axis41, they do not require reviews on their side and we can submit things when we deem it necessary.

In the case of CMO.com, there is a weekly release schedule. We could submit a CAB whenever we want, but, similar to software development best practices, we felt that it was best to maintain a regular, rigorous release pattern. This means that in order for a deployment to occur within the release window, a CAB must be submitted three days in advance. Yes, three full days in advance. This forces us to work regularly in a good cadence with the CMO.com author team to ensure they have reviewed and approved items in time for us to submit to the CAB.

ECAB
After learning about the CAB process, our first question was, what do we do if there is an emergency? In the past, we had complete access to make any needed change, on the spot. We saw this as a shift and paradigm change for both us and the CMO.com team. The answer from AMS was the Emergency Change Approval Board, or ECAB. The requirement to submit a CAB is still in place, and eventually it must be reviewed by their board, but they are willing to abbreviate the process in order to get the issue resolved and maintain uptime or site integrity. After the switchover, we had to request a few ECABs as there were some configurations that needed to be adjusted, but an ECAB is a special exception—not a standard practice. I wouldn’t recommend getting into a habit of multiple ECABs as it is likely to raise a few eyebrows on the AMS side, if not within your own development team. It is better to spend the proper amount of time needed to test the code/system/upgrades than push out code and hope everything is ok.

SharePoint
AMS uses the Microsoft SharePoint system as a place to maintain and manage all relevant documents and CABs. If you are unfamiliar with this tool, your AMS adviser will show you some of the basics to navigate the system.

Day Care Ticket
AMS offers 24/7 support, and customers looking for assistance are assigned a specific worker who will be available during normal business hours. But, what happens if something goes wrong during non-business hours? The process for communicating a problem is to create a support ticket with Adobe. AMS has employees on staff 24/7 and can assign an issue to the on-call/site worker. They will then review the Runbook to understand how things are handled in your specific implementation.

Conclusion
Although we were excited about the challenge of migrating to AMS and working with the AMS team, we were accustomed to managing the site from end to end and had to adjust our processes. We initially had some concerns about loss of control over the site (especially access to CRX in the Author environment and being locked out of Publish completely) when we are the stewards and day-to-day managers of the site. Navigating this new relationship continues to be an evolving process, as we work hand-in-hand with the AMS team in their responsibility for maintaining the infrastructure uptime and our responsiblity to the CMO.com team to make constant updates, enhancements, and improvements to the CMO.com site.

In conclusion, I know that this list is not exhaustive and that your experience may differ, but this should hopefully give you a good idea of the types of things that you will need to do should you ever choose to have Adobe Managed Service host your site “In The Cloud”.

CMO.com by Adobe delivers marketing insights, expertise, and inspiration for and by marketing leaders—all aimed at helping CMOs and senior marketers lead their brands in this new digital world.
Adobe Managed Services provides cloud hosting and expert application support as well as 24×7 maintenance and support and a single point of contact for each customer throughout the application lifecycle.
Adobe@Adobe partners with Adobe product teams and business owners to design and implement solutions that showcase Adobe’s Digital Marketing and Digital Media products by delivering business value using Adobe technology within Adobe and on Adobe.com.
Axis41 is fully integrated creative and technical development teams working together to strategically create, deploy and optimize marketing content that inspires and strengthens profitable relationships for our customers.

LDAP in AEM 6.x

0
0

05287_LDAP_in_AEM_6(1)
Starting in Adobe Experience Manager 6.0, there has been a significant change in the way LDAP Authentication is managed. Rather than using the jaas.conf file of earlier releases, AEM 6.0 comes with Jackrabbit Oak, which has its own LDAP integration. Although the Apache Jackrabbit developers have provided documentation for configuring the system, we felt that it would be helpful if we could provide an example of this configuration.

There are three things we need to configure in Adobe Experience Manager: the LdapIdentityProvider, a DefaultSyncHandler, and an ExternalLoginModule. While in these examples we will be using the Felix Console, we at Axis41 always recommend that all Production OSGi configurations be saved in your source code repository, and become a regular part of your deployment process.

You should take the time to understand all the options in each configuration; however, we will be focusing on the options that you most likely will need to configure.

Apache Jackrabbit Oak LDAP Identity Provider (LdapIdentityProvider)

LdapIdentityProvider

provider.name The “idp.name” we will provide to the ExternalLoginModule
host.name The host where your LDAP server is running
bind.dn The Distinguished Name (DN) to bind to LDAP with
bind.password The username to bind to LDAP with
user.baseDN The LDAP DN that is the base for user accounts that will be allowed to authenticate with AEM
user.objectclass The LDAP objectclass for user objects that will be allowed to authenticate with AEM
user.idAttribute The LDAP attribute that will determine the AEM username
group.baseDN The LDAP DN that is the base for group objects that will be searched by AEM

Apache Jackrabbit Oak Default Sync Handler (DefaultSyncHandler)

DefaultSyncHandler

handler.name The “sync.handlerName” we will provide to the ExternalLoginModule
user.expirationTime How long after synchronization a user object should be considered valid
user.autoMembership Synchronized users will automatically be added to this group.
user.propertyMapping A String[] of “key=value” pairs; keys will be the AEM property name, values the LDAP property which will be copied.
user.pathPrefix Location where synced users will be stored; the value will be appended to /home/users.
group.pathPrefix Location where synced groups will be stored; the value will be appended to /home/groups.

Apache Jackrabbit Oak External Login Module (ExternalLoginModule)

ExternalLoginModule

idp.name provider.name from the LdapIdentityProvider
sync.handlerName handler.name from the DefaultSyncHandler

What it looks like after it syncs

One of the things we found to be a surprise was the name Adobe Experience Manager chooses for the node as it syncs the user from LDAP. Here’s a CRXDE Lite view of a set of objects created using the OSGi configs I shared above. You can see the machine-generated name of both the user and group nodes after the sync took place.

crxde

Adobe Critical Security Hotfix for AEM 5.5.0-6.1

0
0

Adobe today released a Critical Hotfix for AEM to patch a flaw (CVE-2015-7501) classified as CVSS 10.0 (highest criticality in the Common Vulnerability Scoring System). You can find information about the Hotfix by logging into your Adobe PackageShare, or by visiting https://www.adobeaemcloud.com/content/marketplace/marketplaceProxy.html?packagePath=/content/companies/public/adobe/packages/cq/hotfix/cq-ALL-hotfix-NPR-8364.

We join with Adobe in recommending that this Hotfix be applied as soon as possible to all AEM servers 5.5.0-6.1.

If you need any background on the issue, or help figuring out how to apply this to your environments, please don’t hesitate to contact us: @axis41 or info@aempodcast.com.

AEM 6.1 Service Pack 1 Released

0
0

AEM-6-Service-Pack-1-Released
We’ve been waiting anxiously for Service Pack 1 for AEM 6.1 environments, and are happy to announce that it has been released. This hotfix includes many important updates, including Jackrabbit Oak version 1.2.7 (which brings both stability and performance improvements); a host of Touch-UI updates; and a number of other critical updates.

Customers of Axis41’s AEM Managed Services offering are already receiving this update from their Systems Engineers. We recommend you deploy this hotfix in your pre-production environments and perform a full QA cycle before deploying it to your production environments.

If you have questions about the service pack, or would like help getting it deployed in your own environments, please reach out to us via systems@axis41.com.

Solving the dissonance between AEM Dispatcher and Publish

0
0

Solving-the-dissonance-between-AEM-Dispatcher-and-Publish
Part of the beauty and attraction of Adobe Experience Manager is its system architecture—the Author, Publish, and Dispatch instances. Let’s look at a high-level overview of how these things work together. The Author instance allows content to be authored and updated easily and efficiently. The content is then activated and replicated to the Publish instance so web pages are always teeming with the newest content, ready for public consumption. The Dispatcher instance is a cached version of published content so when users hit a website, the content is readily available at increased speeds. The Publish server also lets the public-facing Dispatcher know when its content is out of date and needs to be re-cached on a content path. When a user visits a page with old, invalidated content, that page request will prompt the Dispatcher to fetch new content from the Publish instance and serve that content to the user as well as cache it. The next person to visit the page will receive a fast, updated web page.

It’s simple, right? Author new content –> activate –> publish updates –> Dispatcher is informed it has old content -> Dispatcher re-caches new content when page is visited. It really is a great system, but it isn’t without complex and interesting challenges, depending on the structure of your site and how content is being used.

The problem we faced:
What happens when you have content on one page relying on content from another page? In one particular project, we worked on a complicated site architecture where pages used information from other related pages to populate certain content. For example, Page A is related to Page B for specific content it displays. When the related Page B is updated and activated, AEM does its process and Page B is updated on the Publish instance and eventually gets updated on the Dispatcher. But Page A is relying on that content and does not know that Page B has been updated. Page A does not get re-cached or invalidated and displays old Page B content. There may be additional cases, where Page B refers to content from other pages as well. As you can imagine, this created a huge problem. This system of speed and accuracy was suddenly only fast and definitely not accurate. How did we get related content to stay updated?

Our solution:
We used a combination of an AEM workflow launcher and a custom Java class, implementing the WorkFlowProcess class. Let’s first look under the hood of how this site architecture works. The relationship is that Page A contains a property that refers to the path of Page B. There may also be several other pages: Page C, Page D, etc., that refer to and point to Page B for information and content. If we can collect all of these paths, we can do a request to the Dispatcher, telling it to invalidate and re-cache all of these pages. Whenever a page was activated, the workflow launcher kicked off the custom workflow and executed a series of JCR queries to check for the path of the recently activated page (Page B), which we got through the payload of the WorkItem Java class.

public class RelationalCacheBusting implements WorkflowProcess {
 
	public void execute(WorkItem item, WorkflowSession session, MetaDataMap args)
     	   throws WorkflowException {  
 
WorkflowData workflowData = item.getWorkflowData();
String triggeredPagePath = workflowData.getPayload().toString()
 
…}

If Page B’s path existed in any properties in the JCR nodes of other pages, it would be related to the activated page. We conducted a check to see if Page B refers to any other additional pages. The site architecture allowed us to have an idea of which page component types to check for in our query, narrowing down where to look for relationships, but also largely relying on knowing where to look based on the page component type of the activated page. For example: one page component type—the Map Modal—will always refer to another page component type—the Location—that provides information about a physical location or an address. We knew if this address page was modified and activated, we needed to look in the pages that referenced the address pages.

We collected all the paths of pages that referred to Page B and all the pages that were referenced by Page B and did a request to the Dispatcher, telling it to invalidate all of those pages and then re-cache them.

Now, pages can be activated without worrying about the repercussions of pages relying on each other for their content! Even though it was a decent effort up front, this solution has been a big help to keep the site up to date and fresh, and has taken a big load off of the content authors.

Best Practice: Treat OSGi Configurations as Code

0
0

Best-Practice-Treat-OSGi-Configurations-as-Code
The Question
A few months ago, one of our customers who self-manages their Adobe Experience Manager stack was doing some digging in the filesystem underneath the crx-quickstart folder. They noticed a correlation between the filenames found there (specifically, under crx-quickstart/launchpad/config and the changes they would make in the Felix Console at system/console/configMgr to configure OSGi bundles.) Putting two and two together, this enterprising SysAdmin asked me:
“If I pull those out and drop them into a fresh instance and restart, will that ‘configure’ [the bundle] for me? Is this the best way to accomplish this and similar tasks? Are there API calls I can make to the site to configure these types of things? I’m trying to gauge what it’s going to take to stand up a fully functional instance without having to touch it every time. It seems awfully cumbersome to track down these files after every configuration piece. Do you have any pro-tips?”

Our Answer
While it was awesome that this guy found the correlation, we were quick to reply that we do NOT consider managing these text files to be an ideal way of configuring OSGi services. The better solution, we feel, is to put these configurations into your source control such that they are created as sling:osgiConfig nodes inside your JCR. There are two solutions for that.

Setting up the Package Structure
The short answer is to create the nodes directly with your IDE under jcr_root/apps/myproject/config in one of the existing modules.

Here’s an asciinema recording of me looking at such a setup on my own filesystem. However, Systems Admins are frequently not Adobe Experience Manager Developers, so it’s a lot to expect them to know/remember the directory structure and XML syntax for these configuration files. An easier way to create these things is by making the appropriate node in a CRXDE Lite running locally, and then using VLT (or CRXDE Lite’s Package Manager) to export the node structure and send it to the developers for incorporation into the code repository.

How Many Settings Could a Sysadmin Set If a Sysadmin Could Set Settings?
When doing it via this method, I sometimes begin by going to /system/console/configMgr and finding the service I want to configure. Clicking on the service in this screen opens a dialog.

Here, by way of example, is the dialog for the Apache Jackrabbit Oak Default Sync Handler:
dialogfortheApacheJackrabbitOakDefaultSyncHandler

In the CRXDE Lite, make a new node under /apps/ /config, of type sling:osgiConfig.

The node’s name will be based on the PID found at the bottom of the configMgr dialog. If the service being configured is a factory (as Apache Jackrabbit Oak Default Sync Handler is), then we will append .config. to the”Factory PID” instead.
FactoryPID

When Felix creates these nodes for you, it will put a UUID in the space, but this can really be any distinct value you choose—I usually like to choose a more meaningful name so I don’t have to remember UUIDs. This .config. is used because, as a Service Factory, there can be many distinct configurations of the same service living side by side; for example, we may want a different one per site.

Here’s what the dialog looks like CRXDE Lite:
identifierconfig

For each configuration value in the dialog, we will create an appropriate property on this new sling:osgiConfig node. The name of the property will be the name in parens at the end of the documentation string:
slingosgiConfignode

The type of the property will depend on the value; you should always refer to the API documentation for a given service the first few times you configure it, but after a while you start to notice a few patterns between the datatypes of service properties and their representation in the OSGi Configuration Manager. For example:

  • checkboxes are represented as a Boolean
  • simple integer values (e.g., user.membershipNestingDepth in the above) are of type Long in the service
  • pretty much everything else is a String

Also, pay attention to the little +/- buttons along the right edge of some inputs; where these appear, you should select the “Multi” toggle:
plusminusbuttons

multitoggle

When you have “Multi” selected, hitting “Add” will open a multi-value dialog. Input the appropriate values (in this specific case, there are none to enter, so we leave the initial box blank) and hit OK.
multi-valuedialog

Here’s what the completed sling:osgiConfig will look like:
completedsling-osgiConfig

Save your work and use the “vlt” command-line tool to export this. Here’s an example invocation using the default password of “admin” and connecting to an instance running on localhost:4502:
vlt –credentials admin:admin export -v -t platform http://localhost:4502/crx /apps/myproject somedir

That will create the same directory structure you saw in the asciinema above (it is, in fact, exactly how I created that structure.)

Now, your OSGi configurations can be moved into your change management process, giving better repeatable results, and moving us further down the pipeline to Infrastructure as Code. Let me know if you have any questions about any of the above!


A Year in the Desert of AEM: An Introduction

0
0

05287_AEM_A-Year-in-the-Desert-of-AEM_Intro
Let me start with a brief introduction both of myself and the purpose of this series. When I started my new position as a burgeoning Systems Administrator, I was told I would be working with Adobe Experience Manager (AEM, then called CQ), a product I had never heard of. I had to use Amazon Web Services (AWS), a cloud platform I had never worked with before. To say I felt enormous pressure to grow and perform quickly would be an understatement. The vast AEM environment felt nothing short of a desert wasteland, and I was being called to navigate. On top of this, there was quite a bit of standardization and automation that needed to be hashed out.

Thankfully I wasn’t completely alone; I had a new coworker who had been stranded in this wasteland in much the same way I was. There was also a team lead who was eternally buried behind the workload that my coworker and I had come to help tackle. I first started conceptualizing this series of articles after my first year working with AEM, thinking to myself, “What are some of the things I wish I had known from the start?”

That said, the purpose behind this series of articles is as an introduction to the administrative side of AEM. I will also impart some of the information I have picked up along the way. I will be splitting the remaining articles up as follows; Author, Publish, Dispatcher. Each of these articles will cover different pieces of information regarding the AEM stack; but before we venture too far from civilization as you know it, we need to prepare for our journey by covering some basics.

singleAPD

You see, I realized as I started writing up information about the different environments that there is quite a bit of other introductory information on AEM in general that might be helpful to point out. For example, sometimes you may read/hear references made about the Author environment; this can get a little confusing since we typically think of our environments in terms of “production”, “pre-production”, “development”, etc. “Author” is just one specific responsibility an instance can be assigned in AEM. So we will put a pin in the environments/responsibilities and come back to those later.

The Desert of AEM
The AEM landscape is nothing short of extensive. Like a desert, which is enormous in size and difficult to navigate, this robust content management system with integrations to the rest of the Adobe Marketing Cloud takes time and research to properly cross. AEM is built around a few open source projects with some proprietary code to hold it all together. We at Axis41 have found that AEM, due to its size and complexity, is many different things to different audiences. When looking at it from the SysOps point of view, we usually focus on two specific conceptual models: how it is delivered as a piece of software, and how it executes as a platform.

Let’s dive into the technology a little bit more. AEM has several layers for its Software Delivery Model, like an onion; at its core are the implementations of the OSGi (Apache Felix) and the JCR (Apache Jackrabbit). These are then connected with Apache Sling, which presents some added features—primarily a RESTful Framework, scripting engines, and an authentication layer. This is then wrapped up with Adobe’s CRX, which adds some proprietary features such as the Author/Publish model, replication support, and tools for management and development, just to name a few. The next layer is then the actual Adobe Experience Manager; this brings with it additional management tools for Campaigns, Websites, Assets, Tags, and Workflows.

Moving on we will take a high-level look at the execution model for AEM. The OS executes AEM as a Java application that will run in one of two modes, Author or Publish. Author is the main interface that content creators and developers will interact with. Publish is the “work-camel” of the AEM suite; it takes all the dynamic content and generates static data ready to be delivered to browsers. As AEM is a Java application, it also kicks off the JVM with the flags you have defined. The JVM executes Felix (OSGi), which in turn executes Jackrabbit (JCR), Sling, and the WCM.

Something I have noticed, especially with production environments, is that AEM tends to struggle if you allocate less than 2GB of memory to the JVM. Also, the JDK and Java version you use matters. For AEM versions earlier than 6.0 SP2, you will not be able to use Java 8, and OpenJDK is unsupported.

Planning Your AEM Expedition
Before undertaking your desert excursion, you ought to be certain that everything is in order, like the amount of food and water that you have and the location of various checkpoints along your way. You also need to know how AEM communicates to the other servers in the stack ahead of time. It is important to note that the information I am providing is the default and recommended settings. These settings can be changed, but you really should have a very good reason before you do so, if for nothing else to avoid confusion later on. The image below shows the various security zones and the ports AEM uses, which will need to be whitelisted.

AEMsecurityzoneandports

In a standard setup, you would have your content creators accessing the Author over port 4502 from an internal zone (or possibly through an Author-facing Dispatcher). Then you would have a zone for the Publish, which would be opened on port 4503 to communication from the Author and Dispatcher. Lastly, you would have a zone for the Dispatcher that allows communication on port 80/443 from the Author, Publish, and either the outside world or in a high-availability case from the Load Balancer.

Some additional information that you may want to be aware of is that the Publish server has a passive role—meaning it does not request information from either the Author or the Dispatcher. The Author will either push changes to or pull updates from the Publish. The Dispatcher either requests data from or sends data to the Publish. The only outside communication the Publish initiates is a simple request letting the Dispatcher know its cached content is out of date. So the Publish is really just a go between pulling double duty; first as rendering host, and secondly as a content buffer allowing content creators to make changes without them being viewed by the general public.

The AEM Caravan
Now that your travels have been mapped out, it’s important to know what your days will look like. Similarly, it’s imperative to understand how normal AEM operations work from day to day. Although this next part might sound like it’s straight from Abbott and Costello’s “Who’s on First” skit, it will give a good overview to use as a reference later on.

A content author signs into the Author instance and makes updates to a site page. This is then activated and can trigger a workflow for the content to be reviewed by another party. Once the new content is approved, it is pushed out to the Publish instances in the stack. These Publish instances, after ingesting the changes, then send an invalidation request to the Dispatchers letting them know the page has been updated. Lastly, an end user sends a request through the Load Balancer to view the page that has been changed. The Dispatcher recognizes that the requested page was invalidated and checks for a new version from the Publish. The Dispatcher caches the updated page and serves the request back to the end user. The image below may help visualize this process.

standardAEMarchitecture

With this information out of the way, you should be somewhat versed in the basics, which will help with further discussions of AEM. Whereas none of this is extremely complex, this information will better prepare you for the journey we will be taking together. You’re now armed and ready with what you need to begin the AEM journey as we venture into the great expanse and take a look at the various roles that exist within AEM. Our first stop is the Author.

If you have questions or comments feel free to email info@aempodcast.com.

A Year in the Desert of AEM: The Author

0
0

05287_AEM_A-Year-in-the-Desert-of-AEM_Author
Having prepared for the journey, you’re now ready to venture into the desert of Adobe Experience Manager and learn about the mystical Author. Ok, I am not sure I would really call the AEM Author mystical, but it sure can bewilder the uninitiated. For those of you who are returning for the second installment of this series of articles, I mentioned we would be digging into the various responsibilities within AEM. We’re going to discuss the Author instance, from its purpose through setup and maintenance. The setup and configuration for Author can also be found in Adobe’s documentation. The same process can be followed more or less for the Publish instance, which we will talk about in our next article. For those of you who haven’t read my first article, it covers some high-level information on AEM. Unless you are already familiar with the basic concepts surrounding AEM, I would suggest giving it a quick read before moving on.

Another quick note is that throughout the article I will reference ACS AEM Commons, which is a package provided by Adobe Consulting Services. Essentially, they generalize and make available tools they have created and package them as an add-on to AEM. These features can be extremely helpful and potentially save you and your developers a lot of time and frustration. I recommend including this package on all of your AEM installations. Let’s get started.

The AEM Caravan Lead
As you embark on your journey, it’s important to look to the leader to guide the expedition. Similarly within Adobe Experience Manager, it’s important to look to the Author to guide the creation and management of content. This server should be thought of as the lead instance in AEM. Developers will create templates and components for the the content creators to use on Author; content creators will create pages and import digital assets here as well. As a systems guy or gal, this is where all the configs are stored. The idea here is that everything, even configs that apply only to a Publish instance, is stored on Author and then replicated to Publish servers. Run modes, Author or Publish, for example, are then used to tell the servers if configs should be loaded or not. So really, in a worst case scenario, as long as you have a good backup of your Author instance, you will be able to restore your AEM stack. This does mean that inherently AEM has a single point of failure, the Author. I would suggest becoming very serious about your backup processes, if you are not already—especially when it comes to the Author.

As I mentioned above, Author is where content is created; when you first start an Author instance it installs code that is Author specific, basically the editing dialogs and tools. Just in case any of you were thinking “Well, I’ll just set up one Author and then save time by copying that instance and use it as a Publish”—don’t do it. I know you were thinking it, but don’t do it. You will end up having two Authors and you will run into all kinds of “fun”. This is because of installation run modes, and we’ll talk about those in a minute.

Currently Adobe Experience Manager is in a period of transition when it comes to the web interface; they are working toward Touch UI. What this means is the classic, older tools are being replaced gradually. So tools you might have used the past, including those that are mentioned in this article and others, might change slightly or entirely. With that in mind, I am going to share some paths that as an admin will be helpful to remember. I am going to list them with a quick description and include the alternate paths if there are old and new versions.

  • High-level navigation of the content tree; manage, activate, or deactivate pages
    • /siteadmin (classic tool)
    • /sites.html
  • Allows you to create users and groups, and manage permissions and members
    • /useradmin (classic tool: permissions can be managed here or under “Access Control” in the CRXDE)
    • /libs/granite/security/content/useradmin.html and
    • /libs/granite/security/content/groupadmin.html
  • High-level navigation of digital assets
    • /damadmin (classic tool)
    • /assets.html
  • High-level navigation for AEM tools, including ACS Commons
    • /miscadmin
  • Disk space reports
    • /etc/reports/diskusage.html
  • Replication agents and tree activation
    • /etc/replication.html
  • Workflow manager
    • /libs/cq/workflow/content/console.html
  • OSGI console access
    • /system/console/bundles – Default page, list of bundles
    • /system/console/configMgr – List of service configurations
    • /system/console/slinglog – Quick access to logging information and configs
    • /system/console/jcrresolver – Useful for testing sling mapping configurations
  • Tree-like navigation of the nodes in the JCR
    • /crx/de/index.jsp (CRXDE)

Gaining AEM Ground
As you make your way across the desert, you want to be sure that you’re doing everything possible to maximize your time. You also want to do that with regard to your AEM installation to ensure you’re getting the most out of your investment. When you read through documentation on getting started with AEM, you have the option of double-clicking a JAR file, which will start a local instance of AEM that you can play with; this is great for local testing but not so helpful for a headless server environment. As a rule of thumb when I want to work with Adobe Experience Manager, I have gotten into the habit of doing an unpack on the JAR file (java -jar /path/to/file/aem.jar -unpack), which will extract everything into a directory named “crx-quickstart”. This is an important directory; it is pretty much where all of AEM will live—think of it as AEM’s home directory. This directory can be copied or moved and it will contain your entire AEM installation.

Starting or stopping AEM after an unpack is fairly simple as there are scripts located in the crx-quickstart/bin directory. You can either run these directly, or the better option would be to create a daemon service script that exports the values needed to start AEM, such as the JVM Options and run modes.

I have mentioned run modes a few times, so let me take a quick moment to talk about them here as there are really two types.

Installation run modes are applied the first time you run AEM and then fixed for the entire lifetime of the instance; they cannot be changed later on down the road.

  • Persistence Manager – Determine how data persists, i.e., crx2, crx3, crx3mongo
  • Role – Determines what responsibilities are assigned to AEM, i.e., Author or Publish
  • Samplecontent – installs Adobe’s sample Geometrixx content

Note: By default, samplecontent is added to the installation run modes. If you specify “nosamplecontent”, you will instead get a version of AEM that matches Adobe’s Production-Ready Checklist. What is obvious about this is that sample content and users are not installed, but it also causes some bundles from being installed that you cannot easily get back. For actual production environments this can be helpful, but in the non-production stacks it might make things a little difficult. For non-production environments, you may want to consider allowing sample content to be installed and then remove the Geometrixx packages after.

Customized run modes are applied on each startup and can be changed with a restart of AEM. They allow you to define run modes that can be used to identify the instance that’s running and modify its configurations accordingly. An example would be to set a “production” run mode, so you can identify configs that should only be applied to a production instance.

Conserving Water
In the desert, you have to know how to manage your water supply. The same holds true for “flushing” cached content in AEM. Now, I mentioned in the first article how information that is created on the Author is passed through the stack to reach the end user. This process can run through several workflows, but at the end of the day it is still all handled by replication events. I also mentioned a little earlier in this article that you want to ideally keep everything on Author and then replicate (push) that out to Publish instances. This holds true for the Dispatcher agents as well. You should be in the habit of configuring those nodes on the Author, even though they live under the agents.publish directory, and then push them to your pubs. Now, you might ask, “Why not just have the Author flush the cached content from the Dispatchers?” Well I am glad you asked—you see the issue with having the Author flush content that has just been activated is that sometimes it takes the Publish instances a moment to ingest that content. This is especially true if there are a lot of replication events happening. This then creates an issue where the Dispatcher is trying to re-cache that page but the Publish isn’t ready to render it, so you end up caching broken pages. Thus, you should have your Publish instances flush your Dispatchers in all cases but one.

What is that one case you ask? Another great question. There is a tool packaged with ACS commons called the “Dispatcher Flush UI”, which allows you to create pages that content creators can use to flush pages manually from the Dispatcher. This is safe to do from the Author, but you will need to make sure you enable a flush agent for each Dispatcher on your Author, and that you have the “Ignore default” option selected. This allows ACS Commons to send a flush request from the Author while normal activations will continue to use flush agents on Publish.

Scheduled Breaks
During your journey, you need to ensure that you’ve scheduled time for breaks. You also might want to schedule something of similar importance within AEM. I mentioned the importance of taking backups a little earlier, and if you’re wondering how you can trigger these on a schedule, then you are in luck. We can cover this in more detail later, but for those of you who are looking for a solution right now, when AEM triggers a backup it sends a ReSTful request to start the process. Knowing this can help get you started.

Speaking of ReSTful, calls I should also mention there are quite a few articles out there that cover different cURL commands that can be used with AEM, as such I will not cover those commands in this article. I will however mention something that may prove useful: Adobe Experience Manager is built on a ReSTful framework, which means anything you can do through a console or the CRXDE you can make a ReST call to perform the same action. Although finding exactly the calls that are being made can sometimes be difficult, more often than not they are pretty simple to determine using this method I have picked up along the way. Chrome’s debug tool has this nifty option to copy any request from the network tab as a cURL. This means you can click the Preserve Log box, go into a local AEM instance, make your request using the CRXDE, and then see the result of that request in Chrome. You can then select that request and copy as cURL. Viola! You can now make the same request through the command line, shell script, or what have you.

We have now covered a bit of the basics talking about the Author environment, and getting the Author server started up. Although we could dig even deeper into the Author, this should help you to better understand how Author fits into the AEM stack. That’s two articles down and more to come—make sure to subscribe to the blog to stay tuned. We will be covering the Publish environment next as we continue to traverse the AEM landscape.

A Year in the Desert of AEM: The Publish

0
0

05287_AEM_A-Year-in-the-Desert-of-AEM_Publish
You’re tired, thirsty and maybe a little cranky. I get it; Adobe Experience Manager can be a little frustrating and overwhelming. It might make you feel like you have been left in a desolate wasteland with nothing but your wits and a half empty—or half full—canteen. Never fear. With these articles you will have another tool in your belt to make it across the desert. Today we will cover the Publish server in AEM; and as mentioned in my introductory article, the Publish server is the workhorse of AEM. What do you mean you haven’t read my first two articles? The first article covers some basics about Adobe Experience Manager. The second article covers the Author server and its role within the AEM stack. I do sometimes reference back to those articles and It could be helpful to read them before moving on, but I won’t make you.

Just like the Author, the Publish also runs as a Java application; in fact, most of the information about setup and startup from the Author applies to the Publish as well (they even use the same jar). This means that the steps to get a Publish server up and running are going to feel like déjà vu. You will obviously want to use the installation run mode of publish, and the default port changes as well (Author :4502, Publish :4503). Other than those changes, you are looking at the same process. Let’s move on and learn more about the Publish instance.

The Desert Oasis – A Return to Familiar Ground
The Publish server is your return to an oasis during your journey as you’re well equipped for the task, having already set up the Author. The Publish server in the AEM stack is a render host and is the first way it differs from the Author instance. The Author pushes new content to the Publish server and it ingests that content. The Dispatcher sends requests to the Publish to be rendered and returned so it can cache and deliver them. The point I want to get across here is that the Publish is not starting these communications; instead it’s processing requests as they come in from the rest of the stack. Now, just because the Publish is zen regarding communication doesn’t mean it isn’t doing anything. In fact, most of the time the Publish will be the busiest of the two Java applications. It has to render all that code and process the logic you or the developers created and turn it into static content; i.e., HTML, CSS, JavaScript, etc. It also handles other tasks such as queries coming through the Dispatcher. The Publish is also where requests to flush the Dispatcher originate. These requests to the Dispatcher are normally only triggered after content has been ingested.

The second difference is that the Publish does not have the Authoring UI. As such, making changes directly to the Publish server should not be done. Normally I am not going to tell you how to manage your stack; instead I will give examples and suggestions. For this I am just going to be blunt and tell you—do not create anything directly on the Publish server. The Publish server has its purposes in the stack; manual configuration and changes is not one of them. Instead, changes or config settings should be created on Author and then replicated to Publish. Remembering this will help you avoid situations where content or configs are mysteriously overwritten. I am going to cover a little bit about configs and touch briefly on those run modes again a little later on.

Scaling for Your Journey’s Load
Having regrouped at the oasis, it’s time to determine if you will need to bring on other resources to help with the load. As the Publish server normally deals with a larger load than the Author, it’s nice that it’s also easier to scale than the Author. In the Introduction article there was a graphic that showed the standard Adobe Experience Manager architecture we employ here at Axis41. If you refer back to that image, you will see that we have two Publish servers, which could just as easily be changed to three, four, or more depending on the load and needs of your project. As long as you remember to create a Publish agent on your Author, you can keep more than one Publish up to date and ready to ingest and serve content. Besides scaling for load, the other reason we recommend running with two or more Publish/Dispatcher servers is for higher availability. This allows you to load balance across different geographic locations. It also allows you to perform maintenance on one of the Publish/Dispatcher lines without reducing availability for end users. This same technique could also be used to have a disaster recovery option available as a hot standby.

Note: Scaling Publish servers, or creating a hot standby, may include additional costs for licensing and you should check with your Sales Rep to make sure you are in compliance.

The Refetching Mirage
In my Author article, I talked a little bit about letting the Publish handle flush requests. There are really two types of flush agents available to you on the Publish—the flush and re-fetch agents. In simple terms, the flush agent sends a request to the Dispatcher to invalidate its cache, so on the next request the Dispatcher will get a new render from the Publish. The re-fetch agent sends a POST request to the Dispatcher that will delete the cache and then trigger an immediate re-cache event so that there is no extra wait time when that resource is next requested. The re-fetch agents sounds pretty great, however there is a cost associated with this agent. The major issue here is that the request made by the Dispatcher isn’t the same as a request made from a browser; this can cause irregularities when a page is cached. The re-fetch also triggers an immediate re-cache; if there are many resources being flushed, this can put a large amount of load on the Publish, creating a snowball effect and making the Publish slow down for all tasks.

The other agent you may see or want to use on Publish is the reverse replication agent. Remembering that the Publish is a render host, also means that it will not try to push content to Author, nor should it. This would appear to cause issues with user-generated content such as comments, reviews, etc., getting back to Author or the other Publish servers. AEM, therefore, has the option to enable reverse replication. The Publish stores user-generated content in a special outbox. The Author periodically requests from the Publish anything in the reverse replication outbox, and pulls that content in. The Author can then pass this content through an approval workflow, if needed, and replicate the user-generated content to the other Publish instances.

Publish Configs along Your Route
Now that we’ve talked about scaling your load and visited the refetching mirage, it’s time to cover what the last leg of your Publish journey will entail: configurations. We’ll begin by discussing configurations that normally you’ll only want configured on the Publish instance, or maybe you want them working differently on Publish. First, the way to make these configs only apply to Publish is by accessing those run modes we talked about in the Author article. Remember there are installation run modes, two of which are Author and Publish. This means you can use these run modes to identify which servers to apply the configs to. Adobe Experience Manager has a feature where if you place a directory named config. under the app/project directory, it will automagically apply any configs in that directory only if the run modes match. Armed with this knowledge, you can take it one step further and use multiple run modes, such as config.publish.production, which will only apply to a Publish server also using the production run mode.

So if you have settings that only apply to production, such as mail server settings for contact forms, then you can make sure that only applies in the right situations. Creating these config nodes can be a little bit of a challenge, but luckily for you there is a post right here on AEM Podcast that covers this process.

“Etc” Map Rules to Your Destination
The final configurations that you normally apply only to Publish are etc map rules, so named because of the default path by which they are found in AEM: /etc/map. Think of them as markers along your desert map.

These configurations are officially called Resource Resolver Mapping, and they allow you to rewrite hrefs on pages to strip out paths that you may not want exposed to an end user. A classic example is removing /content/sitename/en from links for SEO as well as security purposes. I am not really going to cover all the specifics of setting up etc map rules; instead, I will cover how to make etc map rules only apply in the same way that other configs do—by leveraging a sling OSGI configuration node inside of a run mode named config directory.
config

You will need to have a config node named “org.apache.sling.jcr.resource.internal.JcrResourceResolverFactoryImpl.sitename” created under config.publish.
config-node-name

Next you will need to add or modify a property on that JcrResourceResolver config, resource.resolver.map.location. Set it as a string, and then for the value enter a unique etc map path; I would suggest something like /etc/map.publish so as not to confuse it with anything else. What this does is tell the Resource Resolver that it should load its rules from the directory you defined.
property-on-JcrResourceResolver-config

You can then set up your etc map rules under that same directory and they will only apply to Publish servers. You can also take this one step further and create the JcrResourceResolver config under config.publish.production and create a map location of /etc/map.publish.production and have rules that apply only to a server that is both Publish and production.

Like the Author article, we really only covered the basics of the Publish server and its configurations. I hope this has shed some light into how the Publish server works and some of the customizations you may need or want to set up. Our next, and final, article will cover the DIspatcher; which for some may be the most frustrating of the servers to set up and configure. Make sure you subscribe and come back as we finish our journey through the desert of AEM, and finally make it out.

A Year in the Desert of AEM: The Dispatcher

0
0

05287_AEM_A-Year-in-the-Desert-of-AEM_Dispatcher

You know how sometimes, you get close to the end of your journey and it makes it feel like something short is something long. This will not be one of those cases as the last leg of this journey talks about the Dispatcher, and there is a lot to cover in a short space. For those of you who may have stumbled upon this article without reading the others in this series let me first say welcome. You are joining us at the tail end of our journey; a four part series about the Adobe Experience Manager infrastructure. To recap what you may have missed. The first article covers some AEM terms and basics, the second article covers the Author server, and the third article covers the Publish server. If you have no prior AEM knowledge it may be worthwhile to give those a look. It’s ok we will be right here when you get back. Civilization is near my friends. So sit down, strap in, and hold on, we’re taking our final ride.

What is the Dispatcher?
To start, the Dispatcher unlike the Author and Publish server is not a Java application. It is actually an httpd module, and it’s proprietary. The Dispatcher pulls double duty in the AEM stack, it serves as both a caching server, as well as something similar to a Web Application Firewall (WAF). When it comes down to it the Dispatcher is similar to other Apache run web servers, you can use Apache mods to change how traffic is handled and how the static content is served. The part that is special is the Dispatcher handler which eventually is passed the request and then it goes to work. The Dispatcher first checks the cache root, which should be the same as the DocumentRoot (more on this later). If the file being requested is not cached or has been marked as invalid, then the Dispatcher will connect to a Publish instance and pass along the request to be rendered. Once this is done the Dispatcher takes the rendered asset, saves it to the cache root, and then serves this content to the end user.

The high level of how the Dispatcher works is fairly simple to understand, however once you start digging into the configuration and customization of the Dispatcher it may seem a little overwhelming. Adobe has quite a bit of documentation on the Dispatcher, such as explanations and examples of the Dispatcher’s configuration. If you are unsure what something does, this documentation may shed some light on it. I am dropping this disclaimer here so I don’t have to state it multiple times below, the configurations I show you are how we at Axis41 do things, your situation or needs may vary. With that said hopefully this will get you on the right path to success. Like the other articles we are going to cover a base level configuration as well as some added tips.

Dispatcher Install
As the Dispatcher is a module there is some installation that is required, as a general rule you should try and use the latest version of the Dispatcher. The Dispatcher comes packaged as a archive and can be found for download here. As we use a linux derivative of RHEL I am going to use that as my example, obviously some of the same information will apply even if you are running a different platform. The way the Dispatcher is packaged you can drop the tar.gz file into the http directory and extract it from that location. This will add Dispatcher specific files to your conf directory and a few files at the httpd directory level. You can then move the dispatcher.so into the modules directory. For ease of use I would then recommend creating a symlink between the versioned .so and mod_dispatcher.so. Once this is done you can then look at the files in the conf directory. One of those files httpd.conf.disp2 is an example httpd.conf file that contains the Dispatcher IfModule configuration.

You have a few options here, the first option is my strong recommendation, as it can save you a lot of frustration later on. I will also mention a couple other ways this could be handled, but seriously just chose number one.

  1. Create a custom conf file with just the Dispatcher LoadModule and IfModule inside and then have Apache include your custom conf file. This is fairly easy to do, and has the added benefit that you don’t need to go mucking about in your httpd.conf file.
  2. Copy out the LoadModule and IfModule lines from the above mentioned httpd.conf.disp2 example file and move those lines into your existing httpd.conf file.
  3. Replace your existing httpd.conf with the example file. If you have a vanilla Apache installation is the only time I would even consider this, and even then I would still chose option one.

Once you have decided how you are going to implement the Dispatcher configurations you can start customizing. To start you off I would highly recommend setting DisspatcherUseProcessedURL to “On”, this allows you to modify the request such as with mod_rewrite and then have the Dispatcher use the updated request.

Dispatcher.any
If you thought installing the Dispatcher and setting up the IfModule configuration was all that is needed, then I have a surprise for you. There is another more comprehensive configuration file called dispatcher.any, and no “any” is not a typo. This file is mainly responsible for how the Dispatcher will behave. Inside this file there are sections that are each responsible for a different part of this behavior. Again in the interest of time I am using the default dispatcher.any file which is covered in Adobe’s documentation. What I am going to cover is some of the changes you might want to make as well as some of the configurations to pay specific attention to. The /website section is normally where you will start to configure things, you can even setup multiple websites each using the /virtualhosts section contained within to tie specific domains to specific Dispatcher configurations, just be aware that once you start down that road things can become tricky very quickly. We are going to stick with using one website using a wildcard for all domains. The /clientheaders section by default uses a wildcard and I would recommend specifying the headers you expect the Dispatcher to see.

/renders
This section sets up your Publish backend that the Dispatcher will connect to. The Dispatcher does have the ability to set up connections to more than one Publish backend, which will allow the Dispatcher to load balance between the Publish servers. If you are only using one Dispatcher this may be the way to go, however if you use two Dispatchers and two Publish servers I would not recommend setting connections to both Publish servers and here is why. In theory having the cross talking between two Publish and two Dispatchers seems like it would be a good thing. In practice you can run into an issue where the Publish server tells the Dispatcher to invalidate a page, then that Dispatcher, because of load balancing, requests the page from another Publish server which has not yet finished ingesting the content from Author. This then results in either out of date content, or content that is cached with errors on page. In essence you can end up with bad cache on one Dispatcher, and then to further complicate the matter because of load balancing it can be difficult to diagnose which Publish served up the bad content. This is why we recommend using a one to one Publish to Dispatcher configuration.

/filter
This section is where the WAF behavior comes into play. It is fairly straightforward if you look at the rules in the default file. The concept is to deny everything first and then whitelist only the requests that make sense for your project. This section is also setup so that the last rule wins. This means if you place broad rules near the bottom, those rules may expose or open up paths that you previously meant to restrict. These filters can be expanded to address each part of the http request; allowing you to move away from glob and wildcards to a more secure multi filter rule. For example using { /type “allow” /method “GET” /url “/content*” } tightens security when whitelisting the content path by only allowing GET requests to those paths. You can also do a similar filter to only allow POST to a specific servlet { /type “allow” /method “GET” /url “/bin/customservlet” }. If you are using a version earlier than 4.1.9 these expanded filters are not available and I would strongly recommend upgrading to a more recent version of the dispatcher.

Caching
The /cache section and caching on the Dispatcher in general really deserve to be singled out as they are one of the major functions of the dispatcher. Let’s start by talking about caching in general and then we will talk about the /cache section of the dispatcher.any file. First it’s important to point out that anything that is not cached or not able to be cached is sent back to the Publish server each time it is requested. As a general rule you want the Dispatcher to cache as much as possible (markup as well as content). This not only removes excess load from the Publish servers, it also greatly speeds up the delivery of content to the end user. The Dispatcher by default will try and cache everything with a few important exceptions.

  1. Missing extensions – If the requested path is missing an extension such as .html
  2. Method Type – If the method is not a GET request
  3. Errors – If the http response from the Publish server contains an error code, it will not be cached
  4. Http Header – If the response.setHeader (“Dispatcher”, “no-cache”); is used
  5. Authorized Headers – If the request contains authorized headers
  6. Query strings – If the request contains a query string
  7. Rules – If the request does not match any /rules defined under the /cache section of the dispatcher.any file

With the above list a few of these can be modified based on settings within the /cache section, which I will cover now. I also cover a couple other important properties to pay attention to in this section.

/allowAuthorized
This property allows the Dispatcher to cache content even if there is authorization being used in the headers, most of the time you would not want this behavior as you would not want content that requires authentication to be served to someone who is not authorized. If you do intend on using authorized headers but you still would like the benefits of cached content there is the option of using /auth_checker which may not be a configuration that was included with the default file.

/ignoreUrlParams
This property can allow you to cache query strings. It basically allows the Dispatcher to treat the query string as though it were a unique path to be cached. Even though this option is available to you, I would recommend trying to avoid query strings as much as possible, and instead use a selector such as page.string.html this still allows you to modify what is cached when a different string is provided as a selector. If you end up just using a query string for something like analytics tracking, which is fairly common, you can instead use something like mod_rewrite to leave the query in the URL but drop the query with a pass through to the Dispatcher.

/rules section
By default this section is set to cache everything with a wildcard, if for some reason there is a specific resource you do not want to allow to be cached you can create a rule under this section that denies that behavior.

/docroot
This property sets where the dispatcher will cache its assets on disk. This should end up being set to the same path as the Apache DocumentRoot. This sets Apache to treat the cache created by the Dispatcher as normal static assets of a website.

/statfileslevel
This property sets how deep in the directory structure the .stat files should be created, 0 being the /docroot cache path

/serveStaleOnError
This allows the Dispatcher to serve files from its cache even if they have been invalidated in the event that the Dispatcher is not able to reach the Publish backend.

Flushing
If you remember from the other articles we have talked a little bit about flushing and the different types of flushing. As the following configurations go hand in hand, I have decided to include them in this section. We will start out by talking about the easier concept which is /allowedClients this configuration is near the end of the Dispatcher.any file and it controls who, or what hosts/IPs, are allow to send flush requests to the Dispatcher. By default this section comes commented out which if left unchanged would allow anyone to send a flush request and clear your Dispatcher’s cache, which could be used as part of a denial of service attack. I strongly recommend you set this section to deny all and then only allow the hosts or IPs you trust, such as the Publish and Author servers.

Now we are going to talk about .stat files. In my opinion this method of cache invalidation is not very efficient, and it can be a little difficult to wrap your head around. So I will try to keep it as simple as I can. First off I mentioned the /statfileslevel just above, which determines how deep the .stat files are created. The .stat file itself is a zero byte file that the Dispatcher uses to help it determine if cached files are invalid. To do this when a file is requested the Dispatcher checks the last modified date of the .stat file as well as the cached file; if the .stat file is newer than the cached file the Dispatcher knows the cached file is stale. The Dispatcher will then check the /invalidate section, and anything stale that also matches a pattern in that section is then considered invalid by the Dispatcher, and requested again from the Publish. I will use an example to help explain what I mean.
statsfile1

Let’s say you have a site under the path /content/mysite/en and a content author updates the contact.html page located at /content/mysite/en/about-us/contact.html. When that page is activated the Dispatcher receives an invalidation for that same path located in the docroot, this file is then automatically considered invalid. Next for every level the Dispatcher traverses to reach the contact.html page it would touch a .stat file up to the number you define under /statfileslevel. So if you have that property set to 4, remembering that 0 is the root, then it would touch the following .stat files:
/.stat
/content/.stat
/content/mysite/.stat
/content/mysite/en/.stat
/content/mysite/en/about-us/.stat

Looking at the default /invalidate section rules we see { /glob “*.html” /type “allow” }. This means any .html file is allowed to be flushed, so any .html file located in the same directory where a .stat file was touched is now considered invalid by the Dispatcher. In our example you can see this would be the .html pages under /content/mysite/en/ that are mainly affected. Now if this only affected those files that would be one thing, however there are more files which will also be considered invalid. If the Dispatcher doesn’t have a .stat file at the same level as the page that was requested, it will traverse up the directory structure to find the nearest .stat file.
statsfile2

So, keeping with the example above if the next request was for /content/mysite/en/about-us/investors/how-to-invest.html the Dispatcher would see there is no .stat file under /content/mysite/en/about-us/investors/, as that would be at level 5. So it would then look for the nearest .stat file available, which in our case is (/content/mysite/en/about-us/.stat), and use that as its .stat file when determining if it should serve how-to-invest.html directly from cache or request it from the Publish again before serving. In our example this would mean the Dispatcher now also considers how-to-invest.html invalid. This would be the same for any other document that lives in cache under the /content/mysite/en/about directory. No matter how deep they are, they will always refer back to /content/mysite/en/about-us/.stat to see if they are invalid or not.
statsfile3

I should also mention the flip side, if you had a page /content/mysite/en/blog/post1.html, for example, this would not be invalid as its nearest stat file would be /content/mysite/en/blog/.stat which was not touched by updating /content/mysite/en/about-us/contact.html. You should put serious thought into your configuration when it comes to cache invalidation. Depending on your site structure, /statfileslevel, and /invalidate rules you could end up wiping out large sections of your cache by accident with a simple page update.

Apache Config
When it comes to the Apache configuration, I am not really going to cover much in the way of Apache itself. Suffice it to say that this is an Apache server that runs a custom Dispatcher handler for serving content. Like I mentioned above this means that most of the configurations you might be used to with Apache will still apply. What I am going to cover here is some configurations you can use to make the Dispatcher work a little more smoothly.

First off we use a vhost configuration block and override the Apache DocumentRoot property as well as set the Apache handler to allow the dispatcher module to take over for serving content.

DocumentRoot /opt/aem/dispatcher/docroot
SetHandler dispatcher-handler

When we covered the Publish server we talked about setting up etc/map rules, now we will talk about the Dispatcher side of that coin. For this we would be using mod_rewrite on the Dispatcher in combination with etc map rules to strip the /content/mysite/en path from URLs. To do this you could use something like I have listed below, added to that same vhost configuration I talked about above. This will add the content path back onto the request behind the scenes before the Dispatcher processes the request.

RewriteRule    ^/$                               /content/mysite/en.html      [PT,L]
RewriteRule    ^/index.html$               /                                          [R=301,L]

RewriteCond   %{REQUEST_URI}    !^/content
RewriteCond   %{REQUEST_URI}    !^/etc
RewriteCond   %{REQUEST_URI}    !^/bin
RewriteCond   %{REQUEST_URI}    !^/lib
RewriteCond   %{REQUEST_URI}    !^/apps
RewriteCond   %{REQUEST_URI}    !^/mysite
RewriteCond   %{REQUEST_URI}    !^/en
RewriteCond   %{REQUEST_URI}    !^/dam
RewriteCond   %{REQUEST_URI}    !^/assets
RewriteRule    ^/(.+)$                         /content/mysite/en/$1         [PT,L]

The other mod_rewrite you can do in the vhost file, that might make your life easier, is mapping your DAM paths. The above covers content paths, but anything under the DAM might have a path like /content/dam/mysite/. My suggestion is to setup etc/mapping to have this path changed to something like /assets/. Oh, so you noticed that I excluded /assets in my block above. Well that was intended, as now you can setup a rewrite rule to handle DAM assets.

RewriteRule    ^/assets/(.+)$                         /content/dam/mysite/$1         [PT,L]

In the immortal words of Porky Pig, “Th-th-th-that’s all folks!”. I know that this all can seem like an insurmountable task when you first start out, but hopefully these articles will speed you on your way. Now you have earned yourself a “I survived the desert of AEM” t-shirt, if such a thing existed. Make sure you take a look at some of the other articles available on this site, and as always if you have questions or comments feel free to email info@aempodcast.com. Thank you for taking this journey with me.

Do not rely on Online Compaction in AEM 6.x

0
0

05287_Do-not-rely-on-Online-Compaction-in-AEM-6x

Most of you should probably already be aware that there are some challenges in AEM 6.x with repository disk growth. While this has improved marginally in more recent releases, it’s absolutely vital to a healthy Adobe Experience Manager stack that offline compaction be performed regularly. For our Managed Services clients, this is a service our Systems Engineers take care of, including watching the growth rates and knowing what kind of schedule a given environment needs.

Old hat, right? Everyone knew about this? Great. However, there is one piece you MAY NOT know about that we feel it’s important to notify people of.

Within Adobe Experience Manager itself, there is a JMX agent that implies online compaction is available. In fact, you might find some people using this in conjunction with the occasional offline compaction; however, Adobe has stated that this “online compaction” is unsupported:

Q: What is the supported way of performing revision cleanup?

A: Offline revision cleanup is the only supported way of performing revision cleanup*. Online revision cleanup is present in AEM 6.2 under restricted support.”

This phrase “restricted support” is defined in the AEM documentation to have the following meaning:
“To ensure our customers project success, Adobe provides full support within a restricted support program, which requires that specific conditions are met. R-level support requires a formal customer request and confirmation by Adobe. For more informations, please contact Adobe Customer Care.”

From experience, we have found that online compaction will not fully compact the store, and sometimes has been know to corrupt the data store. Although the JMX agent can still be found in Adobe Experience Manager, until Adobe has adjusted their position on it, we would recommend against using this on your production instances.

 

*emphasis mine

Maven Build Profiles and the Sling JCR Install Service

0
0

05287_Maven-Build-Profiles-and-the-Sling-JCR-Install-Service

tldr;
Doing both autoInstallPackage and autoInstallBundle at the same time can cause conflicts in the OSGi/Felix/System/Web Console as it installs the jars. JCR config and install folders will not work correctly when the conflict happens. Just do autoInstallPackage. If there is a conflict, there will be folders to mark progress under /system/sling/installer/jcr/pauseInstallation—delete them, and then things should work.

I have been seeing this issue on some local environments, and recently we had issues on a customer’s servers that are being built by bamboo. In our builds, we have zips and jars. The zips go into the JCR and the jars go into the OSGi. autoInstallPackage triggers the content-package-maven-plugin, which picks up the zips and throws them into ${crx.serviceUrl}/crx/packmgr/service.jsp. Similarly, autoInstallBundle triggers the maven-sling-plugin, which picks up the jars and throws them into ${crx.serviceUrl}/system/console/install.

So autoInstallPackage is to zip, JCR, and packmgr, as autoInstallBundle is to jar, OSGi, and system/console.

One of the zips in most projects, here at Axis41, is called bundle-install. It embeds the jars from the project bundles, puts them in a zip package, which then gets installed to the JCR at /apps/[project]/install. The package should also include the OSGi configs in the /apps/site/config.[runmode] folders. The Sling JCR Install Service listens to those two folders, takes the jars and configs, and installs them into the OSGi container. We use this strategy because we have found that having the entire project build to zips to feed into the packmgr gives us more consistency and agility when moving code around.

If the jars in the bundle-install zip try to install at the same time that ${crx.serviceUrl}/system/console/install is catching the jars, there will be a conflict and the installation will enter a paused state, marked by nodes under /system/sling/installer/jcr/pauseInstallation. In this paused state, the Sling JCR Install Service stops listening to the config and install folders. The runmode dependent configs you build in the project will not get applied to the OSGi services, and new jars trying to get installed through the install folder will do nothing. To return the JCR Install Service to normal operation, delete the nodes under /system/sling/installer/jcr/pauseInstallation.

To prevent this from happening in the first place, always install bundles via the bundle-install content package by using the autoInstallPackage profile. Make sure your automated builds are doing that too. While you’re working within a single bundle, autoInstallBundle is meant to provide a way to more rapid deploy/test the bundle, but it shouldn’t be used in combination with autoInstallPackage. Using both profiles at the same time to ensure the bundles install is usually a result of improperly configured bundle-install pom, which needs both a dependency and an embed block for each of your bundles. If you rely on manual code deployments through zip files and the Package Manager then the process of deployment should not have any issues.

Why are you in the Publish server on Prod?

0
0

05287_Why-are-you-in-the-Publish-server-on-Prod

I wrote a terse article last year about the fact that no one should ever need to be in CRXDE in Production. And they shouldn’t be! I kinda skated over another fact related to this that I want to address. You shouldn’t be on your Publish server, especially not in Production.

As Tyler mentioned in his article series about the entire Adobe Experience Manager infrastructure, “the Publish server is the workhorse”. It shares a similar setup to the Author server, as it also runs as a Java application. Most of the information about setup and startup that were done to the Author server also applies to the Publish server (including using the same jar file). You just use the installation run mode of “publish” and the default port changes as well.

The difference is that Publish is responsible for rendering all the content that is meant for consumption by the front-end user. As Tyler said, “it is a render host”. The nature of the Publish server is to handle serving up content and markup for caching to the Dispatcher. It takes all that and generates static data that is delivered to the browser. The Author server is where you input content using the tools, components, and templates that developers build. But until they hit that Publish (activate) button it is just staged content. Its job is to communicate between the Author and the Dispatcher, not to do actual authoring or configuration.

One of the reasons you shouldn’t be on the Publish server is server consistency. Most likely you will have more than one Publish server. The concern is that if someone were to go to one of the Publish servers to make an adjustment to the code, content, or configuration, they might forget to make that adjustment to the remaining servers as well. If you make whatever change is needed on Author and then replicate it, then all the Publish servers stay consistent. It’s not tenable for someone to have to hit each publish instance to make whatever change they need. You are ignoring the way that AEM was designed in the first place.

Another reason to avoid this is from a scaling perspective. Having all the logic, configurations, code, and content live on the Author server ensures that, when you scale up, everything gets replicated out to the Publish server. So as long as you have your replication properly set up you won’t have to worry about making those changes to a new Publish server, you can just replicate it from Author again. Without that, you have no guarantee.

Lastly, I know it sounds pessimistic, but if you are making changes directly on a server, rather than in a repo, there is a high probability that you are going to forget to get it into your repo. Then the next time you deploy your code it will get overridden and you will be left wondering why something is broken that was working before—all because you wanted to make a “quick fix”.

Someone might whine and say, “but something is wrong and this will be faster, just let me make this small change”. I would argue that your real problem is that something is not configured correctly or you have a blocked replication queue and that your real problem is how Author is communicating with Publish. Getting on the Publish server only resolves a symptom and isn’t the cure. Don’t make your implementation of Adobe Experience Manager dependent on people needing to access the Publish server. Don’t do it!


AEM Spark: Install/Stop/Start CRXDE Lite in AEM 6

0
0

05287_AEM-Spark_Install_Stop_Start-CRXDE-Lite-in-AEM-6

Should you be running CRXDE Lite or not? I think we all agree that the IDEAL situation is to have this disabled. However, there are times where you just really feel like you need to debug that one problem by looking something up in the CRXDE Lite. Although Axis41’s Managed Services team never debugs in production, we will occasionally download an Adobe Experience Manager instance locally to do some debugging. In such cases, we figure why not turn CRXDE Lite back on? It will likely save the Systems Engineer some time, and any change has to be deployed through the immutable infrastructure process anyway.

When looking at your error.log, if you try to load the CRXDE Lite while it is disabled, you will see an error message that looks something like this:
org.apache.sling.engine.impl.SlingRequestProcessorImpl service: Resource /crx/server/crx.default/jcr:root/.1.json not found

If this is a new instance 6.1 or later, and it was initialized with the nosamplecontent runmode, you must first create the missing SlingDavExServlet component:
curl -u admin:admin -F “jcr:primaryType=sling:OsgiConfig” -F “alias=/crx/server” -F “dav.create-absolute-uri=true” -F “dav.create-absolute-uri@TypeHint=Boolean” http://localhost:4502/apps/system/config/org.apache.sling.jcr.davex.impl.servlets.SlingDavExServlet

Now we may need to start the bundle. In any 6.x instance with the SlingDavExServlet component created, to START CRXDE Lite, use:
curl –user “admin:admin” -X POST ‘http://localhost:4502/system/console/bundles/org.apache.sling.jcr.davex’ –data ‘action=start’

We’re looking here for a JSON response that shows the bundle as started:
{“fragment”:false,”stateRaw”:32}

On the off chance that someone started this in your production instance, it’s just as easy to stop it. In any 6.x instance with the SlingDavExServlet component created, to STOP CRXDE Lite, use:
curl –user “admin:admin” -X POST ‘http://localhost:4503/system/console/bundles/org.apache.sling.jcr.davex’ –data ‘action=stop’

And confirm that the JSON response shows the bundle as stopped:
{“fragment”:false,”stateRaw”:4}

If you have a better solution to this problem that you’d like to share, contact us at info@aempodcast.com

Solving the dissonance between AEM Dispatcher and Publish

0
0

Solving-the-dissonance-between-AEM-Dispatcher-and-Publish
Part of the beauty and attraction of Adobe Experience Manager is its system architecture—the Author, Publish, and Dispatch instances. Let’s look at a high-level overview of how these things work together. The Author instance allows content to be authored and updated easily and efficiently. The content is then activated and replicated to the Publish instance so web pages are always teeming with the newest content, ready for public consumption. The Dispatcher instance is a cached version of published content so when users hit a website, the content is readily available at increased speeds. The Publish server also lets the public-facing Dispatcher know when its content is out of date and needs to be re-cached on a content path. When a user visits a page with old, invalidated content, that page request will prompt the Dispatcher to fetch new content from the Publish instance and serve that content to the user as well as cache it. The next person to visit the page will receive a fast, updated web page.

It’s simple, right? Author new content –> activate –> publish updates –> Dispatcher is informed it has old content -> Dispatcher re-caches new content when page is visited. It really is a great system, but it isn’t without complex and interesting challenges, depending on the structure of your site and how content is being used.

The problem we faced:
What happens when you have content on one page relying on content from another page? In one particular project, we worked on a complicated site architecture where pages used information from other related pages to populate certain content. For example, Page A is related to Page B for specific content it displays. When the related Page B is updated and activated, AEM does its process and Page B is updated on the Publish instance and eventually gets updated on the Dispatcher. But Page A is relying on that content and does not know that Page B has been updated. Page A does not get re-cached or invalidated and displays old Page B content. There may be additional cases, where Page B refers to content from other pages as well. As you can imagine, this created a huge problem. This system of speed and accuracy was suddenly only fast and definitely not accurate. How did we get related content to stay updated?

Our solution:
We used a combination of an AEM workflow launcher and a custom Java class, implementing the WorkFlowProcess class. Let’s first look under the hood of how this site architecture works. The relationship is that Page A contains a property that refers to the path of Page B. There may also be several other pages: Page C, Page D, etc., that refer to and point to Page B for information and content. If we can collect all of these paths, we can do a request to the Dispatcher, telling it to invalidate and re-cache all of these pages. Whenever a page was activated, the workflow launcher kicked off the custom workflow and executed a series of JCR queries to check for the path of the recently activated page (Page B), which we got through the payload of the WorkItem Java class.

public class RelationalCacheBusting implements WorkflowProcess {
 
	public void execute(WorkItem item, WorkflowSession session, MetaDataMap args)
     	   throws WorkflowException {  
 
WorkflowData workflowData = item.getWorkflowData();
String triggeredPagePath = workflowData.getPayload().toString()
 
…}

If Page B’s path existed in any properties in the JCR nodes of other pages, it would be related to the activated page. We conducted a check to see if Page B refers to any other additional pages. The site architecture allowed us to have an idea of which page component types to check for in our query, narrowing down where to look for relationships, but also largely relying on knowing where to look based on the page component type of the activated page. For example: one page component type—the Map Modal—will always refer to another page component type—the Location—that provides information about a physical location or an address. We knew if this address page was modified and activated, we needed to look in the pages that referenced the address pages.

We collected all the paths of pages that referred to Page B and all the pages that were referenced by Page B and did a request to the Dispatcher, telling it to invalidate all of those pages and then re-cache them.

Now, pages can be activated without worrying about the repercussions of pages relying on each other for their content! Even though it was a decent effort up front, this solution has been a big help to keep the site up to date and fresh, and has taken a big load off of the content authors.

Best Practice: Treat OSGi Configurations as Code

0
0

Best-Practice-Treat-OSGi-Configurations-as-Code
The Question
A few months ago, one of our customers who self-manages their Adobe Experience Manager stack was doing some digging in the filesystem underneath the crx-quickstart folder. They noticed a correlation between the filenames found there (specifically, under crx-quickstart/launchpad/config and the changes they would make in the Felix Console at system/console/configMgr to configure OSGi bundles.) Putting two and two together, this enterprising SysAdmin asked me:
“If I pull those out and drop them into a fresh instance and restart, will that ‘configure’ [the bundle] for me? Is this the best way to accomplish this and similar tasks? Are there API calls I can make to the site to configure these types of things? I’m trying to gauge what it’s going to take to stand up a fully functional instance without having to touch it every time. It seems awfully cumbersome to track down these files after every configuration piece. Do you have any pro-tips?”

Our Answer
While it was awesome that this guy found the correlation, we were quick to reply that we do NOT consider managing these text files to be an ideal way of configuring OSGi services. The better solution, we feel, is to put these configurations into your source control such that they are created as sling:osgiConfig nodes inside your JCR. There are two solutions for that.

Setting up the Package Structure
The short answer is to create the nodes directly with your IDE under jcr_root/apps/myproject/config in one of the existing modules.

Here’s an asciinema recording of me looking at such a setup on my own filesystem. However, Systems Admins are frequently not Adobe Experience Manager Developers, so it’s a lot to expect them to know/remember the directory structure and XML syntax for these configuration files. An easier way to create these things is by making the appropriate node in a CRXDE Lite running locally, and then using VLT (or CRXDE Lite’s Package Manager) to export the node structure and send it to the developers for incorporation into the code repository.

How Many Settings Could a Sysadmin Set If a Sysadmin Could Set Settings?
When doing it via this method, I sometimes begin by going to /system/console/configMgr and finding the service I want to configure. Clicking on the service in this screen opens a dialog.

Here, by way of example, is the dialog for the Apache Jackrabbit Oak Default Sync Handler:
dialogfortheApacheJackrabbitOakDefaultSyncHandler

In the CRXDE Lite, make a new node under /apps/ /config, of type sling:osgiConfig.

The node’s name will be based on the PID found at the bottom of the configMgr dialog. If the service being configured is a factory (as Apache Jackrabbit Oak Default Sync Handler is), then we will append .config. to the”Factory PID” instead.
FactoryPID

When Felix creates these nodes for you, it will put a UUID in the space, but this can really be any distinct value you choose—I usually like to choose a more meaningful name so I don’t have to remember UUIDs. This .config. is used because, as a Service Factory, there can be many distinct configurations of the same service living side by side; for example, we may want a different one per site.

Here’s what the dialog looks like CRXDE Lite:
identifierconfig

For each configuration value in the dialog, we will create an appropriate property on this new sling:osgiConfig node. The name of the property will be the name in parens at the end of the documentation string:
slingosgiConfignode

The type of the property will depend on the value; you should always refer to the API documentation for a given service the first few times you configure it, but after a while you start to notice a few patterns between the datatypes of service properties and their representation in the OSGi Configuration Manager. For example:

  • checkboxes are represented as a Boolean
  • simple integer values (e.g., user.membershipNestingDepth in the above) are of type Long in the service
  • pretty much everything else is a String

Also, pay attention to the little +/- buttons along the right edge of some inputs; where these appear, you should select the “Multi” toggle:
plusminusbuttons

multitoggle

When you have “Multi” selected, hitting “Add” will open a multi-value dialog. Input the appropriate values (in this specific case, there are none to enter, so we leave the initial box blank) and hit OK.
multi-valuedialog

Here’s what the completed sling:osgiConfig will look like:
completedsling-osgiConfig

Save your work and use the “vlt” command-line tool to export this. Here’s an example invocation using the default password of “admin” and connecting to an instance running on localhost:4502:
vlt –credentials admin:admin export -v -t platform http://localhost:4502/crx /apps/myproject somedir

That will create the same directory structure you saw in the asciinema above (it is, in fact, exactly how I created that structure.)

Now, your OSGi configurations can be moved into your change management process, giving better repeatable results, and moving us further down the pipeline to Infrastructure as Code. Let me know if you have any questions about any of the above!

A Year in the Desert of AEM: An Introduction

0
0

05287_AEM_A-Year-in-the-Desert-of-AEM_Intro
Let me start with a brief introduction both of myself and the purpose of this series. When I started my new position as a burgeoning Systems Administrator, I was told I would be working with Adobe Experience Manager (AEM, then called CQ), a product I had never heard of. I had to use Amazon Web Services (AWS), a cloud platform I had never worked with before. To say I felt enormous pressure to grow and perform quickly would be an understatement. The vast AEM environment felt nothing short of a desert wasteland, and I was being called to navigate. On top of this, there was quite a bit of standardization and automation that needed to be hashed out.

Thankfully I wasn’t completely alone; I had a new coworker who had been stranded in this wasteland in much the same way I was. There was also a team lead who was eternally buried behind the workload that my coworker and I had come to help tackle. I first started conceptualizing this series of articles after my first year working with AEM, thinking to myself, “What are some of the things I wish I had known from the start?”

That said, the purpose behind this series of articles is as an introduction to the administrative side of AEM. I will also impart some of the information I have picked up along the way. I will be splitting the remaining articles up as follows; Author, Publish, Dispatcher. Each of these articles will cover different pieces of information regarding the AEM stack; but before we venture too far from civilization as you know it, we need to prepare for our journey by covering some basics.

singleAPD

You see, I realized as I started writing up information about the different environments that there is quite a bit of other introductory information on AEM in general that might be helpful to point out. For example, sometimes you may read/hear references made about the Author environment; this can get a little confusing since we typically think of our environments in terms of “production”, “pre-production”, “development”, etc. “Author” is just one specific responsibility an instance can be assigned in AEM. So we will put a pin in the environments/responsibilities and come back to those later.

The Desert of AEM
The AEM landscape is nothing short of extensive. Like a desert, which is enormous in size and difficult to navigate, this robust content management system with integrations to the rest of the Adobe Marketing Cloud takes time and research to properly cross. AEM is built around a few open source projects with some proprietary code to hold it all together. We at Axis41 have found that AEM, due to its size and complexity, is many different things to different audiences. When looking at it from the SysOps point of view, we usually focus on two specific conceptual models: how it is delivered as a piece of software, and how it executes as a platform.

Let’s dive into the technology a little bit more. AEM has several layers for its Software Delivery Model, like an onion; at its core are the implementations of the OSGi (Apache Felix) and the JCR (Apache Jackrabbit). These are then connected with Apache Sling, which presents some added features—primarily a RESTful Framework, scripting engines, and an authentication layer. This is then wrapped up with Adobe’s CRX, which adds some proprietary features such as the Author/Publish model, replication support, and tools for management and development, just to name a few. The next layer is then the actual Adobe Experience Manager; this brings with it additional management tools for Campaigns, Websites, Assets, Tags, and Workflows.

Moving on we will take a high-level look at the execution model for AEM. The OS executes AEM as a Java application that will run in one of two modes, Author or Publish. Author is the main interface that content creators and developers will interact with. Publish is the “work-camel” of the AEM suite; it takes all the dynamic content and generates static data ready to be delivered to browsers. As AEM is a Java application, it also kicks off the JVM with the flags you have defined. The JVM executes Felix (OSGi), which in turn executes Jackrabbit (JCR), Sling, and the WCM.

Something I have noticed, especially with production environments, is that AEM tends to struggle if you allocate less than 2GB of memory to the JVM. Also, the JDK and Java version you use matters. For AEM versions earlier than 6.0 SP2, you will not be able to use Java 8, and OpenJDK is unsupported.

Planning Your AEM Expedition
Before undertaking your desert excursion, you ought to be certain that everything is in order, like the amount of food and water that you have and the location of various checkpoints along your way. You also need to know how AEM communicates to the other servers in the stack ahead of time. It is important to note that the information I am providing is the default and recommended settings. These settings can be changed, but you really should have a very good reason before you do so, if for nothing else to avoid confusion later on. The image below shows the various security zones and the ports AEM uses, which will need to be whitelisted.

AEMsecurityzoneandports

In a standard setup, you would have your content creators accessing the Author over port 4502 from an internal zone (or possibly through an Author-facing Dispatcher). Then you would have a zone for the Publish, which would be opened on port 4503 to communication from the Author and Dispatcher. Lastly, you would have a zone for the Dispatcher that allows communication on port 80/443 from the Author, Publish, and either the outside world or in a high-availability case from the Load Balancer.

Some additional information that you may want to be aware of is that the Publish server has a passive role—meaning it does not request information from either the Author or the Dispatcher. The Author will either push changes to or pull updates from the Publish. The Dispatcher either requests data from or sends data to the Publish. The only outside communication the Publish initiates is a simple request letting the Dispatcher know its cached content is out of date. So the Publish is really just a go between pulling double duty; first as rendering host, and secondly as a content buffer allowing content creators to make changes without them being viewed by the general public.

The AEM Caravan
Now that your travels have been mapped out, it’s important to know what your days will look like. Similarly, it’s imperative to understand how normal AEM operations work from day to day. Although this next part might sound like it’s straight from Abbott and Costello’s “Who’s on First” skit, it will give a good overview to use as a reference later on.

A content author signs into the Author instance and makes updates to a site page. This is then activated and can trigger a workflow for the content to be reviewed by another party. Once the new content is approved, it is pushed out to the Publish instances in the stack. These Publish instances, after ingesting the changes, then send an invalidation request to the Dispatchers letting them know the page has been updated. Lastly, an end user sends a request through the Load Balancer to view the page that has been changed. The Dispatcher recognizes that the requested page was invalidated and checks for a new version from the Publish. The Dispatcher caches the updated page and serves the request back to the end user. The image below may help visualize this process.

standardAEMarchitecture

With this information out of the way, you should be somewhat versed in the basics, which will help with further discussions of AEM. Whereas none of this is extremely complex, this information will better prepare you for the journey we will be taking together. You’re now armed and ready with what you need to begin the AEM journey as we venture into the great expanse and take a look at the various roles that exist within AEM. Our first stop is the Author.

If you have questions or comments feel free to email info@aempodcast.com.

A Year in the Desert of AEM: The Author

0
0

05287_AEM_A-Year-in-the-Desert-of-AEM_Author
Having prepared for the journey, you’re now ready to venture into the desert of Adobe Experience Manager and learn about the mystical Author. Ok, I am not sure I would really call the AEM Author mystical, but it sure can bewilder the uninitiated. For those of you who are returning for the second installment of this series of articles, I mentioned we would be digging into the various responsibilities within AEM. We’re going to discuss the Author instance, from its purpose through setup and maintenance. The setup and configuration for Author can also be found in Adobe’s documentation. The same process can be followed more or less for the Publish instance, which we will talk about in our next article. For those of you who haven’t read my first article, it covers some high-level information on AEM. Unless you are already familiar with the basic concepts surrounding AEM, I would suggest giving it a quick read before moving on.

Another quick note is that throughout the article I will reference ACS AEM Commons, which is a package provided by Adobe Consulting Services. Essentially, they generalize and make available tools they have created and package them as an add-on to AEM. These features can be extremely helpful and potentially save you and your developers a lot of time and frustration. I recommend including this package on all of your AEM installations. Let’s get started.

The AEM Caravan Lead
As you embark on your journey, it’s important to look to the leader to guide the expedition. Similarly within Adobe Experience Manager, it’s important to look to the Author to guide the creation and management of content. This server should be thought of as the lead instance in AEM. Developers will create templates and components for the the content creators to use on Author; content creators will create pages and import digital assets here as well. As a systems guy or gal, this is where all the configs are stored. The idea here is that everything, even configs that apply only to a Publish instance, is stored on Author and then replicated to Publish servers. Run modes, Author or Publish, for example, are then used to tell the servers if configs should be loaded or not. So really, in a worst case scenario, as long as you have a good backup of your Author instance, you will be able to restore your AEM stack. This does mean that inherently AEM has a single point of failure, the Author. I would suggest becoming very serious about your backup processes, if you are not already—especially when it comes to the Author.

As I mentioned above, Author is where content is created; when you first start an Author instance it installs code that is Author specific, basically the editing dialogs and tools. Just in case any of you were thinking “Well, I’ll just set up one Author and then save time by copying that instance and use it as a Publish”—don’t do it. I know you were thinking it, but don’t do it. You will end up having two Authors and you will run into all kinds of “fun”. This is because of installation run modes, and we’ll talk about those in a minute.

Currently Adobe Experience Manager is in a period of transition when it comes to the web interface; they are working toward Touch UI. What this means is the classic, older tools are being replaced gradually. So tools you might have used the past, including those that are mentioned in this article and others, might change slightly or entirely. With that in mind, I am going to share some paths that as an admin will be helpful to remember. I am going to list them with a quick description and include the alternate paths if there are old and new versions.

  • High-level navigation of the content tree; manage, activate, or deactivate pages
    • /siteadmin (classic tool)
    • /sites.html
  • Allows you to create users and groups, and manage permissions and members
    • /useradmin (classic tool: permissions can be managed here or under “Access Control” in the CRXDE)
    • /libs/granite/security/content/useradmin.html and
    • /libs/granite/security/content/groupadmin.html
  • High-level navigation of digital assets
    • /damadmin (classic tool)
    • /assets.html
  • High-level navigation for AEM tools, including ACS Commons
    • /miscadmin
  • Disk space reports
    • /etc/reports/diskusage.html
  • Replication agents and tree activation
    • /etc/replication.html
  • Workflow manager
    • /libs/cq/workflow/content/console.html
  • OSGI console access
    • /system/console/bundles – Default page, list of bundles
    • /system/console/configMgr – List of service configurations
    • /system/console/slinglog – Quick access to logging information and configs
    • /system/console/jcrresolver – Useful for testing sling mapping configurations
  • Tree-like navigation of the nodes in the JCR
    • /crx/de/index.jsp (CRXDE)

Gaining AEM Ground
As you make your way across the desert, you want to be sure that you’re doing everything possible to maximize your time. You also want to do that with regard to your AEM installation to ensure you’re getting the most out of your investment. When you read through documentation on getting started with AEM, you have the option of double-clicking a JAR file, which will start a local instance of AEM that you can play with; this is great for local testing but not so helpful for a headless server environment. As a rule of thumb when I want to work with Adobe Experience Manager, I have gotten into the habit of doing an unpack on the JAR file (java -jar /path/to/file/aem.jar -unpack), which will extract everything into a directory named “crx-quickstart”. This is an important directory; it is pretty much where all of AEM will live—think of it as AEM’s home directory. This directory can be copied or moved and it will contain your entire AEM installation.

Starting or stopping AEM after an unpack is fairly simple as there are scripts located in the crx-quickstart/bin directory. You can either run these directly, or the better option would be to create a daemon service script that exports the values needed to start AEM, such as the JVM Options and run modes.

I have mentioned run modes a few times, so let me take a quick moment to talk about them here as there are really two types.

Installation run modes are applied the first time you run AEM and then fixed for the entire lifetime of the instance; they cannot be changed later on down the road.

  • Persistence Manager – Determine how data persists, i.e., crx2, crx3, crx3mongo
  • Role – Determines what responsibilities are assigned to AEM, i.e., Author or Publish
  • Samplecontent – installs Adobe’s sample Geometrixx content

Note: By default, samplecontent is added to the installation run modes. If you specify “nosamplecontent”, you will instead get a version of AEM that matches Adobe’s Production-Ready Checklist. What is obvious about this is that sample content and users are not installed, but it also causes some bundles from being installed that you cannot easily get back. For actual production environments this can be helpful, but in the non-production stacks it might make things a little difficult. For non-production environments, you may want to consider allowing sample content to be installed and then remove the Geometrixx packages after.

Customized run modes are applied on each startup and can be changed with a restart of AEM. They allow you to define run modes that can be used to identify the instance that’s running and modify its configurations accordingly. An example would be to set a “production” run mode, so you can identify configs that should only be applied to a production instance.

Conserving Water
In the desert, you have to know how to manage your water supply. The same holds true for “flushing” cached content in AEM. Now, I mentioned in the first article how information that is created on the Author is passed through the stack to reach the end user. This process can run through several workflows, but at the end of the day it is still all handled by replication events. I also mentioned a little earlier in this article that you want to ideally keep everything on Author and then replicate (push) that out to Publish instances. This holds true for the Dispatcher agents as well. You should be in the habit of configuring those nodes on the Author, even though they live under the agents.publish directory, and then push them to your pubs. Now, you might ask, “Why not just have the Author flush the cached content from the Dispatchers?” Well I am glad you asked—you see the issue with having the Author flush content that has just been activated is that sometimes it takes the Publish instances a moment to ingest that content. This is especially true if there are a lot of replication events happening. This then creates an issue where the Dispatcher is trying to re-cache that page but the Publish isn’t ready to render it, so you end up caching broken pages. Thus, you should have your Publish instances flush your Dispatchers in all cases but one.

What is that one case you ask? Another great question. There is a tool packaged with ACS commons called the “Dispatcher Flush UI”, which allows you to create pages that content creators can use to flush pages manually from the Dispatcher. This is safe to do from the Author, but you will need to make sure you enable a flush agent for each Dispatcher on your Author, and that you have the “Ignore default” option selected. This allows ACS Commons to send a flush request from the Author while normal activations will continue to use flush agents on Publish.

Scheduled Breaks
During your journey, you need to ensure that you’ve scheduled time for breaks. You also might want to schedule something of similar importance within AEM. I mentioned the importance of taking backups a little earlier, and if you’re wondering how you can trigger these on a schedule, then you are in luck. We can cover this in more detail later, but for those of you who are looking for a solution right now, when AEM triggers a backup it sends a ReSTful request to start the process. Knowing this can help get you started.

Speaking of ReSTful, calls I should also mention there are quite a few articles out there that cover different cURL commands that can be used with AEM, as such I will not cover those commands in this article. I will however mention something that may prove useful: Adobe Experience Manager is built on a ReSTful framework, which means anything you can do through a console or the CRXDE you can make a ReST call to perform the same action. Although finding exactly the calls that are being made can sometimes be difficult, more often than not they are pretty simple to determine using this method I have picked up along the way. Chrome’s debug tool has this nifty option to copy any request from the network tab as a cURL. This means you can click the Preserve Log box, go into a local AEM instance, make your request using the CRXDE, and then see the result of that request in Chrome. You can then select that request and copy as cURL. Viola! You can now make the same request through the command line, shell script, or what have you.

We have now covered a bit of the basics talking about the Author environment, and getting the Author server started up. Although we could dig even deeper into the Author, this should help you to better understand how Author fits into the AEM stack. That’s two articles down and more to come—make sure to subscribe to the blog to stay tuned. We will be covering the Publish environment next as we continue to traverse the AEM landscape.

Viewing all 36 articles
Browse latest View live




Latest Images