Some
times I have seen, we may need some of the bundles latest version which
are available in AEM but same version is not available in maven public
repository or Adobe nexus repository. Here we will see how to get the
bundle locally and compile it. First Step - if the third party bundle is in your local AEM server,
Getting bundle from AEM and install it in our local maven repository-
When
you notice a bundle is available in AEM servers system >console
>bundle, the AEM installed folder will have the same bundle in disk.
First of all you identify the bundle id from AEM system console as shown below.
Click on image to see it big
To find the same bundle in local disk, go to
AEM Installed folder\crx-quickstart\launchpad\felix\bundle<id>)
Click on image to see it big
Now copy this bundle to a location (for e.g C:)
Second Step: Next step is installing it in our local maven repository. Open the command prompt in c:
The syntax for installing the bundle in local repository is
mvn
install:install-file -Dfile=<path-to-file>
-DgroupId=<group-id> -DartifactId=<artifact-id>
-Dversion=<version> -Dpackaging=<packaging>
Actual command used:
mvn
install:install-file -Dfile=bundle.jar -DgroupId=org.apache.jackrabbit
-DartifactId=jackrabbit-api -Dversion=2.18.0 -Dpackaging=jar
Now you will have the dependency bundle in your local maven repsotory and your code will compile without issues.
In this post we will analyze the ways we can use AEM with GraphQL and the advantages.
GraphQL is becoming a trend setting tool to query the response now. There are some cons with traditional way of using API calls.
The difference between GraphQL and API
Usually an API response dumps all the information passed from the third party back-end. But when we use GraphQL we can just query only the required relevant there by the data transfer load is less.
AEM as back-end with GraphQL:
Here AEM Content will be exposed as an API using content/ assets API and GraphQL queries the response and send the relevant response to any third party application like REACT or Angular.
Sample use case:
In my test scenario, I had created a content fragment in AEM and exposed over an http API. I have a GraphQL layer deployed on a stand alone Node JS and this GraphQL queries the Content Fragment API for relevant information. This data was then send to REACT application for display purpose.
AEM for content display from third party system:
In this case GraphQL queries any third party system and send the relevant information to AEM. Sample use case: I have a Facebook API to retrieve a set of information from Facebook and it was then filtered through GraphQL and then send to AEM.
What Next?
I will come up with GraphQL Setup + AEM Integration with GraphQL in my upcoming tutorials. Keep watching this page for more.
In AEM
projects, there are cases we may need to create pdf or png form of an html
page for preview purpose. Media Handlers are a good help here. By using Media Handlers we can process the
AEM assets easily. Once configured, during asset uploads, the asset gets
processed using either AEM provided handlers or command line tools.
Click on image to see it big
What is media Handlers?
They
are services internal to AEM Assets that perform specific actions on
assets. They work hand in hand with Workflows. The Media Handlers
extract all available metadata from an asset; it has also capability of
creating a thumbnail image.
Enable/ Disable
By default all the available Media Handlers are enabled. To disable them , just click on the disable button.
Go to http://localhost:4502/system/console/components to see all media handlers.
Some of the examples could be TextHandler, JpegHandler, PdfHandler etc
Developers follow the approach given by Adobe to work with Editable Templates, ContextHubs and Content Fragments. But many are not sure the reason behind why there needs to be configuration browser for AEM.
We have given a video explaining what is configuration browser, why it is required and if we dont create / configure it how it affects the AEM Site.
Once the production deployment of an AEM site is done, and if we find slowness in any of the things like pages are loading slow, creation or editing of pages are slow, AEM response times are not fair, AEM is not responding to some requests, request.log on AEM shows slow response times etc. we can assume there is some issue with the performance of the site.
Common reasons for slow performance
Below given some of the possible reasons for AEM site performance issues;
Improper design - Not a deeply though solution
High CPU utilization due to long running requests such as slow searches, write-heavy background jobs, moving the whole branches of site content, etc.
Application code - Error prone code
Memory Issues - Not an efficiently written
Insufficient server sizing or incorrect architecture - For a huge site, we did not use mult author multi pubish setup
Indexing Issues - Not done a proper indexing
Lack of caching - No efficient caching
Wrong disk I/O configuration - Improper infra configuration
Memory sizing - Not used enough memory
Network bandwidth and latency - Not having proper bandwidth allocated
Replication Issues - Improper configuration which leads to blockage
Ineffective or inadequate maintenance
Lack of a Content Delivery Network
How do we analyze the root cause of a performance issue?
Check CPU utilization for any AEM process eating much memory
Study the request.log file for detailed data
Collect thread dumps and analyze them
Workflow checks, version checks, audit checks
Analyze caching strategies implemented at the AEM dispatcher
Check maintenance related to Oak repositories
Validate asset guidelines
Check indexing and review the jcr queries for 1. Poorly restricted (or scoped) queries 2. Large result set queries 3. Index-less queries
Some of the Tools for validating and fixing AEM performance:
JMX Console in AEM : Enables you to monitor and manage services on the CRX server.
JConsole: that comes with JDK - helps to find memory leaks, thread deadlock etc.
Any other profilers : like YourKit(CPU and memory profiling tool) which recommends the better usage of code
Memory analyzer tool - MAT: Eclipse's MAT is a set of plug-ins for the Eclipse IDE. Helps for heap dump analysis & memory problems in the application
SonarQube : A code validation tool for better code
How to make sites perform better?
Ensure you are carrying out regular maintenance
Improve back-end service calls to a fail safe state.
Optimize AEM client libraries - Embed client libraries, Minify them
Cache JavaScript and CSS for long periods of time
Optimize Indexes so that querying works better
Modify the jcr queries to scope limited and efficient.
Install the recommended AEM service packs, cumulative fix packs and hot fixes:
Follow the Assets best practices.
Allocate enough RAM to avoid IO saturation
Enable transient workflows - this avoids manual purging of workflows
Tune the Oak Repository as per best practice
Hold on; Before you go for any big changes as part of performance improvements, have a backup plan, Disaster recovery plan do itfirst before you try to fix the performance.
When ever we need to retrieve a value from JSON using its key, JSONParser is a better and easy approach.
We know in AEM 6.3, all json related operations are deprecated from package org.apache.commons.json.
For eg JSONParse, JSONObject.
Let us try to fix this using GSON. AEM has default GSON library to parse the JSON or for JSON processing & conversations.
How to convert a String to JsonObject using Gson library.
Below is the common syntax to use GSON in java code. To use this ensure your pom.xml has the GSON dependency added.
The pattern to use GSON is, Gson gson = new Gson(); YourClass yourClassObject = new YourClass(); String jsonString = gson.toJson(yourClassObject);
Below given a real case example.
Say we have a multifield in AEM which has a JSON string array as,
String personalData = {"name": "Alex","age":"27","details": "User says at Washington"}
// Now we need to create a Java model class as given below. Remember to match the fields(keys in JSON with string variables )
public class PersonalData { public String name; public String age; public String details; }
//Now in our sling model or relevant class, the GSON invocation could be something like; Gson gson = new Gson(); PersonalData persondata = gson.fromJson(personalData, PersonalData.class);
Another simple example is
Say we have a multifield as shown below.
String organization = {"org": "Google"}
// Our Java model class
public class OrgData {
public String org;
}
//invoking the method
Gson gson = new Gson();
OrgData orgdata = gson.fromJson(organization, OrgData.class);
//This class takes a json string and parse it to get its value from a key. /*Say we have a json {"key":"value"} Then to get its 'value' easily without using Java regular expression or patterns We can use this approach */
public class MyJsonParser {
//You can run this code directly to test how it works public static void main(String[] args) { Gson gson = new Gson(); String jsonString = "{\"key\":\"value\"}"; //Create JSON element from JSON String JsonElement element = gson.fromJson(jsonString, JsonElement.class); //Fomr a Json Object from element JsonObject jsonObject = element.getAsJsonObject(); //Below line takes the 'key' from json and print its 'value' System.out.println(jsonObject.get("key").getAsString()); }
}
AEM server holds both content and binary data. For a better deployment isolation and organizing data considering performance and scalability of AEM, the binary data(for eg media files) can be stored independently from the content nodes by configuring it.
Generally binary data is stored in a data store, whereas content nodes are stored in a node store. Both 'data stores' and 'node stores' can be configured by updating persistent identifier (PID) in OSGi configuration.
Say when we are working with large number of binaries, Adobe recommends to use an external data store instead of the default node stores. This provides better performance.
The external data store can be File Data Store, Amazon S3 Data Store, Azure Data Store which works well when we need to store binaries like media files.
Node store can be of two types 'Segment Node' Store & 'Document node' store. Segment node store is the basis of Adobe's TarMK implementation & document node store is the basis of AEM's MongoMK implementation in AEM6x.
Configuration PID's for each storage types are given below.
Document node store
org.apache.jackrabbit.oak.plugins.document.DocumentNodeStoreService.config
Segment Node Store
org.apache.jackrabbit.oak.segment.SegmentNodeStoreService.config
File Data Store
org.apache.jackrabbit.oak.plugins.blob.datastore.FileDataStore.config
Amazon S3 Data Store
org.apache.jackrabbit.oak.plugins.blob.datastore.S3DataStore.config PID
Azure Data Store
org.apache.jackrabbit.oak.plugins.blob.datastore.AzureDataStore.config
Summary: Thus by selecting the recommended configurations based on requirement, we can achieve a high performing AEM instance.
Note: The concepts are same for all AEM 6x versions, except a few minor configuration changes.