Expand my Community achievements bar.

SOLVED

Copy Assets from Crx to Physical server location

Avatar

Level 3

I am trying to Copy the asstes from crx to physical server location based on their Metadata (ex release date). So based on the Metadata a listener has to create a scheduler and deploy it to the physical server.

package sampleforms.core.listener;

import java.io.Serializable;

import java.util.Calendar;

import java.util.Date;

import java.util.HashMap;

import java.util.Map;

import javax.jcr.Node;

import javax.jcr.Property;

import javax.jcr.RepositoryException;

import javax.jcr.Session;

import javax.jcr.observation.Event;

import javax.jcr.observation.EventIterator;

import javax.jcr.observation.EventListener;

import javax.jcr.observation.ObservationManager;

import org.apache.jackrabbit.api.observation.JackrabbitEventFilter;

import org.apache.jackrabbit.api.observation.JackrabbitObservationManager;

import org.apache.sling.api.resource.Resource;

import org.apache.sling.api.resource.ResourceResolver;

import org.apache.sling.api.resource.ResourceResolverFactory;

import org.apache.sling.commons.scheduler.Scheduler;

import org.apache.sling.jcr.api.SlingRepository;

import org.osgi.service.component.ComponentContext;

import org.osgi.service.component.annotations.Component;

import org.osgi.service.component.annotations.Reference;

import org.osgi.service.metatype.annotations.AttributeDefinition;

import org.osgi.service.metatype.annotations.Designate;

import org.osgi.service.metatype.annotations.ObjectClassDefinition;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.day.cq.dam.api.Asset;

import com.day.cq.dam.api.Rendition;

@Component(immediate = true, service = EventListener.class)

public class DeployAssetsHandler implements EventListener {

private final Logger logger = LoggerFactory.getLogger(getClass());

// Inject a Sling ResourceResolverFactory

@Reference

private ResourceResolverFactory resolverFactory;

private Session observationSession = null;

private JackrabbitObservationManager observationManager;

@Reference

private SlingRepository repository;

@Reference

private Scheduler scheduler;

    public static final String DEPLOY_DATE_PROPERTY = "deploy_date";

private String damPathImages;

private String serverPathImages;

private final String[] nodeTypes = new String[] { "nt:unstructured" };

// Place app logic here to define the AEM Custom Event Handler

protected void activate() {

damPathImages = "/content/dam/images";

serverPathImages = "Physical server location";

logger.debug("activate: DAM PATH='{}''", damPathImages);

try {

// Invoke the adaptTo method to create a Session

// ResourceResolver resourceResolver =

// resolverFactory.getAdministrativeResourceResolver(null);

observationSession = repository.loginAdministrative(null);

// Setup the event handler to respond to a new claim under

// content/claim....

observationManager = (JackrabbitObservationManager) observationSession.getWorkspace()

.getObservationManager();

JackrabbitEventFilter eventFilter = new JackrabbitEventFilter()

             .setAbsPath(damPathImages)

             .setEventTypes(Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED)

             .setIsDeep(true)

             .setNodeTypes(nodeTypes)

             .setNoLocal(false)

             .setNoExternal(false);

observationManager.addEventListener(this,eventFilter);

logger.info("Observing property changes to {} ", damPathImages);

} catch (Exception e) {

logger.error("Exception {} ", e);

}

}

protected void deactivate(ComponentContext componentContext)

throws RepositoryException {

try {

if (observationManager != null) {

observationManager.removeEventListener(this);

}

} catch (Exception e) {

logger.error("Exception {} ", e);

}

if (observationSession != null) {

observationSession.logout();

observationSession = null;

}

}

// when the event occurred.

public void onEvent(EventIterator it) {

while (it.hasNext()) {

Event event = it.nextEvent();

try {

logger.info("{} property event: ------->>>>> {}",DEPLOY_DATE_PROPERTY, event.getPath());

Property changedProperty = observationSession.getProperty(event

.getPath());

if (changedProperty.getName().equalsIgnoreCase(DEPLOY_DATE_PROPERTY)) {

Date date = changedProperty.getValue().getDate().getTime();

Date currentDate = new Date();

if (date.getTime() >= currentDate.getTime()) {

Calendar deplotDate = (Calendar) changedProperty

.getValue().getDate();

String cronExpression = deplotDate.get(Calendar.SECOND)

+ " " + deplotDate.get(Calendar.MINUTE) + " "

+ deplotDate.get(Calendar.HOUR_OF_DAY) + " "

+ deplotDate.get(Calendar.DAY_OF_MONTH) + " "

+ (deplotDate.get(Calendar.MONTH)+1) + " ? "

+ deplotDate.get(Calendar.YEAR);

logger.info("cron: {}", cronExpression);

String assetPath = event.getPath().split("/jcr:content")[0];

Node damResorce = observationSession.getNode(assetPath);

String jobName = damResorce.getName();

scheduleWork(assetPath, serverPathImages, cronExpression,jobName);

}

}

} catch (Exception e) {

logger.error(e.getMessage(), e);

}

}

}

@SuppressWarnings("deprecation")

private void scheduleWork(String assetPath,String saveLocation,String cronExpression,String jobName) {

        try {

            logger.info("In ReRegister" + jobName + " " + assetPath + " " + cronExpression);

            Map<String, Serializable> serviceProps = new HashMap<String, Serializable>();

            serviceProps.put("assetPath", assetPath);

            serviceProps.put("jobName", jobName);

            serviceProps.put("saveLocation", saveLocation);

            Runnable job = new DeployAssetsScheduler(serviceProps);

            scheduler.addJob(jobName, job, serviceProps, cronExpression, false);

            logger.info("#### Successfully re registered ####" + jobName);

        } catch (Exception e) {

            logger.error("Could not schedule work.", e);

        }

    }

public class DeployAssetsScheduler implements Runnable {

    private Map<String, Serializable> jobProperties;

public DeployAssetsScheduler(Map<String, Serializable> jobProperties) {

        logger.info("#####In my DeployAssetsScheduler constructor with property " + jobProperties.get("jobName"));

        this.jobProperties = jobProperties;

    }

    @Override

    public void run() {

        // TODO Auto-generated method stub

        logger.debug("In Job Run Method");

        String assetPath = (String) this.jobProperties.get("assetPath");

        String saveLocation = (String) this.jobProperties.get("saveLocation");

        deployAsset(assetPath, saveLocation);

    }

@SuppressWarnings("deprecation")

private void deployAsset(String assetPath,

String saveLocation) {

ResourceResolver resourceResolver = null;

try {

logger.info("entered deployAsset {}",resolverFactory);

resourceResolver = resolverFactory

.getAdministrativeResourceResolver(null);

Resource r = resourceResolver.getResource(assetPath);

Asset asset = r.adaptTo(Asset.class);

Rendition original = asset.getOriginal();

if (original != null) {

String name = asset.getName();

String newFile = saveLocation +"/"+ name;

logger.info("Asset path {}",newFile);

// Use AssetManager to place the file into the AEM DAM

com.day.cq.dam.api.AssetManager assetMgr = resourceResolver

.adaptTo(com.day.cq.dam.api.AssetManager.class);

Asset deployedAsset = assetMgr.createAsset(newFile, original.getStream(),

asset.getMimeType(), true);

logger.info("End of Deploy Asset {}",deployedAsset.getPath());

}

} catch (Exception e) {

logger.error("Exception {}", e);

} finally {

resourceResolver.close();

}

}

}

}

Can i use this code.And what type of credentials are required to Read and write in Physical server location Which is  a linux

1 Accepted Solution

Avatar

Correct answer by
Level 10

You mean on the file system of the server?

The AEM Asset Manager is used to place an asset in a CRX path - not outside of the AEM JCR.

If you want to write the file on LINUX file system as opposed to a JCR path - simply use Java File API

View solution in original post

12 Replies

Avatar

Level 10

This looks like the right approach - you can use Asset Manager API to move the assets to the AEM DAM.

Also - if you use this code in AEM 6.3/6.4 - you must white list the AEM OSGi bundle to use repository.loginAdministrative(null);

A better approach is to use a system user as shown here -- adminSession = repository.loginService("datawrite",null);.

Creating an Event Listener for Adobe Experience Manager 6.4

Avatar

Level 3

The Physical directory is also in AEM.

So some thing like from

content/dam/images  to  /apps/aemadmin/images in the Linux directory

Can I use this approach

Avatar

Level 10

As stated above - i would convert your code from repository.loginAdministrative(null) to repository.loginService("datawrite",null);. 

Creating an Event Listener for Adobe Experience Manager 6.4

Using an Event handler like this is a good approach once you change use of  repository.loginAdministrative() to repository.loginService().

Avatar

Level 10

Typically the Asset Mamager API to to place Assets in the DAM, not move from DAM to a location under /apps.

Avatar

Level 10

However - Asset Manager API has this method -

createAsset

Asset createAsset(String path, InputStream is, String mimeType, boolean doSave)

Creates a new Asset at the given path. If an asset already exists at the given path, its original rendition is updated instead of creating a new asset. If inputStream is null new Asset is created without original rendition. If an asset already exists at given path and inputstream is null, original rendition is not updated.

Parameters:
path - The path of the asset to be created.
is - The input stream of the new asset's original binary.
mimeType - The mime type of the new asset's original binary.
doSave - Whether the repository changes are saved or not.
Returns:
The newly created asset.
So as long as the path parameter is valid - this will work.

Avatar

Level 3

My goal is to copy from DAM to physical server path

Avatar

Correct answer by
Level 10

You mean on the file system of the server?

The AEM Asset Manager is used to place an asset in a CRX path - not outside of the AEM JCR.

If you want to write the file on LINUX file system as opposed to a JCR path - simply use Java File API

Avatar

Level 10

If you want to write the file on LINUX file system as opposed to a JCR path - simply use Java File API - helpful link - Java file path in Linux - Stack Overflow

Avatar

Level 10

If you need to copy an asset to a physical server path, then download the binary and use File API to copy that to a different path.

Avatar

Level 3

Hello Smacdonald2008

Right now our platform is copying the images manually to the physical drive with super administrator credentials.

By the code i am going to automate that process. What type of credentials i need to provide in the code .

Thank you

Santhosh

Avatar

Level 10

Try using the same creds in the Java code. That should work.