Expand my Community achievements bar.

SOLVED

MSRP - How to CRUD image/file attachments?

Avatar

Level 5

Hi all,

Does there exist an example usage of storing/reading an attachment through the SRP API?

With the how-to samples on Github, specifically the TodoMVC sample[1], I've been able to figure out how to CRUD UGC in MongoDB through the SRP API in our custom components. However, I'm really not sure how to, or what the best practices are for, upload image attachments from custom UGC components.

Right now I'm using the same method I wrote for storing the post but one level down, with a random md5 hash of the current timestamp + filename, and storing the image data as a byte array. This just throws it into the same collection as the rest of the UGC though, and just looking at the Storage Configuration options, there's clearly a separate collection just for attachments.

Thanks for any and all help!

[1] https://github.com/Adobe-Marketing-Cloud/aem-communities-todomvc-sample

1 Accepted Solution

Avatar

Correct answer by
Level 2

Let me take a crack at this. In the ToDoMVC sample, there's an example of using srp.create(), which is probably what you're using to write to SRP. You can use the same API to create attachments.

This is roughly the pseudocode to add an attachment to a resource named "resource".

Map<String, Object> attachmentProps = new HashMap<String, Object>();
attachmentProps.put("nt:file", inputStream); // java.io.InputStream
attachmentProps.put("mimetype", mimeType); // String
attachmentProps.put(SocialUtils.PN_PARENTID, resource.getPath());
attachmentProps.put("name", fileName); // String

String attachmentPath = resource.getPath() + "/" + fileName;

Resource attachmentResource = srp.create(resource.getResourceResolver(), attachmentPath, attachmentProps);

List<String> attachments = new ArrayList<String>();

attachments.add(attachmentResource.getPath());

ValueMap vm = resource.adaptTo(ModifiableValueMap.class);

vm.put("attachments", attachments.toArray(new String[0])); // keep track of the attachments in the resource, so you can read them back

 

This will create attachments like the way it's done in the Social Comments component.

View solution in original post

8 Replies

Avatar

Level 5

JK Kendall wrote...

Hi Greg,

Have you explored the file library component?

- JK

 

No, I haven't yet. We're updating our own custom components to utliize the new SRP API instead of custom JCR-based UGC with Forward/Reverse Replication workflows (it's awful...). Just trying to figure out how to handle file/attachment storage with the SRP API.

This is a helpful link and I'll keep looking through the File Library Client API[1] but seeing the function names only helps so much. Seeing what SRP API methods are actually called with what values would be extremely helpful. Any chance there's a github project with sample uses of this? Or one in the works that isn't published yet?

Easier yet... Is there a SocialResourceProvider specific to attachments that I can use to simply "srp.create(resourceResolver, storagePath, propertyMap);" for attachments? That would be the easiest thing.

[1] https://docs.adobe.com/docs/en/aem/6-2/develop/ref/javadoc/com/adobe/cq/social/filelibrary/client/ap...

Avatar

Level 1

Hi Greg,

Am curious about the custom component that you are implementing using SRP. Would it be possible to share what your use case is? Most times, UGC based components can be built as extensions to the Comment System APIs or Forum APIs instead of building a component from scratch. This will give you various capabilities that are available in our OOTB components without you having to talk to SRP APIs directly (for the most part).

We do not have a public sample of storing attachments in SRP yet. Its a good suggestion and we will add it to our todo list.

I will also try to get you a snippet to show how we add attachments via the SRP API.

Avatar

Level 5

Siddharth_Palaniswami wrote...

Hi Greg,

Am curious about the custom component that you are implementing using SRP. Would it be possible to share what your use case is? Most times, UGC based components can be built as extensions to the Comment System APIs or Forum APIs instead of building a component from scratch. This will give you various capabilities that are available in our OOTB components without you having to talk to SRP APIs directly (for the most part).

 

Hi, we're actually working on converting existing components that we had already written to utilize the SRP API. Figured it would be easier to just update our code to change how we're storing content to use the SocialResourceProvider to interface with MongoDB, since before we were just creating JCR-based UGC nodes/properties. That's the primary reason we didn't just extend OOTB components, thinking it would be less work overall, given that extending the OOTB components would require a whole different structure of code and all of the reskinning on the front-end. They're also, if I'm not mistaken, all *.hbs handlebars-based and have their own JS that makes it work. We have a ton of custom JS on the front-end as well that we would need to figure out how to incorporate into your Backbone framework. It just seemed like a way bigger headache to try to convert everything and keep it working the exact same way, than to simply update the current back-end code how it's reading/storing the data (to MongoDB instead of pre-SRP JCR).

The particular component I'm working on for this project is a message board of sorts, specifically for posting wanted/forsale ads, with pictures and contact information. We also have a custom modal gallery when you click on the picture thumbnails so that you can view the larger images, scrolling left/right through them if you want. Everything works perfectly as-is except we're storing everything in the JCR and using Forward/Reverse Replication to keep everything in sync across the publishers, which is TERRIBLE. In the process of upgrading AEM from 5.6.1 to 6.2, we're also trying to update this code to utilize the SRP API (specifically for MSRP) as well.

Siddharth_Palaniswami wrote...

I will also try to get you a snippet to show how we add attachments via the SRP API.

 

That would be incredibly helpful, I can't wait, thank you!

Avatar

Level 5

Siddharth_Palaniswami wrote...

I will also try to get you a snippet to show how we add attachments via the SRP API. 

 

Hi Siddharth,

Just wondering if you were able to share that snippet? It's pretty crucial for a service I'm working on right now.

Thanks in advance!

Avatar

Correct answer by
Level 2

Let me take a crack at this. In the ToDoMVC sample, there's an example of using srp.create(), which is probably what you're using to write to SRP. You can use the same API to create attachments.

This is roughly the pseudocode to add an attachment to a resource named "resource".

Map<String, Object> attachmentProps = new HashMap<String, Object>();
attachmentProps.put("nt:file", inputStream); // java.io.InputStream
attachmentProps.put("mimetype", mimeType); // String
attachmentProps.put(SocialUtils.PN_PARENTID, resource.getPath());
attachmentProps.put("name", fileName); // String

String attachmentPath = resource.getPath() + "/" + fileName;

Resource attachmentResource = srp.create(resource.getResourceResolver(), attachmentPath, attachmentProps);

List<String> attachments = new ArrayList<String>();

attachments.add(attachmentResource.getPath());

ValueMap vm = resource.adaptTo(ModifiableValueMap.class);

vm.put("attachments", attachments.toArray(new String[0])); // keep track of the attachments in the resource, so you can read them back

 

This will create attachments like the way it's done in the Social Comments component.

Avatar

Level 5

calvin.wong wrote...

Let me take a crack at this. In the ToDoMVC sample, there's an example of using srp.create(), which is probably what you're using to write to SRP. You can use the same API to create attachments.

This is roughly the pseudocode to add an attachment to a resource named "resource".

Map<String, Object> attachmentProps = new HashMap<String, Object>();
attachmentProps.put("nt:file", inputStream); // java.io.InputStream
attachmentProps.put("mimetype", mimeType); // String
attachmentProps.put(SocialUtils.PN_PARENTID, resource.getPath());
attachmentProps.put("name", fileName); // String

String attachmentPath = resource.getPath() + "/" + fileName;

Resource attachmentResource = srp.create(resource.getResourceResolver(), attachmentPath, attachmentProps);

List<String> attachments = new ArrayList<String>();

attachments.add(attachmentResource.getPath());

ValueMap vm = resource.adaptTo(ModifiableValueMap.class);

vm.put("attachments", attachments.toArray(new String[0])); // keep track of the attachments in the resource, so you can read them back

 

This will create attachments like the way it's done in the Social Comments component.

 

Thanks for the overview, will modify my code and report back. For some reason, I thought maybe it had something to do with a different SocialResourceConfiguration of the SocialResourceProvider used to store attachments.

Avatar

Level 5

Thanks again Calvin, that absolutely worked.

Whether it was storing the value as an InputStream instead of a byte array (byte[]) or storing the key as "nt:file" (JcrConstants.NT_FILE), it worked.

 

As an aside... I'm still extremely confused on what some of the key mappings are between Java and MongoDB. For example, "mimetype" all lowercase translates to "content-type" through the SRP API. These pieces are extremely unclear and not straight forward at all. :(