• Be assumption that there is existed event in Call to action (AEM)
export default class <Call To Action> extends Component {
private memberSelector = '<prefix defined for Servlet detect>';
private $component;
constructor(cmp: HTMLElement) {
super(cmp);
this.$component = $(cmp);
this.generatePDFasFormat();
}
private generatePDFasFormat = () => {
const <Call to Action> = this.$cmp;
const button = <Call to Action>.querySelector('.btn-generate-membership') as HTMLElement;
button.addEventListener('click', (event) => {
this.generateMembershipInfo(event);
});
};
private generateMembershipInfo = (event: MouseEvent): void => {
const targetElement = event.target as HTMLElement;
const resource = this.$component.data('resource') as string;
const endpoint = `${resource}.${this.memberSelector}.json`;
targetElement.classList.add('disabled');
const pdfWindow = window.open('', '_blank');
if (pdfWindow) {
pdfWindow.document.write('<p>Please wait while we retrieve your document...</p>');
$.get(endpoint)
.done((data: string): void => {
const servletUrl = `/bin/pdf/pdf-statement?path=${data}`;
pdfWindow.location = servletUrl.replace(/"/g, ""); // eslint-disable-line
targetElement.classList.remove('disabled');
})
.catch((err): void => {
pdfWindow.document.body.innerHTML = '';
pdfWindow.document.write('<p>We were unable to retrieve your document.</p>');
logger.error(err);
})
}
};
}
• Sling Servlets in AEM
@Component(immediate = true, service = Servlet.class,
property = {
SERVICE_DESCRIPTION + <Component Name>Servlet.SERVLET_SERVICE_DESCRIPTION,
SLING_SERVLET_RESOURCE_TYPES + <Component Name>Servlet.RESOURCE_TYPE,
SLING_SERVLET_METHODS + "=" + HttpConstants.METHOD_GET,
SLING_SERVLET_SELECTORS + <Component Name>Servlet.SELECTOR,
SLING_SERVLET_EXTENSIONS + "=" + Constants.EXTENSION_JSON
})
public class <Component Name>Servlet extends SlingSafeMethodsServlet {
public static final String SERVLET_SERVICE_DESCRIPTION = "<Description for Servlets>";
public static final String RESOURCE_TYPE = "=flagtick/components/content/<Component Name (root name)>";
public static final String SELECTOR = "=<prefix defined for Servlet detect>";
private static final long serialVersionUID = 1L;
@Reference
private transient FlagtickInformationService flagtickInformationService;
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws IOException {
if (flagtickInformationService == null) {
response.setStatus(HTTP_UNAVAILABLE);
response.getWriter().write("Service unavailable");
return;
}
final String userID = CookieUtils.getCookieValue(request, Constants.USER_ID_PARAMETER);
if (StringUtils.isBlank(personID)) {
String errorMsg = "No user ID found for the request";
response.getWriter().append(errorMsg);
response.setStatus(HTTP_BAD_REQUEST);
return;
}
final String userStatus = CookieUtils.getCookieValue(request, Constants.USER_STATUS_COOKIE_NAME);
if (StringUtils.isBlank(userStatus)) {
String errorMsg = "No User Status Token found for the request";
response.getWriter().append(errorMsg);
response.setStatus(HTTP_BAD_REQUEST);
return;
}
final String token = CookieUtils.getCookieValue(request, Constants.TOKEN_COOKIE_NAME);
if (StringUtils.isBlank(token)) {
String errorMsg = "No JWT Token found for the request";
response.getWriter().append(errorMsg);
response.setStatus(HTTP_BAD_REQUEST);
return;
}
Map<String, String> params = new HashMap<>();
params.put(Constants.USER_ID_PARAMETER, userID);
params.put(Constants.USER_STATUS_COOKIE_NAME, userStatus);
String documentUrl = flagtickInformationService.saveDocumentInDAM(params, token);
// if requested parameters don't exist or an invalid combination was requested
if (StringUtils.isEmpty(documentUrl)) {
response.setStatus(HTTP_BAD_REQUEST);
response.getWriter().write("Invalid request parameters");
return;
}
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValue(response.getWriter(), documentUrl);
}
}
• Create Interface in Java as named FlagtickInformationService
public interface FlagtickInformationService {
String saveDocumentInDAM(Map<String, String> params, String token);
void deleteDocumentInDAM(String personId);
}
• Integrate FlagtickInformationServiceImpl based interface named FlagtickInformationService as below:
@Component(service = FlagtickInformationService.class, immediate = true)
public class FlagtickInformationServiceImpl implements FlagtickInformationService {
private static final Logger LOGGER = LoggerFactory.getLogger(MembershipInformationServiceImpl.class);
private static final String ROOT_PATH = "/content/dam/flagtick/<prefix defined for Servlet detect>";
@Reference
private ResourceResolverService resourceResolverService;
@Reference
private FlagtickIntegrationService flagtickIntegrationService;
@Reference
private QueryBuilder builder;
@Override
public String saveDocumentInDAM(Map<String, String> params, String token) {
Binary binary = null;
String pdfPath = StringUtils.EMPTY;
try (ResourceResolver resourceResolver = resourceResolverService.getResourceResolver()) {
final Session session = resourceResolver.adaptTo(Session.class);
final AssetManager assetManager = resourceResolver.adaptTo(AssetManager.class);
if (null != session && null != assetManager) {
final Node rootFolder = JcrUtils.getOrCreateByPath(ROOT_PATH, NT_SLING_FOLDER, session);
byte[] bytes = flagtickIntegrationService.generateServicePDF(params, token);
binary = new BinaryImpl(bytes);
final Asset pdfAsset = assetManager.createOrUpdateAsset(
rootFolder.getPath() + SLASH + getDocumentName(params.get(USER_ID_PARAMETER)),
binary, "application/pdf", true);
if (null != pdfAsset) {
pdfPath = pdfAsset.getPath();
}
session.save();
}
} catch (LoginException | RepositoryException e) {
e.printStackTrace();
LOGGER.error("Exception occurred: {}", e.getMessage());
} finally {
if (binary != null) {
binary.dispose();
}
}
return pdfPath;
}
public void deleteDocumentInDAM(String userId) {
try (ResourceResolver resourceResolver = resourceResolverService.getResourceResolver()) {
final Session session = resourceResolver.adaptTo(Session.class);
if (session != null){
Map<String, String> map = new HashMap<>();
map.put("path", ROOT_PATH);
map.put("type", "dam:Asset");
map.put("nodename","*"+userId+"*");
map.put("nodename.operation","like");
map.put("relativedaterange.property","jcr:created");
map.put("relativedaterange.upperBound","-1d");
map.put("p.limit","-1");
Query query = builder.createQuery(PredicateGroup.create(map),session);
SearchResult searchResult = query.getResult();
for(Hit hit : searchResult.getHits()) {
String path = hit.getPath();
session.removeItem(path);
if (session.hasPendingChanges()) {
session.save();
}
}
}
} catch (LoginException | RepositoryException e) {
e.printStackTrace();
LOGGER.error("Exception occurred: {}", e.getMessage());
}
}
private String getDocumentName(final String userId) {
return UUID.randomUUID() + DASH_CHARACTER + userId + ".pdf";
}
}
• Integrate FlagtickIntegrationService.java
public interface FlagtickIntegrationService {
byte[] generateServicePDF(Map<String, String> params, String token);
}
• Integrate FlagtickIntegrationServiceImpl.java
@Component(
immediate = true,
service = FlagtickIntegrationService.class
)
@Designate(ocd = FlagtickIntegrationServiceImpl.Config.class)
public class FlagtickIntegrationServiceImpl implements FlagtickIntegrationService {
public static final String BEARER = "Bearer ";
public static final String CLIENT_PROTOCOL_EXCEPTION = "Client protocol exception";
public static final String ERROR_WHILE_PARSING_THE_RESPONSE = "Error while parsing the response";
public static final String UNABLE_TO_CREATE_URI = "Unable to create URI";
public static final String IN_OUT_EXCEPTION = "In out exception";
private static final Logger LOGGER = LoggerFactory.getLogger(FlagtickIntegrationServiceImpl.class);
private static final String BAD_REQUEST_ERROR_MSG = "Bad Request - Incorrect or invalid parameters";
private static final String BAD_GATEWAY_ERROR_MSG = "Bad Gateway - Internal server error";
private String servicePDFEndpoint;
private String apiKey;
@Activate
protected void activate(Config config) {
servicePDFEndpoint = config.servicePDFEndpoint();
apiKey = config.apiKey();
}
@Override
public byte[] generateServicePDF(Map<String, String> params, String userToken) {
URI uri;
try {
uri = buildParameterizedUri(servicePDFEndpoint, params);
} catch (URISyntaxException e) {
LOGGER.error(UNABLE_TO_CREATE_URI, e);
return new byte[0];
}
HttpGet request = createAuthenticatedGetRequest(apiKey, uri);
request.addHeader(HttpHeaders.AUTHORIZATION, BEARER + userToken);
try (CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = httpClient.execute(request)) {
if (response.getStatusLine().getStatusCode() == HTTP_BAD_REQUEST) {
LOGGER.error(BAD_REQUEST_ERROR_MSG);
return new byte[0];
}
if (response.getStatusLine().getStatusCode() == HTTP_BAD_GATEWAY) {
LOGGER.error(BAD_GATEWAY_ERROR_MSG);
return new byte[0];
}
if (response.getStatusLine().getStatusCode() == HTTP_INTERNAL_ERROR) {
LOGGER.error("Internal Server Error");
return new byte[0];
}
HttpEntity entity = response.getEntity();
if (entity != null) {
return EntityUtils.toByteArray(entity);
}
} catch (ClientProtocolException e) {
LOGGER.error(CLIENT_PROTOCOL_EXCEPTION, e);
} catch (IOException e) {
LOGGER.error(ERROR_WHILE_PARSING_THE_RESPONSE, e);
}
return new byte[0];
}
private HttpGet createAuthenticatedGetRequest(String apiKey, URI uri) {
HttpGet request = new HttpGet(uri);
request.addHeader(Constants.HEADER_CONTENT_TYPE, Constants.CONTENT_TYPE_JSON);
request.addHeader(Constants.X_API_KEY, apiKey);
return request;
}
private HttpPost createAuthenticatedPostRequest(String apiKey, URI uri) {
HttpPost request = new HttpPost(uri);
request.addHeader(Constants.HEADER_CONTENT_TYPE, Constants.CONTENT_TYPE_JSON);
request.addHeader(Constants.X_API_KEY, apiKey);
return request;
}
private URI buildParameterizedUri(String endpoint, Map<String, String> paramMap) throws URISyntaxException {
List<NameValuePair> list = new ArrayList<NameValuePair>();
paramMap.entrySet()
.forEach(entry -> list.add(
new BasicNameValuePair(entry.getKey(), entry.getValue()
)));
URI uri = new URIBuilder(endpoint)
.add Parameters(list)
.build();
return uri;
}
@ObjectClassDefinition(
name = "FLAGTICK - Flagtick Service Configurations",
description = "Flagtick Service Configurations"
)
protected @interface Config {
@AttributeDefinition(
name = "Service PDF Endpoint",
description = "URL endpoint for service pdf endpoint",
type = AttributeType.STRING
)
String servicePDFEndpoint();
@AttributeDefinition(
name = "API key",
description = "API key for Flagtick",
type = AttributeType.STRING
)
String apiKey();
}
}
• Reference link Creating your custom OSGi Configuration
{
"generatePDFEndpoint": "https://<UUID.randomUUID()>.execute-api.us-west-2.amazonaws.com/dev/membershipInformationPDF",
"apiKey":"<API Key Generate Random String - UUID.randomUUID()>"
}
• Update API Gateway as named <UUID.randomUUID()>
• Create Endpoint
• Setup Lambda function and link to API Gateway
Note: Please click checkbox as named Use Lambda Proxy Integration
• Generate PDF Resource with Root Path (/)
• Double Click Method Request
+ API Key Required (false => true)
+ URL Query String Parameters
• Deploy API (The steps should be run again after whatever changes for Resources tab)
• Testing API Gateway First
• Create Lambda function as Java 8 on Amazon Linux 1
+ Runtime Java 8 on Amazon Linux 1
+ Handler example.Hello::handleRequest
+ Architecture x86_64
• Check connection with API Gateway from Dashboard Lambda flagtickInfoPDF function
• Create AWS Serverless Application from Intellij IDE
• Create Self Template from Soft named ...
• Create Template by Apache PDFBox
mvn archetype:generate -DgroupId=com.ap.pdfboxgenerate -DartifactId=pdf-box-app -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4 -DinteractiveMode=false
• Configure Pdfbox Library
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<pdfbox.version>3.0.0-alpha2</pdfbox.version>
</properties>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>${pdfbox.version}</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>fontbox</artifactId>
<version>${pdfbox.version}</version>
</dependency>
Note: Run mvn clean install to install dependencies as above. Then, Right Click => Maven => Reload Project.
• Establish Main Function to Generate PDF Template: Reference link here.