HI @divyat3
In AEM 6.5, by the time `DamEvent.Type.ORIGINAL_UPDATED` or `METADATA_UPDATED` is triggered, the asset’s metadata has already been replaced, making it too late to capture the original values. To preserve existing metadata before it gets overwritten during a re-upload, you need to intercept the process earlier—before the asset is persisted. While customizing the Asset Upload Servlet is one way, a more stable and maintainable approach is to insert a custom step at the beginning of the DAM Update Asset workflow to back up the existing metadata before any update occurs.
Try this custom workflow
public class BackupMetadataStep implements WorkflowProcess {
@Reference
private ResourceResolverFactory resolverFactory;
private static final Logger log = LoggerFactory.getLogger(BackupMetadataStep.class);
@Override
public void execute(WorkItem workItem, WorkflowSession session, MetaDataMap args) throws WorkflowException {
String payloadPath = workItem.getWorkflowData().getPayload().toString();
try (ResourceResolver resolver = resolverFactory.getServiceResourceResolver(
Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, "datawrite"))) {
Resource metadataRes = resolver.getResource(payloadPath + "/jcr:content/metadata");
if (metadataRes != null) {
ValueMap metadataMap = metadataRes.adaptTo(ValueMap.class);
// Optional: save metadata into a backup node
Resource parent = resolver.getResource(payloadPath + "/jcr:content");
if (parent != null && !parent.hasChild("metadataBackup")) {
Node parentNode = parent.adaptTo(Node.class);
Node backupNode = parentNode.addNode("metadataBackup", "nt:unstructured");
for (Map.Entry<String, Object> entry : metadataMap.entrySet()) {
if (entry.getValue() instanceof String) {
backupNode.setProperty(entry.getKey(), (String) entry.getValue());
}
// Add more type checks if needed
}
resolver.commit();
log.info("Metadata backed up for {}", payloadPath);
}
}
} catch (LoginException | PersistenceException | RepositoryException e) {
log.error("Error while backing up metadata for " + payloadPath, e);
}
}
}
Hope this helpful.:)
Regards,
Karishma.
Hi @karishma_begumsh
I tried to insert a process step at the beginning of the OOTB Asset Update workflow, but it didn't work. Even after placing the process step at the start of the workflow, the metadata is already overwritten, and I do not have access to the old metadata values. Below is the code I tried (with the property value hardcoded for testing). However, neither the old metadata nor the `metadataBackup` node exists when re-uploading or replacing the asset.
Please let me know if I am doing something wrong.
import com.adobe.granite.workflow.WorkflowException;
import com.adobe.granite.workflow.WorkflowSession;
import com.adobe.granite.workflow.exec.WorkItem;
import com.adobe.granite.workflow.exec.WorkflowProcess;
import com.adobe.granite.workflow.metadata.MetaDataMap;
import com.marketing.core.workflow.utility.ResourceResolverUtils;
import org.apache.sling.api.resource.*;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Node;
import java.util.Map;
import java.util.Objects;
@Component(
service = WorkflowProcess.class,
property = {
"process.label=Custom BackupMetadataStep"
}
)
public class BackupMetadataStep implements WorkflowProcess {
@Reference
private ResourceResolverFactory resolverFactory;
private static final Logger log = LoggerFactory.getLogger(BackupMetadataStep.class);
@Override
public void execute(WorkItem workItem, WorkflowSession session, MetaDataMap args) throws WorkflowException {
String payloadPath = workItem.getWorkflowData().getPayload().toString();
// Extract the base asset path (e.g., /content/dam/.../test.pdf)
String baseAssetPath = extractBaseAssetPath(payloadPath);
try (ResourceResolver resolver = ResourceResolverUtils.getDefaultServiceResourceResolver(resolverFactory)) {
Resource metadataResource = resolver.getResource(baseAssetPath + "/jcr:content/metadata");
Resource metadataBackupResource = resolver.getResource(baseAssetPath + "/jcr:content/metadataBackup");
if (metadataResource != null) {
ValueMap metadataMap = Objects.requireNonNull(metadataResource.adaptTo(ValueMap.class));
String docID = Objects.requireNonNull(metadataMap).get("DocumentId", String.class);
log.info("Existing metadata for {}: {}", payloadPath, docID);
ValueMap metadataBackUpMap = null;
if (metadataBackupResource != null) {
metadataBackUpMap = Objects.requireNonNull(metadataBackupResource.adaptTo(ValueMap.class));
String documentId = Objects.requireNonNull(metadataBackUpMap).get("DocumentId", String.class);
log.info("Existing metadataBackup for {}: {}", payloadPath, documentId);
}
// Optional: save metadata into a backup node
Resource parent = resolver.getResource(baseAssetPath + "/jcr:content");
if (parent != null && parent.getChild("metadataBackup") == null) {
Node parentNode = parent.adaptTo(Node.class);
Node backupNode = parentNode.addNode("metadataBackup", "nt:unstructured");
backupNode.setProperty("DocumentId", "12345");
resolver.commit();
log.info("Metadata backed up for {}", payloadPath);
}
}
} catch (Exception e) {
log.error("Error while backing up metadata for " + baseAssetPath, e);
}
}
}
Thank you.