Abstract
Uploading assets to AEM Cloud Service is a 3 step process (initiateUpload.json, Upload to blob storage, completeUpload.json). Tools like https://github.com/adobe/aem-upload can be used to upload files to AEM using a NodeJS client...
This post is on creating simple assets (text , json files etc.) in AEM using CURL or other third party apps in a single step (in traditional AEMs this is provided by .createasset.html check documentation). Pass the fileName and fileContent parameters to create assets in AEM with this servlet installed...
Solution
Add a servlet apps.experienceaem.assets.core.servlets.EAEMCreateAssetServlet to create the assets in AEM...
package apps.experienceaem.assets.core.servlets;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.osgi.services.HttpClientBuilderFactory;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.api.wrappers.SlingHttpServletRequestWrapper;
import org.apache.sling.api.wrappers.SlingHttpServletResponseWrapper;
import org.apache.sling.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONObject;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;
@Component(
immediate = true,
service = Servlet.class,
property = {
"sling.servlet.selectors=eaemcreateasset",
"sling.servlet.methods=POST",
"sling.servlet.resourceTypes=sling/servlet/default"
}
)
public class EAEMCreateAssetServlet extends SlingAllMethodsServlet {
private static final Logger log = LoggerFactory.getLogger(EAEMCreateAssetServlet.class);
private static String INITIATE_UPLOAD_REQ = ".initiateUpload.json";
public static String FILE_NAME = "fileName";
public static String UPLOAD_TOKEN = "uploadToken";
public static String MIME_TYPE = "mimeType";
public static String FILE_SIZE = "fileSize";
@Reference
private HttpClientBuilderFactory httpClientBuilderFactory;
private CloseableHttpClient httpClient;
protected void activate(ComponentContext ctx) {
HttpClientBuilder builder = httpClientBuilderFactory.newBuilder();
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000)
.setSocketTimeout(30000).build();
builder.setDefaultRequestConfig(requestConfig);
httpClient = builder.build();
}
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws ServletException, IOException {
String fileName = request.getParameter("fileName");
String fileContent = request.getParameter("fileContent");
try {
if (StringUtils.isEmpty(fileName)) {
response.sendError(SlingHttpServletResponse.SC_FORBIDDEN, "fileName parameter missing");
return;
}
int fileSize = fileContent.length();
request.setAttribute(FILE_NAME, fileName);
request.setAttribute(FILE_SIZE, fileSize);
String initiateUploadResponse = makeInitiateUploadRequest(request, response);
log.debug("initiateUpload Response : " + initiateUploadResponse);
JSONObject uploadResponse = new JSONObject(initiateUploadResponse);
JSONArray filesJSON = uploadResponse.getJSONArray("files");
JSONObject fileJSON = (JSONObject) filesJSON.get(0);
String binaryPOSTUrl = fileJSON.getJSONArray("uploadURIs").getString(0);
HttpPut put = new HttpPut(binaryPOSTUrl);
HttpEntity entity = new StringEntity(fileContent);
put.setEntity(entity);
HttpResponse putResponse = httpClient.execute(put);
int statusCode = putResponse.getStatusLine().getStatusCode();
if( (statusCode < 200) || (statusCode > 210)){
response.sendError(SlingHttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error uploading file - " + putResponse.getStatusLine().getReasonPhrase());
return;
}
String completedResponse = makeCompleteUploadRequest(uploadResponse, request, response);
log.debug("completeUpload Response : " + completedResponse);
response.getWriter().print(fileName);
} catch (Exception e) {
log.error("Error creating file : {}", fileName);
response.sendError(SlingHttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error creating file - " + e.getMessage());
}
}
private String makeCompleteUploadRequest(JSONObject uploadResponse, SlingHttpServletRequest request,
SlingHttpServletResponse response) throws Exception{
JSONArray filesJSON = uploadResponse.getJSONArray("files");
JSONObject fileJSON = (JSONObject) filesJSON.get(0);
String uploadToken = fileJSON.getString("uploadToken");
String mimeType = fileJSON.getString("mimeType");
String completeURI = uploadResponse.getString("completeURI");
request.setAttribute(UPLOAD_TOKEN, uploadToken);
request.setAttribute(MIME_TYPE, mimeType);
SlingHttpServletRequest wrapperRequest = new FileNameSlingServletRequestWrapper(request);
SlingHttpServletResponse wrapperResponse = new EAEMSlingModelResponseWrapper(response);
RequestDispatcher dp = wrapperRequest.getRequestDispatcher(completeURI);
dp.include(wrapperRequest, wrapperResponse);
return wrapperResponse.toString();
}
private String makeInitiateUploadRequest(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws Exception{
String folderPath = request.getResource().getPath();
SlingHttpServletRequest wrapperRequest = new FileNameSlingServletRequestWrapper(request);
RequestDispatcher dp = wrapperRequest.getRequestDispatcher(folderPath + INITIATE_UPLOAD_REQ);
SlingHttpServletResponse wrapperResponse = new EAEMSlingModelResponseWrapper(response);
dp.include(wrapperRequest, wrapperResponse);
String uploadResponseStr = wrapperResponse.toString();
if(StringUtils.isEmpty(uploadResponseStr)){
response.sendError(SlingHttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Empty upload response, file creation failed");
return "";
}
//uploadResponseStr = getTestInitiateUploadResponse();
return uploadResponseStr;
}
private class EAEMSlingModelResponseWrapper extends SlingHttpServletResponseWrapper {
private CharArrayWriter writer;
public EAEMSlingModelResponseWrapper (final SlingHttpServletResponse response) {
super(response);
writer = new CharArrayWriter();
}
public PrintWriter getWriter() throws IOException {
return new PrintWriter(writer);
}
public String toString() {
return writer.toString();
}
}
private class FileNameSlingServletRequestWrapper extends SlingHttpServletRequestWrapper {
public FileNameSlingServletRequestWrapper(final SlingHttpServletRequest request) {
super(request);
}
public String[] getParameterValues(String paramName) {
if(EAEMCreateAssetServlet.FILE_NAME.equals(paramName)){
return new String[] { String.valueOf(super.getAttribute(FILE_NAME)) };
}else if(EAEMCreateAssetServlet.FILE_SIZE.equals(paramName)){
return new String[] { String.valueOf(super.getAttribute(FILE_SIZE)) };
}else if(EAEMCreateAssetServlet.UPLOAD_TOKEN.equals(paramName)){
return new String[] { (String)super.getAttribute(UPLOAD_TOKEN) };
}else if(EAEMCreateAssetServlet.MIME_TYPE.equals(paramName)){
return new String[] { (String)super.getAttribute(MIME_TYPE) };
}
return super.getParameterValues(paramName);
}
}
}
To make a CURL request using login-token
Read Full Blog
Q&A
Please use this thread to ask the related questions.
Kautuk Sahni