Custom implementation for RemoteContentRendererRequestHandler
Hello Members,
Has any one tried implementing custom usecase for RemoteContentRendererRequestHandler by following the below documentation?
Below is our implementation which works fine in local SDK but not in cloud service.
I refer to RemoteContentRendererRequestHandler defaultHandler; which is required for processing. Unfortunately this does not seem to become available and hence my custom implementation is never invoked.
I have also delayed the service activation with immediate=false which does not help
I have also tried so that my service gets activated and gets the reference when available which also does not help
@3214626(
cardinality = ReferenceCardinality.OPTIONAL,
policy = ReferencePolicy.DYNAMIC,
policyOption = ReferencePolicyOption.GREEDY
)
private volatile RemoteContentRendererRequestHandler defaultHandler;
Kindly share your thoughts on what would be wrong in this implementation
import com.adobe.cq.export.json.ComponentExporter;
import com.adobe.cq.remote.content.renderer.RemoteContentRendererRequestHandler;
import com.adobe.cq.remote.content.renderer.RemoteContentRenderingException;
import com.google.gson.JsonParser;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.sling.api.SlingHttpServletRequest;
import org.osgi.framework.Constants;
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.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
@Component(immediate = true,
service = RemoteContentRendererRequestHandler.class,
property={
Constants.SERVICE_RANKING +":Integer=1000"
})
public class CustomRemoteContentRendererRequestHandlerImpl implements RemoteContentRendererRequestHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomRemoteContentRendererRequestHandlerImpl.class);
public static final String HEAD_DATA = "headData";
@Reference(
cardinality = ReferenceCardinality.MANDATORY,
policy = ReferencePolicy.DYNAMIC
)
private volatile RemoteContentRendererRequestHandler defaultHandler;
private final ThreadLocal<SlingHttpServletRequest> currentRequest = new ThreadLocal<>();
@Activate
void init() {
if (defaultHandler == null) {
LOGGER.error("CustomRemoteContentRendererRequestHandlerImpl: Default RemoteContentRendererRequestHandler is null!");
throw new IllegalStateException("Default RemoteContentRendererRequestHandler is not available.");
}
LOGGER.info("CustomRemoteContentRendererRequestHandlerImpl: initialized with defaultHandler: {}", defaultHandler);
}
public ThreadLocal<SlingHttpServletRequest> getCurrentRequest() {
return currentRequest;
}
public void setCurrentRequest(final SlingHttpServletRequest request) {
currentRequest.set(request);
}
private void clearCurrentRequest() {
currentRequest.remove();
}
@Override
public boolean canHandle(final SlingHttpServletRequest servletRequest) {
return defaultHandler.canHandle(servletRequest);
}
@Override
public RequestConfig getRequestConfig(final SlingHttpServletRequest servletRequest) {
setCurrentRequest(servletRequest);
return defaultHandler.getRequestConfig(servletRequest);
}
@Override
public HttpUriRequest getRequest(final SlingHttpServletRequest servletRequest, final ComponentExporter componentExporter) throws RemoteContentRenderingException {
return defaultHandler.getRequest(servletRequest, componentExporter);
}
/**
* This method grabs the response from Remote server and sets to request attribute
*
* Response from React will be in the form of
*
* { "html": "SSR constructed html", "headData": "{"attr1": "val1" ... }"}
*
* @90521 httpResponse Response to the request sent to the remote endpoint
* @2007960 String response
* @throws IOException
*/
@Override
public String getResponseMessage(final CloseableHttpResponse httpResponse) throws IOException {
try {
final String response = defaultHandler.getResponseMessage(httpResponse);
final var jsonResponse = JsonParser.parseString(response).getAsJsonObject();
final String htmlContent = jsonResponse.get("html").getAsString();
final SlingHttpServletRequest request = currentRequest.get();
if (request != null) {
var headDataNode = jsonResponse.get(HEAD_DATA);
if (headDataNode != null && !headDataNode.isJsonNull() && headDataNode.getAsJsonObject().size() > 0) {
request.setAttribute(HEAD_DATA, headDataNode.toString());
LOGGER.debug("CustomRemoteContentRendererRequestHandlerImpl: headData received for request : {} is : {}", request, headDataNode);
}
}
return htmlContent;
} finally {
clearCurrentRequest();
}
}
}