How to upload multiple files in aem from java

Qamar_khan 11-02-2019

Hello All,

              Once again I need help to upload multiple asset files into  AEM dam/content/MyParentFolder/MyCustomFiles/File.jpg  path level.

1. My case is

  • I am creating a MyCustomFiles sling folder to save the files under the MyParentFolder folder.
  •   Adding Node resNode = FolderNode.addNode("jcr:content", "dam:AssetContent");
  • then session.save();
  • After sending the path with files to method readMultiPartFormData( request, FileName,FileID,FilePath) as

try

         {

         final boolean isMultipart = org.apache.commons.fileupload.servlet.ServletFileUpload.isMultipartContent(request);

           if (isMultipart) {

             final java.util.Map<String, org.apache.sling.api.request.RequestParameter[]> params = request.getRequestParameterMap();

             

             for (final java.util.Map.Entry<String, org.apache.sling.api.request.RequestParameter[]> pairs : params.entrySet()) {

               

                 final org.apache.sling.api.request.RequestParameter[] pArr = pairs.getValue();

               

                 final org.apache.sling.api.request.RequestParameter param0 = pArr[0];

                 

                 //Determine if the posted value is a file or the JCR Path

                 boolean formField = param0.isFormField(); //Is this a form field or a posted file

                 

                 if (formField)

                 {

                     String libLoc = path;

                     clientLibPath = libLoc ; //Set the class member - its the first posted value from the client

                 }

                 else

                 {

                     // final org.apache.sling.api.request.RequestParameter param1 = pArr[1];

                  final InputStream stream = param0.getInputStream();

                  String mimeType = param0.getContentType();

               

                  //Save the uploaded file into the Adobe CQ DAM

                  return writeToClientLib(stream,param0.getFileName(),clientLibPath,mimeType,JFileID);

                 }

             }

          }

  • After this calling

try

{

    //Invoke the adaptTo method to create a Session

    ResourceResolver resourceResolver = resolverFactory.getAdministrativeResourceResolver(null);

    session = resourceResolver.adaptTo(Session.class);

    session.refresh(true);

   

     String uuid=UUID.randomUUID().toString();

    Calendar lastModified = Calendar.getInstance();

    lastModified.setTimeInMillis(lastModified.getTimeInMillis());

    Node node = session.getNode(path); 

    javax.jcr.ValueFactory valueFactory = session.getValueFactory();            

    javax.jcr.Binary contentValue = valueFactory.createBinary(is);           

    Node fileNode = node.addNode(fileName, "dam:Asset");

    fileNode.addMixin("mix:referenceable");

  

    Node resNode = fileNode.addNode("jcr:content", "dam:AssetContent");

   

    Node metadata=resNode.addNode("metadata", "nt:unstructured");

    metadata.setProperty("dc:format", mimetype);

    metadata.setProperty("dam:size", contentValue.getSize());

    Node related=resNode.addNode("related", "nt:unstructured");   

    Node renditions=resNode.addNode("renditions", "nt:folder");   

    Node renditionsChild=renditions.addNode("original", "nt:file");

    Node renditionsChildJcr=renditionsChild.addNode("jcr:content", "nt:unstructured");

    renditionsChildJcr.setProperty("jcr:data", contentValue);

    renditionsChildJcr.setProperty("jcr:lastModified", lastModified);

    renditionsChildJcr.setProperty("jcr:lastModifiedBy", session.getUserID());

    renditionsChildJcr.setProperty("jcr:mimeType", "application/xml");

    renditionsChildJcr.setProperty("jcr:uuid", uuid);

    session.save();          

    // Return the path to the document that was stored in CRX.

    return fileNode.getIdentifier();

}

Its working perfectly but when we were doing load testing we were getting exception as

OakConstraint004 error :No matching property definiation found for jcr:predecessors = []

We have resolved it by this code

private String writeToDam(InputStream is, String fileName)

{

    Map<String, Object> param = new HashMap<String, Object>();

    param.put(ResourceResolverFactory.SUBSERVICE, "datawrite");

    ResourceResolver resolver = null;

      

    try {

                 

        //Invoke the adaptTo method to create a Session used to create a QueryManager

        resolver = resolverFactory.getServiceResourceResolver(param);

      

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

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

        String newFile = "/content/dam/travel/"+fileName ;

        assetMgr.createAsset(newFile, is,"image/jpeg", true);

    

        // Return the path to the file was stored

        return newFile;

}

NOW ON LOAD TESTING WE ARE FACING THE EXCEPTION AS

{"result":{"httpstatuscode":500,"stacktrace":"string","message":"OakState0001: Unresolved conflicts in /content/dam/MY CUSTOMPATH,"codeorigin":"string","status":"EXCEPTION"}}

Can someone help me out on this

Thanks

Qamar

Accepted Solutions (1)

Accepted Solutions (1)

gauravb41175071
MVP
12-02-2019

You're getting this exception probably because your automation scripts are trying to save same image at same location with concurrent threads. Modify your code accordingly-

Try -

  • modify image name, add a suffix so that it gets treated as a new image each time or otherwise
  • Use session.refresh(true) and add a delay (thread.sleep(2000))

AEM anti pattern: Long running sessions | Things on a content management system

** you should change the admin session to a service-user based session - resolverFactory.getAdministrativeResourceResolver(null);

Answers (3)

Answers (3)

Qamar_khan 11-02-2019

Hi, Thanks for your reply.

                 Yes, we are able to write asset to given JCR location but in the case for load testing or uploading files continuously we are facing this exception OakState0001: Unresolved conflicts.

Can you help me on this what is going wrong or will it require some other way?

Thanks

Qamar

smacdonald2008 11-02-2019

First - you are correct - you should use AssetManager API as opposed to NODE API when working with Assets.

WHen you use the AssetManager API - such as :

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

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

        String newFile = "/content/dam/travel/"+fileName ;

        assetMgr.createAsset(newFile, is,"image/jpeg", true);

This should be writing the Asset to the given JCR location.