As everything is moving to the cloud, Adobe has launched in 2020 AEM as a Cloud Service (AEMaaCS), which is the next generation and cloud-native way of leveraging AEM applications. In this article, we present a feature of the Gradle AEM Plugin we recently developed to migrate content between AEM and AEMaaCS instances.
Gradle AEM Plugin (GAP)
Gradle AEM Plugin (GAP) is a Gradle plugin that provides many tasks related to AEM development, such as launching, provisioning, restarting, backing up, restoring, and destroying instances, deploying packages, synchronizing content between a local repository and a running instance, copying content between instances, tailing logs, and more. All of these tasks are incremental builds that take seconds, not minutes.
GAP Launcher
To run GAP, you need a project that has at least Gradle Wrapper files and minimal Gradle configuration that applies the Gradle AEM Plugin. However, some GAP features can be useful even when you're not building an AEM application, and that's where the GAP Launcher comes in handy. It's a standalone launcher that provides GAP features with minimal effort. To get it working, download the latest jar from GitHub releases page, or simply run the following command in the directory where you want to use it:
curl -OJL https://github.com/wttech/gradle-aem-plugin/releases/latest/download/gap.jar && java -jar gap.jar && rm gap.jar
This will download the latest GAP jar file and run it, then delete the jar file.
You can now use the Gradle wrapper to run the tasks provided by GAP.
Instances Setup and Requirements
You need access to the following:
- A local or remote AEM on-prem author instance
- An AEM author instance running on Adobe cloud infrastructure (AEMaaCS)
For a regular on-prem AEM instance, basic authentication (username and password) is sufficient. However, with AEMaaCS, Adobe doesn't share these credentials, so authentication must be performed using a bearer token. GAP can generate this token if you provide it with a JSON file that you can download from the cloud developer console, as shown in the image below.
Adobe cloud developer console image by Adobe
Writing a Migration Task with GAP
Add the following snippet to build.gradle.kts
file to extend GAP tasks with this custom "migrate" task which when you
run will copy all the content you have under a specified path from your on-prem AEM author to the same path in your
AEMaaCS author.
tasks.register("migrate") {
doLast {
val author1 = aem.instance("http://<username>:<password>@localhost:4502")
val author2 = aem.instance("https://<author-name>.adobeaemcloud.com")
author2.serviceCredentials.set(File("/path/to/service_token.json"))
val pkg = author1.sync.packageManager.download {
filters("/content/foo")
}
author2.sync.packageManager.deploy(pkg)
}
}
aem
- AemExtension is the core of GAP and represents the facade for implementing tasks.aem.instance
is a shorthand method for getting/creating a defined Instance by URLauthor1
represents your on-prem author instance. Notice that you can set the username and password through the URL.author2
represents your AEMaaCS author instance in this case because of passing the .adobeaemcloud.com domain.serviceCredentials
is a property in the instance object where you can specify the path to the earlier downloaded JSON credentials file.sync
- InstanceSync is a class that provides access to AEM-specific resources (OSGI, JCR, CRX, GroovyConsole, etc.) to perform synchronization tasks.packageManager
- PackageManager is a class to manage CRX packages on an AEM instance (upload, install, delete, etc.).sync.packageManager.download
will download the package with the location specified in thefilter
object from author1.sync.packageManager.deploy
will deploy that downloaded package and install it to author2.
you can now execute the following command to run the task whenever you want to migrate content between those two instances:
sh gradlew migrate
Summary
As you have seen, implementing automation in GAP is very easy and powerful, we were able to migrate content to AEMaaCS in a couple of lines of code. You could definitely use it in a daily development routine together with AEMaaCS SDK.
For more information on GAP, check out the GAP GitHub repository. Additionally, the plugin documentation contains a lot of examples and use cases that will help you to understand how to use GAP in your specific situation.
Hero image by fullvector - www.freepik.com, opens in a new window