AEM Assets events for PIM integration
- Tópicos:
- Desenvolvimento
- Criador de aplicativos
Criado para:
- Iniciante
- Desenvolvedor
Learn how to receive an AEM Event and act on it to update the content state in AEM using the OpenAPI-based Assets Author API.
How to process the received event depends on the business requirements. For example, the event data can be used to update the third-party system, or AEM, or both.
This example demonstrates how a third-party system, such as a Product Information Management (PIM) system, can be integrated with AEM as a Cloud Service Assets. Upon receiving an AEM Assets event, it is processed to retrieve additional metadata from the PIM system and update the asset metadata in AEM. The updated asset metadata can include additional information like SKU, supplier name, or other product details.
To receive and process the AEM Assets event, the Adobe I/O Runtime, a serverless platform is used. However, other event processing systems like Webhook in your third-party system or Amazon EventBridge can also be used.
The high-level flow of the integration is as follows:
- The AEM Author service triggers an Asset Processing Completed event when an asset upload is completed and all asset processing activities are also completed. Waiting for asset processing to complete ensures that any out-of-the-box processing, such as metadata extraction, has been completed.
- The event is sent to the Adobe I/O Events service.
- The Adobe I/O Events service passes the event to the Adobe I/O Runtime Action for processing.
- The Adobe I/O Runtime Action calls the API of the PIM system to retrieve additional metadata like SKU, supplier information, or other details.
- The additional metadata retrieved from the PIM is then updated in AEM Assets using the OpenAPI-based Assets Author API.
Prerequisites
To complete this tutorial, you need:
-
AEM as a Cloud Service environment with AEM Eventing enabled. Also, the sample WKND Sites project must be deployed on to it.
-
Access to the Adobe Developer Console.
-
Adobe Developer CLI installed on your local machine.
Development steps
The high-level development steps are:
-
Configure the project in ADC
-
Configure the AEM Author service to enable ADC project communication
-
Develop a runtime action to orchestrate
- metadata retrieval from the PIM system
- metadata update in AEM Assets using the Assets Author API
-
Create and apply asset metadata schema
-
Verification of asset upload and metadata update
For details on steps 1-2, refer to the Invoke OpenAPI-based AEM APIs guide and for steps 3-4 refer to the Adobe I/O Runtime Action and AEM Events example. For steps 5-9, refer to the following sections.
Configure the project in Adobe Developer Console (ADC)
To receive AEM Assets Events and execute the Adobe I/O Runtime Action created in the previous step, configure the project in ADC.
-
In ADC, navigate to the project that you created in step-3. From that project, select the
Stage
workspace here the runtime action is deployed when you runaio app deploy
as part of the step-4 instructions. -
Click the Add Service button and select the Event option. In the Add Events dialog, select Experience Cloud > AEM Assets, and click Next.
-
In the Configure event registration step, select the desired AEMCS instance, then Asset Processing Completed event, and the OAuth Server-to-Server authentication type.
-
Finally, in the How to receive events step, expand the Runtime action option and select the generic action created in the previous step. Click Save configured events.
-
Likewise, click the Add Service button and select the API option. In the Add an API modal, select Experience Cloud > AEM Assets Author API and click Next.
-
Then select OAuth Server-to-Server for authentication type and click Next.
-
Then select the correct Product Profile that is associated with the AEM Assets environment from which the event is being produced and have sufficient access to update assets there. Finally, click the Save configured API button.
In my case the AEM Administrators - author - Program XXX - Environment YYY product profile is selected, it has AEM Assets API Users service enabled.
Configure AEM instance to enable ADC Project communication
To enable the ADC Project’s OAuth Server-to-Server credential ClientID to communication with the AEM instance, you need to configure the AEM instance.
It is done by defining the configuration in the config.yaml
file in the AEM Project. Then, deploy the config.yaml
file using the Config Pipeline in the Cloud Manager.
-
In AEM Project, locate or create the
config.yaml
file from theconfig
folder. -
Add the following configuration to the
config.yaml
file.kind: "API" version: "1.0" metadata: envTypes: ["dev", "stage", "prod"] data: allowedClientIDs: author: - "<ADC Project's OAuth Server-to-Server credential ClientID>"
Replace
<ADC Project's OAuth Server-to-Server credential ClientID>
with the actual ClientID of the ADC Project’s OAuth Server-to-Server credential. -
Commit the config changes to the Git repository and push the changes to the remote repository.
-
Deploy the above changes using the Config Pipeline in the Cloud Manager. Note that the
config.yaml
file can also be installed in an RDE, using command line tooling.
Develop runtime action
To perform the metadata retrieval and update, start by updating the auto created generic action code in src/dx-excshell-1/actions/generic
folder.
Refer to the attached WKND-Assets-PIM-Integration.zip file for the complete code, and the below section highlights the key files.
-
The
src/dx-excshell-1/actions/generic/mockPIMCommunicator.js
file mocks the PIM API call to retrieve additional metadata like SKU and supplier name. This file is used for demo purposes. Once you have the end-to-end flow working, replace this function with a call to your real PIM system to retrieve metadata for the asset./** * Mock PIM API to get the product data such as SKU, Supplier, etc. * * In a real-world scenario, this function would call the PIM API to get the product data. * For this example, we are returning mock data. * * @param {string} assetId - The assetId to get the product data. */ module.exports = { async getPIMData(assetId) { if (!assetId) { throw new Error('Invalid assetId'); } // Mock response data for demo purposes const data = { SKUID: 'MockSKU 123', SupplierName: 'mock-supplier', // ... other product data }; return data; }, };
-
The
src/dx-excshell-1/actions/generic/aemCommunicator.js
file updates the asset metadata in AEM using the Assets Author API.const fetch = require('node-fetch'); ... /** * Get IMS Access Token using Client Credentials Flow * * @param {*} clientId - IMS Client ID from ADC project's OAuth Server-to-Server Integration * @param {*} clientSecret - IMS Client Secret from ADC project's OAuth Server-to-Server Integration * @param {*} scopes - IMS Meta Scopes from ADC project's OAuth Server-to-Server Integration as comma separated strings * @returns {string} - Returns the IMS Access Token */ async function getIMSAccessToken(clientId, clientSecret, scopes) { const adobeIMSV3TokenEndpointURL = 'https://ims-na1.adobelogin.com/ims/token/v3'; const options = { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: `grant_type=client_credentials&client_id=${clientId}&client_secret=${clientSecret}&scope=${scopes}`, }; const response = await fetch(adobeIMSV3TokenEndpointURL, options); const responseJSON = await response.json(); return responseJSON.access_token; } async function updateAEMAssetMetadata(metadataDetails, aemAssetEvent, params) { ... // Transform the metadata details to JSON Patch format, // see https://developer.adobe.com/experience-cloud/experience-manager-apis/api/experimental/assets/author/#operation/patchAssetMetadata const transformedMetadata = Object.keys(metadataDetails).map((key) => ({ op: 'add', path: `wknd-${key.toLowerCase()}`, value: metadataDetails[key], })); ... // Get ADC project's OAuth Server-to-Server Integration credentials const clientId = params.ADC_CECREDENTIALS_CLIENTID; const clientSecret = params.ADC_CECREDENTIALS_CLIENTSECRET; const scopes = params.ADC_CECREDENTIALS_METASCOPES; // Get IMS Access Token using Client Credentials Flow const access_token = await getIMSAccessToken(clientId, clientSecret, scopes); // Call AEM Author service to update the metadata using Assets Author API // See https://developer.adobe.com/experience-cloud/experience-manager-apis/api/experimental/assets/author/ const res = await fetch(`${aemAuthorHost}/adobe/assets/${assetId}/metadata`, { method: 'PATCH', headers: { 'Content-Type': 'application/json-patch+json', 'If-Match': '*', 'X-Adobe-Accept-Experimental': '1', 'X-Api-Key': 'aem-assets-management-api', // temporary value Authorization: `Bearer ${access_token}`, }, body: JSON.stringify(transformedMetadata), }); ... } module.exports = { updateAEMAssetMetadata };
The
.env
file stores the ADC Project’s OAuth Server-to-Server credentials details, and they are passed as parameters to the action usingext.config.yaml
file. Refer to the App Builder Configuration Files for managing secrets and action parameters. -
The
src/dx-excshell-1/actions/model
folder containsaemAssetEvent.js
anderrors.js
files, which are used by the action to parse the received event and handle errors respectively. -
The
src/dx-excshell-1/actions/generic/index.js
file uses the above mentioned modules to orchestrate the metadata retrieval and update.... let responseMsg; // handle the challenge probe request, they are sent by I/O to verify the action is valid if (params.challenge) { logger.info('Challenge probe request detected'); responseMsg = JSON.stringify({ challenge: params.challenge }); } else { logger.info('AEM Asset Event request received'); // create AEM Asset Event object from request parameters const aemAssetEvent = new AEMAssetEvent(params); // Call mock PIM API to get the product data such as SKU, Supplier, etc. const mockPIMData = await mockPIMAPI.getPIMData( aemAssetEvent.getAssetName(), ); logger.info('Mock PIM API response', mockPIMData); // Update PIM received data in AEM as Asset metadata const aemUpdateStatus = await updateAEMAssetMetadata( mockPIMData, aemAssetEvent, params, ); logger.info('AEM Asset metadata update status', aemUpdateStatus); if (aemUpdateStatus) { // create response message responseMsg = JSON.stringify({ message: 'AEM Asset Event processed successfully, updated the asset metadata with PIM data.', assetdata: { assetName: aemAssetEvent.getAssetName(), assetPath: aemAssetEvent.getAssetPath(), assetId: aemAssetEvent.getAssetId(), aemHost: aemAssetEvent.getAEMHost(), pimdata: mockPIMData, }, }); } // response object const response = { statusCode: 200, body: responseMsg, }; // Return the response to the caller return response; ... }
-
Deploy the updated action to Adobe I/O Runtime using the following command:
$ aio app deploy
Create and apply asset metadata schema
By default, the WKND Sites project does not have the asset metadata schema to display the PIM specific metadata like SKU, Supplier Name, etc. Let’s create and apply the asset metadata schema to an asset folder in the AEM instance.
-
Log in to the AEM as a Cloud Service Asset instance and be in the Asset view.
-
Navigate to the Settings > Metadata Forms option from the left rail and click the Create button. In the Create Metadata Form dialog, enter the following details and click Create.
- Name:
PIM
- Use existing form structure as template:
Check
- Choose from:
default
- Name:
-
Click the + icon to add a new PIM tab and add Single Line Text components to it.
The following table lists the metadata properties and their corresponding fields.
LabelPlaceholderMetadata propertySKUAuto populated via AEM Eventing integrationwknd-skuid
Supplier NameAuto populated via AEM Eventing integrationwknd-suppliername
-
Click Save and Close to save the metadata form.
-
Finally, apply the PIM metadata schema to the PIM folder.
With the above steps, the assets from the Adventures folder are ready to display the PIM specific metadata like SKU, Supplier Name, etc.
Asset upload and metadata verification
To verify the AEM Assets and PIM integration, upload an asset to the Adventures folder in AEM Assets. The PIM tab in the asset details page should display the SKU and Supplier Name metadata.
Concept and key takeaways
The asset metadata synchronization between AEM and other systems like PIM are often required in the enterprise. Using AEM Eventing such requirements can be achieved.
- The asset metadata retrieval code is executed outside of AEM, avoiding the load on the AEM Author service, thus an event-driven architecture that scales independently.
- The newly introduced Assets Author API is used to update the asset metadata in AEM.
- The API authentication uses OAuth server-to-server (aka client credentials flow), see OAuth Server-to-Server credential implementation guide.
- Instead of Adobe I/O Runtime Actions, other webhooks or Amazon EventBridge can be used to receive the AEM Assets event and process the metadata update.
- Asset Events via AEM Eventing empower businesses to automate and streamline critical processes, fostering efficiency and coherence across the content ecosystem.