resource adapted to ContentFragment throws null in AEM service Impl | Community
Skip to main content
Nikhil-Kumar
Community Advisor
Community Advisor
November 22, 2022
Solved

resource adapted to ContentFragment throws null in AEM service Impl

  • November 22, 2022
  • 3 replies
  • 4479 views

Hi All,

In my aem service impl, when I am adapting my resource to ContentFragment Object it returns null CF object.
Although my resource is not null and I can see my resource path as well. 

Thanks!

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by Nikhil-Kumar

At the end figures out the issue, I know it was a blunder, 
I guess the issue was that we need to give permissions to /conf/myproject along with /content/dam/project.
And I guess CF api ONLY works when we have access to both. Rather Node and Resource API work with only access to /content/dam

3 replies

krati_garg
Adobe Employee
Adobe Employee
November 22, 2022

@nikhil-kumar Try validating from below Code Snippet

https://engineering.icf.com/aem-content-fragments-as-an-api/#:~:text=Creating%20a%20content%20fragment%20API

 

If it is still not resolved, kindly share your Code Snippet

Nikhil-Kumar
Community Advisor
Community Advisor
November 22, 2022

@krati_garg - Yes I am trying the same approach, but it gives null values after adapting the resource to CF.

Here is my code snippet:

package com.myproject.core.services.impl;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Base64;
import java.util.Collections;
import java.util.Enumeration;
import org.apache.sling.api.resource.LoginException;
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.serviceusermapping.ServiceUserMapped;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.propertytypes.ServiceRanking;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jcr.query.Query;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.metatype.annotations.AttributeDefinition;
import org.osgi.service.metatype.annotations.AttributeType;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.adobe.cq.dam.cfm.ContentElement;
import com.adobe.cq.dam.cfm.ContentFragment;
import com.day.cq.commons.Externalizer;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.myproject.core.models.TeamMemberContentFragment;
import com.myproject.core.services.SearchService;

import com.myproject.core.services.TeamMemberPageService;
import com.myproject.core.utils.LinkUtils;
import org.apache.sling.api.resource.ResourceResolver;
import java.util.Optional;
import com.adobe.cq.dam.cfm.FragmentTemplate;

@Component(immediate = true, service = TeamMemberPageService.class, name = "com.myproject.core.services.TeamMemberPageService", configurationPolicy = ConfigurationPolicy.REQUIRE, property = {
"service.vendor=myproject", "service.description=myproject - Team Member Service" })
@Designate(ocd = TeamMemberPageServiceImpl.Config.class)
public class TeamMemberPageServiceImpl implements TeamMemberPageService {

public static final Logger LOGGER = LoggerFactory.getLogger(TeamMemberPageService.class);

@ObjectClassDefinition(name = "myproject - Team Mmeber Service Configuration", description = "Configuration for Team Mmeber Service Configuration.")
public @interface Config {

@AttributeDefinition(name = "Enable Create Bio Page", description = "This enables Create Dynamic Bio Page.", type = AttributeType.BOOLEAN)
public boolean enableCreateBioPage();

@AttributeDefinition(name = "Team Mmeber Source Content Fragment Path", description = "Team Mmeber Source Content Fragment Path.")
String teamMemeberSourceCfPath()

default "/content/dam/myproject/content-fragments/team-members";

@AttributeDefinition(name = "Team Mmeber Destination Page Path", description = "Team Mmeber Destination Page Path.")
String teamMemeberDestinationPagePath()

default "/content/myproject/us/en/team-members";

}

private Config config;



@Reference
private ResourceResolverFactory resourceResolverFactory;

@Activate
public void activate(Config config) {
this.config = config;

}

private Optional<ContentFragment> contentFragment;

@Override
public void createTeamMmeberPages(String path) {
LOGGER.info("Inside the Teams Service");

final Map<String, Object> authInfo = Collections.singletonMap(
ResourceResolverFactory.SUBSERVICE, "readWriteServiceUser");

try (ResourceResolver serviceResolver = resourceResolverFactory.getServiceResourceResolver(authInfo)) {

Resource resource = serviceResolver
.resolve(path);

LOGGER.info("Resource OBJECT: {} " + resource);
LOGGER.info("Resource Value: {} " + resource.getPath());

contentFragment = Optional.ofNullable(resource.adaptTo(ContentFragment.class));

LOGGER.info("CF: {} " + contentFragment);

String cfValue = contentFragment
.map(cf -> cf.getElement("name"))
.map(ContentElement::getContent)
.orElse(StringUtils.EMPTY);

LOGGER.info("content cf: {} " + cfValue);


} catch (LoginException e) {
LOGGER.error("Login Exception when obtaining a User for the Bundle Service: {} ", e);
}

}

}

krati_garg
Adobe Employee
Adobe Employee
November 22, 2022

Also, I can adapt my resource to a Node without any issue in my service impl. But it doesn't resolve the resource to ContentFragment in my service impl.

It's bit weird! 


Hi @nikhil-kumar 

With above comment, it feels the service user does not have required access to adapt to a Content Fragment, and just default JCR permissions.

Can you please share the ACL permissions for the readWriteServiceUser, especially over content/dam?

It should have required read/write access over Content Fragment Folder, you are trying to access in the code.

Abhishek_Narula25
Level 3
November 22, 2022

Try using below code, if you have the request object:

 

  • import org.apache.sling.models.factory.ModelFactory;
  • @OSGiService

         private ModelFactory modelFactory;

  • ContentFragment cf = modelFactory.getModelFromWrappedRequest(request, resource, ContentFragment.class);

https://github.com/kiransg89/LinkedContentFragment/blob/main/LinkedContentFragmentImpl.java

 

Maybe this might help!

Nikhil-Kumar
Community Advisor
Community Advisor
November 22, 2022

Nope this didn't helped!

SantoshSai
Community Advisor
Community Advisor
November 22, 2022

Hi @nikhil-kumar ,

Can you try this?

ContentFragment CF = resourceResolver.getResource(path).adaptTo(ContentFragment.class);

or in your case

Resource resource = serviceResolver.getResource(path); //instead .resolve(path);

Regards,

Santosh

Santosh Sai
Nikhil-Kumar
Community Advisor
Nikhil-KumarCommunity AdvisorAuthorAccepted solution
Community Advisor
November 23, 2022

At the end figures out the issue, I know it was a blunder, 
I guess the issue was that we need to give permissions to /conf/myproject along with /content/dam/project.
And I guess CF api ONLY works when we have access to both. Rather Node and Resource API work with only access to /content/dam

krati_garg
Adobe Employee
Adobe Employee
November 23, 2022

Almost inline with my last comment. Hope you read it, before finding it on your own. Could have saved some of your time @nikhil-kumar