I have a method generateXmlAndImages
with input xmlDataMap
size of 400. Each of these map entries will cause four images to be created and written to storage.
In a single thread it is taking long time to process, about 15 minutes. So I thought concurrent execution might improve performance. But when I switch to parallel streams rather than single-thread, the data is never generated.
The buildIt
method is printing first log message “generatingXmlAndImages” for few xml-ids bun never printing the end log message “generatedXmlAndImages”.
It never printed below lines when I ran the method.
log.info("1:collect.size() = " + collect.size());
log.info("2:input map.size() = " + xmlDataMap.values().size());
Please help me with this, or any ideas, how I can solve this issue.
private void generateXmlAndImages() {
List<XmlData> collect = xmlDataMap.keySet().stream()
.parallel()
.map(xmlId -> xmlDataMap.get(xmlId))
.map(data -> buildIt(data))
.collect(Collectors.toList());
log.info("1:collect.size() = " + collect.size());
log.info("2:input map.size() = " + xmlDataMap.values().size());
}
private XmlData buildIt(XmlData xmlData) {
log.info("generatingXmlAndImages: xmlId=" + xmlData.getId());
try {
if (!xmlData.isValid()) {
return null;
}
Map<String, String> imagesPaths = generateSignatureAndLogoImages(xmlData);
XML xml = XmlGenerator.generateXML(imagesPaths, xmlData);
xmlData.setXml(xml);
xmlData.setValid(true);
log.info("generatedXmlAndImages: xmlId=" + xmlData.getId());
} catch (Exception e) {
String errorMessage = "Unable to generate Images or XML for xml Id:" + xmlData.getId();
log.error("FAILED" + errorMessage, e);
xmlData.setValid(false);
xmlData.addError(e.toString());
}
return xmlData;
}
private Map<String, String> generateSignatureAndLogoImages(XmlData xmlData) {
SignatureDataImpl signatureData = xmlData.getSignatureData();
Map<String, String> paths = new HashMap<>();
String sig1 = createImage("SIG1", xmlData.getId(), signatureData.getSignature1Data(), signatureData.getSignature1Format());
String sig2 = createImage("SIG2", xmlData.getId(), signatureData.getSignature2Data(), signatureData.getSignature2Format());
String blogo1 = createImage("LOGO1", xmlData.getId(), signatureData.getLogo1Data(), signatureData.getLogo1Format());
String blogo2 = createImage("LOGO2", xmlData.getId(), signatureData.getLogo1Data(), signatureData.getLogo1Format());
if (StringUtils.isEmpty(sig1) && StringUtils.isEmpty(sig2)) {
String error = "Failed to generate signature images for xmlId " + xmlData.getId();
log.error(error);
throw new RuntimeException(error);
}
paths.put(Properties.SIGNATURE_1, sig1);
paths.put(Properties.SIGNATURE_2, sig2);
paths.put(Properties.LOGO1, blogo1);
paths.put(Properties.LOGO1, blogo2);
return paths;
}
private String createImage(String suffix, String name, String imageData, String format) {
if (imageData == null || imageData.isEmpty()) {
return "";
}
String imageFileName = (name+"_"+ suffix+"."+ format);
String decodedBase64 = FileUtils.decodeBase64(imageData);
FileUtils.writeToFile( TMP_IMAGE_STORE_DIR, imageFileName, decodedBase64);
Files.write(Path.of(TMP_IMAGE_STORE_DIR + "/" + imageFileName),data.getBytes());
StringBuilder pathBuilder = new StringBuilder();
pathBuilder.append(TMP_IMAGE_STORE_DIR).append("/");
pathBuilder.append(imageFileName);
return pathBuilder.toString();
}
public static XML generateXML(Map<String, String> imagePaths, XmlData xmlData) {
XML xml = new XML();
Element customerRootElement = createRoot(xml, "customer");
Element stubElement = createTag(xml, customerRootElement, "stub");
Element bodyElement = createTag(xml, customerRootElement, "body");
Element mailFaceElement = createTag(xml, customerRootElement, "mailface");
addStubXml(xmlData, xml, stubElement);
addBodyXML(xmlData, imagePaths, xml, bodyElement);
addMailFaceXML(xmlData, xml, mailFaceElement);
return xml;
}
7