Welcome to Tech Mastery, your expert source for insights into technology and digital strategy. Explore topics like Adobe Experience Manager, AWS, Azure, generative AI, and advanced marketing strategies. Delve into MACH architecture, Jamstack, modern software practices, DevOps, and SEO. Our blog is ideal for tech professionals and enthusiasts eager to stay ahead in digital innovations, from Content Management to Digital Asset Management and beyond.
How to enable Basic Authentication for Non-Prod AEM websites? | Support Authenticated Performance Testing with Cloud Manager
Enable Basic Authentication:
Most of the time we will have the use case to enable basic authentication for non-prod AEM websites to avoid non authenticated users accessing the content(another option is through IP whitelisting) also avoiding the non-prod contents getting indexed through google search(another approach to avoid the indexing is through Robots meta tag)
Easy to use generic user name/password for every website so that only the users know those credentials can access the password(if you need more security go with site-specific users or individual users)
In AEM the basic authentication can be enabled quickly through Dispatcher(Apache)
Create a common configuration file for authentication - /conf.d/htaccess/authentication.conf
## unsets authorization header when sending request to AEM
Include this file into the individual Virtual Hosts
<Location />
<If "'${ENV_TYPE}' =~ m#(dev|uat|stage)#">
Include /etc/httpd/conf.d/htaccess/authentication.conf
</If>
</Location>
The ENV_TYPE can be set as an Environment variable e.g /etc/sysconfig/httpd (for AMS environment the required environment variables will be enabled by default)
ENV_TYPE='dev'
Create the credential file, execute the below command, you will be prompted to enter the password
Restart the Apache server, now basic authentication is enabled for the websites.
Authenticated Performance Testing with Cloud Manager:
Cloud Manager is a Cloud service that allows customers to build, test, and deploy AEM applications hosted by Adobe Managed Services. Refer to the below URL for more details
The Cloud Manager enables the Performance Testing on Stage environment after every successful deployment.
The list of Stage domains enabled for performance testing can be configured - this configuration is not supported through UI but needs to be enabled through the backend(Adobe team should be helping here)
Also, the required performance KPI's can be configured through Cloud Manager UI
The performance testing will fail now due to the basic authentication enabled for the Stage websites, to overcome this the basic authentication credential should be configured in the Cloud Manager prod pipeline - the configuration cant be enabled through Cloud Manager UI but through Cloud Manager Plugin for the Adobe I/O CLI
This CLI supports two modes of authentication: Browser-based and Service Account. I am going to use browser-based authentication to enable the required configurations
aio auth:login - login through browser with your Cloud Manager credentials
aio cloudmanager:org:select - select your organization where your program and the pipeline is configured(most of the case signle org)
aio config:set cloudmanager_programid PROGRAMID - Add your program ID
aio cloudmanager:set-pipeline-variables PIPELINEID--variable CM_PERF_TEST_BASIC_USERNAME testuser--secret CM_PERF_TEST_BASIC_PASSWORD pwdtestuser- Add your pipeline ID and the basic credentials
Now the basic authentication is enabled and the basic authentication credential are set while performing the performance testing.
"A Sandbox program is one of the two types of programs available in AEM Cloud Service, the other being a Production program.
A Sandbox is typically created to serve the purposes of training, running demos, enablement, or Proof of Concept (POC)s. They are not meant to carry live traffic."
Refer to the following URL to get the details on AEM as a Cloud Service Sandbox program - https://experienceleague.adobe.com/docs/experience-manager-cloud-service/implementing/using-cloud-manager/sandbox-programs/introduction-sandbox-programs.html?lang=en#
Enable Sandbox Program:
To start using the AEM as a Cloud Service Sandbox, the minimal required Adobe Enterprise Term License Agreement (ETLA) should be signed, you can reach out to Adobe Account/Support team for more details on this.
Once the ETLA is in place you should be able to add the sandbox program through Cloud Manager(one of your primary contacts will be added as an administrator, if you are already part of Cloud Manager through AMS then that will continue)
Select the Profile the user should be added (AEM administrator or AEM user) - Create new profiles based on the need
Now you should be able to access the author server
Sandbox program also enables Publish and Preview servers - You can view those details by going into the environment
Now you can push the changes to the git repository
By default the "main" branch is enabled for deployment, if required you can create the additional branch e.g dev, and enable the deployment through the new branch.
Now start the pipeline to deploy the changes
Even if you required the deployment can be initiated on repository change
The Sandbox setup is completed now, enable the content and code based on your use cases.
Error while syncing the local git repository to remote repository | error: unpack failed: error Shallow object update failed | Shallow vs Full Cloning
I was using the BitBucket Pipeline to sync the local repository(specified branches) to the remote git repository, the sync was working without any issue and stooped working recently with the below exception.
! [remote rejected] dev -> dev (Shallow object update failed: The object xxxxxxxxxxxxx is being referenced but does not exist.)
error: failed to push some refs to 'https://testuser:[email protected]/test/test.git'"
After analysis, the root cause for the issue is the BitBucket pipeline doing a Shallow clone(with specific depth)
A shallow clone is a repository created by limiting the depth of the history that is cloned from an original repository. A shallow clone is created using the --depth option when calling the clone command, followed by the number of commits that you want to retrieve from the remote repository.
--depth <depth> - Create a shallow clone with a history truncated to the specified number of commits. Implies --single-branch unless --no-single-branch is given to fetch the histories near the tips of all branches. If you want to clone submodules shallowly, also pass --shallow-submodules.
A shallow clone helps to improve the performance of the clone by pulling down just the latest commits, not the entire repo history
In full clone, by default git download the history of all branches, sometimes this will create performance issues but useful for some cases like repository synching.
Blank screen displayed in edit mode | Adobe Experience Manager(AEM)
I was getting the blank screen while accessing the pages through Edit mode in AEM
The below exception was displayed
java.lang.NullPointerException
at org.apache.jsp.libs.cq.gui.components.authoring.workflow.startworkflow.startworkflow_jsp._jspService(startworkflow_jsp.java:217)
at org.apache.sling.scripting.jsp.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.sling.scripting.jsp.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:502)
at org.apache.sling.scripting.jsp.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:449)
at org.apache.sling.scripting.jsp.JspScriptEngineFactory.callJsp(JspScriptEngineFactory.java:339)
at org.apache.sling.scripting.jsp.JspScriptEngineFactory.access$100(JspScriptEngineFactory.java:97)
at org.apache.sling.scripting.jsp.JspScriptEngineFactory$JspScriptEngine.eval(JspScriptEngineFactory.java:600)
Also, the workflow model page was blank with the below exception
java.lang.NullPointerException
at org.apache.jsp.libs.cq.workflow.admin.console.components.datasource.modelsdatasource.modelsdatasource_jsp._jspService(modelsdatasource_jsp.java:410)
at org.apache.sling.scripting.jsp.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.sling.scripting.jsp.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:502)
at org.apache.sling.scripting.jsp.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:449)
at org.apache.sling.scripting.jsp.JspScriptEngineFactory.callJsp(JspScriptEngineFactory.java:339)
at org.apache.sling.scripting.jsp.JspScriptEngineFactory.access$100(JspScriptEngineFactory.java:97)
The workflow Instances/Archives/Failures pages were failing with the below exceptions
java.lang.NullPointerException
at org.apache.jsp.libs.cq.workflow.admin.console.components.datasource.workflowinstancedatasource.workflowinstancedatasource_jsp._jspService(workflowinstancedatasource_jsp.java:176)
at org.apache.sling.scripting.jsp.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.sling.scripting.jsp.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:502)
at org.apache.sling.scripting.jsp.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:449)
at org.apache.sling.scripting.jsp.JspScriptEngineFactory.callJsp(JspScriptEngineFactory.java:339)
at org.apache.sling.scripting.jsp.JspScriptEngineFactory.access$100(JspScriptEngineFactory.java:97)
java.lang.NullPointerException
at org.apache.jsp.libs.cq.workflow.admin.console.components.datasource.failureinstancedatasource.failureinstancedatasource_jsp._jspService(failureinstancedatasource_jsp.java:167)
at org.apache.sling.scripting.jsp.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.sling.scripting.jsp.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:502)
at org.apache.sling.scripting.jsp.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:449)
at org.apache.sling.scripting.jsp.JspScriptEngineFactory.callJsp(JspScriptEngineFactory.java:339)
at org.apache.sling.scripting.jsp.JspScriptEngineFactory.access$100(JspScriptEngineFactory.java:97)
Somehow the restart of the AEM server has not helped to resolve the issue(not sure how this bundle has been to an Installed state, suspecting this is happened as part of Cloud Manager deployment). The issue got resolved after manually starting the bundle through the console
Editable templates have been introduced in AEM 6.2, which allows the authors to create and edit templates. Template authors can create and configure templates from the Templates console in the AEM without the help of the development team. Template authors can define the policies, structure, and initial content for the templates that will be shared by all the pages created based on this template.
Editable Templates allow the template-authors to configure the client libraries required to style the websites created based on this template — base/common client libraries are included through page rendering component but site-specific client libraries through template policy configuration.
Most of the time we will have a generic template enabled with headers and footers through experience fragment and the container with allowed components that can be managed by Authors while creating the pages, e.g.
This will have some constraint while reusing the template with multiple sites
site-specific header and footer — customize the header/footer for individual website
site-specific style/theme — enable different styles/themes for individual sites.
In this tutorial let us see how to enable the editable template with multiple sites that have the different header/footer and styling requirements.
site-specific header/footer:
Most of the time the header and footer are enabled through experience fragment and configured in template level by using experience fragment component so that all pages created based on this template will have the consistent header/footer experience. The issue is while reusing the template with sites that require a localized header and footer, the Experience Fragment core component saves us here, the Experience Fragment core component enables the support for localized fragment content
"Supports references for localized content: if the component is defined in a template and if the fragment is part of a localized structure below /content/experience-fragments that follows the same patterns as the site below /content, the fragment with the same localization (language, blueprint or live copy) as the current page will be rendered".
If the experience fragments and the sites follow the same localized structure, the experience fragment core component uses the localized fragment content based on the site language.
The experience fragment components in the template are enabled with default experiment fragment — /content/experience-fragments/my-site/us/en/header/master and /content/experience-fragments/my-site/us/en/footer/master, while accessing the different localized sites the experience fragment core component derives the localized fragment path based on the site structure and applies that to the pages.
e.g while accessing the content from /us/es the following fragments are applied —/content/experience-fragments/my-site/us/es/header/master and /content/experience-fragments/my-site/us/es/footer/master , the same case for other localized sites.
This experience fragment localization feature helps us to reuse the template across different websites that have localized header and footer needs without creating site-specific templates.
site-specific style/theme
Most of the time we may have the need to enable site-specific style/theme for the websites that are built on the same templates. By default Editable template and core components won't support different styles for the websites built on the same template — the client libraries are enabled either in the page rendering component or in the template. The cq:designPath value configured in the site property will not be honored by editable templates and core components, the cq:designPath is more used by the static template.
Let us see a custom approach that will help us to enable site-specific style/themes(client library).
The front end module should generate the site-specific client library that can be configured for individual websites, refer to the link below for the details on enabling site-specific client libraries through the UI frontend module.
As a first step enable the additional property- styleName to the page dialog (if required enable dropdown list with predefined style values, also the property can be enabled in all level to apply different site and page level styles) — the styleName value is equal to the site names used by ui frontend module e.g site1, site2 (use context-aware configuration instead of page properties if required)
Enable sling model to to return the site specific client library names based on the inherited styleName property passed from customheaderlibs.html and customfooterlibs.html files of the page rendering component.
Enable the client library categories into the page rendering component(e.g /apps/multisitefrontenddemo/components/page) — customheaderlibs.html and customfooterlibs.html, the inherited style name property is injected to StyleNameModel — the property form current page if not available then from the parent hierarchy