Expand my Community achievements bar.

SOLVED

I need to export content fragments to target through custom workflow

Avatar

Level 2

I have a project where content fragments need to be automatically exported as JSON to a target location upon creation via a custom workflow. The JSON format should match what is generated when accessing the URL: http://localhost:4502/api/assets/contentfragment.model.json.

However, I am facing an issue where I can't replicate the exact JSON format needed for export. Despite my efforts with the code below, the resource resolver is unable to recognise the resource at api/assets.

Resource modelJsonResource = resolver.getResource("http://localhost:4502/api/assets/contentfragment.model.json");
            if (modelJsonResource != null) {
InputStream jsonContent = modelJsonResource.adaptTo(InputStream.class); if (jsonContent != null) {
sendToTarget(jsonContent); } }


Could someone help me achieve the expected JSON output?

1 Accepted Solution

Avatar

Correct answer by
Level 9

Hi @harshak11490245 ,

Okay, got it. So, you can send request to AEM publisher/dispatcher from AEM using HTTP client.

 

@Component
public class MyHttpClient {

    @OSGiService
    private HttpClientBuilderFactory httpClientBuilderFactory;

    public void executeHttpRequest() {
        try (CloseableHttpClient httpClient = httpClientBuilderFactory.newBuilder().build()) {
            // Perform HTTP operations with httpClient
            HttpGet httpGet = new HttpGet(aemHost 
 + "/api/assets/contentfragment.model.json");
            getRequest.addHeader("Content-Type", "application/json");

            CloseableHttpResponse response = httpClient.execute(getRequest);
            int statusCode = response.getStatusLine().getStatusCode();
            String jsonString = response.getEntity() == null
                        ? "" : IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
            // process JSON string

        } catch (IOException e) {
            // Handle exceptions
        }
    }
}

 

NOTE: you need to properly get AEM host.

 

Best regards,

Kostiantyn Diachenko.

 

View solution in original post

8 Replies

Avatar

Level 9

Hi @harshak11490245 ,

 

Your resource resolver can't recognize URL. You should find content fragment by path e.g. /content/dam/wknd-shared/en/adventures/napa-wine-tasting/napa-wine-tasting, adapt to ContentFragment model and export it with Jackson exporter.

 

Below you can find a code an example of OSGi component how to get Content Fragment in JSON programmatically:

@Component
public class CfConverter {
   @Reference
   private org.apache.sling.models.factory.ModelFactory modelFactory;

   public String exportCfInJSON(ResourceResolver resourceResolver, String cfPath) {
       Resource cfResource = resourceResolver.getResource(cfPath);
       if (cfResource == null) {
           return null;
       }
       ContentFragment model = cfResource.adaptTo(com.adobe.cq.dam.cfm.ContentFragment.class)
       if (model == null) {
           return null;
       }
       return modelFactory.exportModel(model, 'jackson', String.class, Map.of());
   }
}

 

Best regards,

Kostiantyn Diachenko.

Hi @konstantyn_diachenko thank you for your reply, I tried your suggestion but ended up with the below error message for the below line.

return modelFactory.exportModel(model, 'jackson', String.class, Map.of());


unreported exception org.apache.sling.models.factory.Export Exception; must be caught or declared to be thrown. Not sure what is the issue.

Can you please provide a stack trace? Or increase logging level to get more details about this exception.

Thank you @konstantyn_diachenko . Finally I was able to resolve all the exceptions and getting the json output. But the output is not exactly like the api/assets json format.

Avatar

Correct answer by
Level 9

Hi @harshak11490245 ,

Okay, got it. So, you can send request to AEM publisher/dispatcher from AEM using HTTP client.

 

@Component
public class MyHttpClient {

    @OSGiService
    private HttpClientBuilderFactory httpClientBuilderFactory;

    public void executeHttpRequest() {
        try (CloseableHttpClient httpClient = httpClientBuilderFactory.newBuilder().build()) {
            // Perform HTTP operations with httpClient
            HttpGet httpGet = new HttpGet(aemHost 
 + "/api/assets/contentfragment.model.json");
            getRequest.addHeader("Content-Type", "application/json");

            CloseableHttpResponse response = httpClient.execute(getRequest);
            int statusCode = response.getStatusLine().getStatusCode();
            String jsonString = response.getEntity() == null
                        ? "" : IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
            // process JSON string

        } catch (IOException e) {
            // Handle exceptions
        }
    }
}

 

NOTE: you need to properly get AEM host.

 

Best regards,

Kostiantyn Diachenko.

 

This is working fine with publisher URL. Thank you @konstantyn_diachenko 

Avatar

Level 5

 Hi @harshak11490245   Replicating the json structure that you want is easy when you use grapql. Create a graphql query in the json format you need and call the graphql endpoint progrmatically by passing the path of content fragment as a parameter and then graphql will give you exact json format as defined in the query. You can take this endpoint response and you can create the json files in the target path by using the response from graphql directly. 

Avatar

Level 2

Hi @Uppari_Ramesh Thank you for your reply, for this project we need the output exactly like api assets json format.