Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
326 changes: 150 additions & 176 deletions pom.xml

Large diffs are not rendered by default.

42 changes: 19 additions & 23 deletions src/main/java/io/mosip/print/PrintPDFApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,32 @@
import io.mosip.print.service.impl.CbeffImpl;
import io.mosip.print.spi.CbeffUtil;


@SpringBootApplication(scanBasePackages = { "io.mosip.print.*", "${mosip.auth.adapter.impl.basepackage}" }, exclude = { DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
CacheAutoConfiguration.class })
@SpringBootApplication(scanBasePackages = { "io.mosip.print.*", "${mosip.auth.adapter.impl.basepackage}" },
exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class, CacheAutoConfiguration.class })
@EnableScheduling
@EnableAsync
public class PrintPDFApplication {


@Bean
@Primary
public CbeffUtil getCbeffUtil() {
return new CbeffImpl();
}
@Bean
@Primary
public CbeffUtil getCbeffUtil() {
return new CbeffImpl();
}

@Bean
public CredentialsVerifier credentialsVerifier() {
return new CredentialsVerifier();
}

@Bean
public ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(5);
threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler");
return threadPoolTaskScheduler;
}

public static void main(String[] args) {
SpringApplication.run(PrintPDFApplication.class, args);
}

}
@Bean
public ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(5);
threadPoolTaskScheduler.setThreadNamePrefix("ThreadPoolTaskScheduler");
return threadPoolTaskScheduler;
}

public static void main(String[] args) {
SpringApplication.run(PrintPDFApplication.class, args);
}
}
6 changes: 6 additions & 0 deletions src/main/java/io/mosip/print/config/PrintConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.web.client.RestTemplate;


@Configuration
Expand All @@ -18,4 +19,9 @@ public TaskScheduler taskScheduler() {
}


@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}

}
7 changes: 7 additions & 0 deletions src/main/java/io/mosip/print/constant/ProcessType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.mosip.print.constant;

public enum ProcessType {
NEW,
CRVS_NEW,
UPDATE,
}
20 changes: 20 additions & 0 deletions src/main/java/io/mosip/print/constant/TemplateType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.mosip.print.constant;

public enum TemplateType {
UIN_CARD_TEMPLATE("RPR_UIN_CARD_TEMPLATE"),
UIN_CARD_EMAIL_SUB("RPR_UIN_CARD_EMAIL_SUB"),
UIN_CARD_EMAIL("RPR_UIN_CARD_EMAIL");

private final String value;

TemplateType(String value) {
this.value = value;
}

public String getValue() {
return value;
}

@Override
public String toString() { return value; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public enum PlatformErrorMessages {
PRT_BDD_ABIS_ABORT(PlatformConstants.PRT_PRINT_PREFIX + "002",
"ABIS for the Reference ID and Request ID was Abort"),
/** The PRT tem processing failure. */
PRT_TEM_MAPPER_NOT_FOUND(PlatformConstants.PRT_PRINT_PREFIX + "030", "Template mapper could not be mapped for processType = %s"),

PRT_TEM_PROCESSING_FAILURE(PlatformConstants.PRT_PRINT_PREFIX + "002", "The Processing of Template Failed "),
PRT_SYS_JSON_PARSING_EXCEPTION(PlatformConstants.PRT_PRINT_PREFIX + "009", "Error while parsing Json"),
PRT_AUT_INVALID_TOKEN(PlatformConstants.PRT_PRINT_PREFIX + "01", "Invalid Token Present"),
Expand Down
191 changes: 137 additions & 54 deletions src/main/java/io/mosip/print/service/impl/PrintServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import io.mosip.print.constant.*;
import io.mosip.print.dto.*;
import io.mosip.print.exception.*;
import io.mosip.print.util.*;
Expand All @@ -30,6 +31,7 @@
import io.mosip.vercred.exception.ProofTypeNotFoundException;
import io.mosip.vercred.exception.PubicKeyNotFoundException;
import io.mosip.vercred.exception.UnknownException;
import lombok.Getter;
import org.apache.commons.codec.binary.Base64;
import org.joda.time.DateTime;
import org.json.simple.JSONArray;
Expand All @@ -42,15 +44,6 @@
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import io.mosip.print.constant.EventId;
import io.mosip.print.constant.EventName;
import io.mosip.print.constant.EventType;
import io.mosip.print.constant.IdType;
import io.mosip.print.constant.ModuleName;
import io.mosip.print.constant.PDFGeneratorExceptionCodeConstant;
import io.mosip.print.constant.PlatformSuccessMessages;
import io.mosip.print.constant.QrVersion;
import io.mosip.print.constant.UinCardType;
import io.mosip.print.logger.LogDescription;
import io.mosip.print.logger.PrintLogger;
import io.mosip.print.model.CredentialStatusEvent;
Expand Down Expand Up @@ -87,11 +80,6 @@ public class PrintServiceImpl implements PrintService{
/** The Constant VALUE. */
private static final String VALUE = "value";

/** The Constant UIN_CARD_TEMPLATE. */
private static final String UIN_CARD_TEMPLATE = "RPR_UIN_CARD_TEMPLATE";
private static final String UIN_CARD_EMAIL_SUB = "RPR_UIN_CARD_EMAIL_SUB";
private static final String UIN_CARD_EMAIL = "RPR_UIN_CARD_EMAIL";

/** The Constant FACE. */
private static final String FACE = "Face";

Expand Down Expand Up @@ -237,7 +225,7 @@ public boolean generateCard(EventModel eventModel) {
private Map<String, byte[]> getDocuments(String credential, String credentialType, String encryptionPin,
String requestId,
String cardType,
boolean isPasswordProtected, String refId, String registrationId) {
boolean isPasswordProtected, String refId, String registrationId) {
printLogger.debug("PrintServiceImpl::getDocuments()::entry");
String credentialSubject;
Map<String, byte[]> byteMap = new HashMap<>();
Expand All @@ -248,10 +236,8 @@ private Map<String, byte[]> getDocuments(String credential, String credentialTyp
String individualBio = null;
Map<String, Object> attributes = new LinkedHashMap<>();
boolean isTransactionSuccessful = false;
String template = UIN_CARD_TEMPLATE;
byte[] pdfbytes = null;
try {

credentialSubject = getCrdentialSubject(credential);
org.json.JSONObject credentialSubjectJson = new org.json.JSONObject(credentialSubject);
org.json.JSONObject decryptedJson = decryptAttribute(credentialSubjectJson, encryptionPin, credential);
Expand All @@ -272,37 +258,39 @@ private Map<String, byte[]> getDocuments(String credential, String credentialTyp
if (isPasswordProtected) {
password = getPassword(uin);
}
if (credentialType.equalsIgnoreCase("qrcode")) {
boolean isQRcodeSet = setQrCode(decryptedJson.toString(), attributes, isPhotoSet);
InputStream uinArtifact = templateGenerator.getTemplate(template, attributes, templateLang);
pdfbytes = uinCardGenerator.generateUinCard(uinArtifact, UinCardType.PDF,
password);

} else {

if (!isPhotoSet) {
printLogger.debug(PlatformErrorMessages.PRT_PRT_APPLICANT_PHOTO_NOT_SET.name());
}

// byte[] textFileByte = createTextFile(decryptedJson.toString());
// byteMap.put(UIN_TEXT_FILE, textFileByte);

boolean isQRcodeSet = setQrCode(decryptedJson.toString(), attributes, isPhotoSet);
Optional<TemplateMapper.TemplateMappedConfig> templateConfigOpt = TemplateMapper.getTemplatesConfig(attributes);
if (templateConfigOpt.isEmpty()) {
throw new TemplateProcessingFailureException(
String.format(
PlatformErrorMessages.PRT_TEM_MAPPER_NOT_FOUND.getMessage(),
attributes.get(TemplateMapper.PROCESS_TYPE_KEY)
)
);
}
TemplateMapper.TemplateMappedConfig templateMappedConfig = templateConfigOpt.get();
String template = templateMappedConfig.getDocumentTemplateName().getValue();
if (template != null) {
boolean isQRcodeSet = setQrCode(decryptedJson.toString(), attributes, isPhotoSet);
if (!isQRcodeSet) {
printLogger.debug(PlatformErrorMessages.PRT_PRT_QRCODE_NOT_SET.name());
}
printLogger.info("Attributes:{}", JSONObject.toJSONString(attributes));
// getting template and placing original valuespng
InputStream uinArtifact = templateGenerator.getTemplate(template, attributes, templateLang);
if (uinArtifact == null) {
printLogger.error(PlatformErrorMessages.PRT_TEM_PROCESSING_FAILURE.name());
throw new TemplateProcessingFailureException(
PlatformErrorMessages.PRT_TEM_PROCESSING_FAILURE.getCode());
if (!isPhotoSet) {
printLogger.debug(PlatformErrorMessages.PRT_PRT_APPLICANT_PHOTO_NOT_SET.name());
}
pdfbytes = uinCardGenerator.generateUinCard(uinArtifact, UinCardType.PDF, password);
printLogger.info("Attributes:{}", JSONObject.toJSONString(attributes));
pdfbytes = generatePdfFromTemplate(template, attributes, templateLang, password);
}

if (templateMappedConfig.getEmailSubjectTemplate() != null && templateMappedConfig.getEmailTemplate() != null) {
TemplateType emailSubject = templateMappedConfig.getEmailSubjectTemplate();
TemplateType emailBody = templateMappedConfig.getEmailTemplate();
Attachment attachment = pdfbytes != null ? new Attachment(cardType + ".pdf", pdfbytes) : null;
sendEmail(residentEmailId, emailSubject, emailBody, attachment, attributes, templateLang);
}

// Send UIN Card Pdf to Email
// leaving it as it is to keep backward compatibility
if (emailUINEnabled) {
sendUINInEmail(residentEmailId, registrationId, attributes, pdfbytes, templateLang);
}
Expand Down Expand Up @@ -387,20 +375,87 @@ private Map<String, byte[]> getDocuments(String credential, String credentialTyp
}


private void sendUINInEmail(String residentEmailId, String fileName, Map<String, Object> attributes, byte[] pdfbytes, String templateLang) {
if (pdfbytes != null) {
try {
List<String> emailIds = Arrays.asList(residentEmailId, defaultEmailIds);
List<NotificationResponseDTO> responseDTOs = notificationUtil.emailNotification(emailIds, fileName,
UIN_CARD_EMAIL, UIN_CARD_EMAIL_SUB, attributes, pdfbytes, templateLang);
responseDTOs.forEach(responseDTO ->
printLogger.info("UIN sent successfully via Email, server response..{}", responseDTO)
);
} catch (Exception e) {
printLogger.error("Failed to send pdf UIN via email.{}", residentEmailId, e);
}
}
}
@Getter
static class Attachment {
private final String fileName;
private final byte[] data;

public Attachment(String fileName, byte[] data) {
this.fileName = fileName;
this.data = data;
}
}

private Optional<List<NotificationResponseDTO>> sendEmail(
String residentEmailId,
TemplateType emailSubject,
TemplateType emailBody,
Attachment attachment,
Map<String, Object> attributes,
String templateLang
) {

Optional<List<NotificationResponseDTO>> noResult = Optional.empty();
if (residentEmailId == null) {
printLogger.error("Resident email ID parameter is null");
return noResult;
}
if (emailSubject == null) {
printLogger.error("Email subject parameter is null");
return noResult;
}
if (emailBody == null) {
printLogger.error("Email body parameter is null");
return noResult;
}

if (attachment != null && (attachment.getFileName() == null || attachment.getData() == null)) {
printLogger.error("Both filename and data must be provided for email attachment");
return noResult;
}

List<String> emailIds = new ArrayList<>();
emailIds.add(residentEmailId);
if (defaultEmailIds != null) {
emailIds.add(defaultEmailIds);
}

try {
List<NotificationResponseDTO> responseDTOs = notificationUtil.emailNotification(
emailIds,
attachment != null ? attachment.getFileName() : null,
emailBody.getValue(),
emailSubject.getValue(),
attributes,
attachment != null ? attachment.getData() : null,
templateLang
);
return Optional.of(responseDTOs);
} catch (Exception e) {
printLogger.error("Failed to send email to {}: {}", residentEmailId, e.getMessage(), e);
return noResult;
}
}

private void sendUINInEmail(String residentEmailId, String fileName, Map<String, Object> attributes, byte[] pdfbytes, String templateLang) {
if (pdfbytes == null) {
return;
}

var responsesDtos = sendEmail(
residentEmailId,
TemplateType.UIN_CARD_EMAIL_SUB,
TemplateType.UIN_CARD_EMAIL,
new Attachment(fileName, pdfbytes),
attributes,
templateLang
);
responsesDtos.ifPresent(responseDTOs -> {
responseDTOs.forEach(responseDTO ->
printLogger.info("Email sent successfully, server response: {}", responseDTO)
);
});
}
/**
* Creates the text file.
*
Expand Down Expand Up @@ -720,6 +775,34 @@ private void printStatusUpdate(String requestId, byte[] data, String credentialT
webSubSubscriptionHelper.printStatusUpdateEvent(topic, creEvent);
}

/**
* Processes a template and generates a PDF document.
*
* @param template the template name
* @param attributes the template attributes
* @param templateLang the template language
* @param password the password for PDF protection (can be null)
* @return the generated PDF as byte array
* @throws TemplateProcessingFailureException if template processing fails
*/
private byte[] generatePdfFromTemplate(String template, Map<String, Object> attributes, String templateLang, String password) {
try {
InputStream uinArtifact = templateGenerator.getTemplate(template, attributes, templateLang);

if (uinArtifact == null) {
printLogger.error(PlatformErrorMessages.PRT_TEM_PROCESSING_FAILURE.name());
throw new TemplateProcessingFailureException(
PlatformErrorMessages.PRT_TEM_PROCESSING_FAILURE.getCode());
}

return uinCardGenerator.generateUinCard(uinArtifact, UinCardType.PDF, password);
} catch (Exception e) {
printLogger.error("Error in template processing or PDF generation", e);
throw new TemplateProcessingFailureException(
PlatformErrorMessages.PRT_TEM_PROCESSING_FAILURE.getCode());
}
}

public org.json.JSONObject decryptAttribute(org.json.JSONObject data, String encryptionPin, String credential)
throws ParseException {

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/io/mosip/print/util/RestApiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public class RestApiClient {

/** The builder. */
@Autowired
@Qualifier("selfTokenRestTemplate")
// @Qualifier("selfTokenRestTemplate")
private RestTemplate restTemplate;

@Autowired
Expand Down
Loading
Loading