Skip to content

Commit

Permalink
feat(exportExcel): Send an email to user with download link once expo…
Browse files Browse the repository at this point in the history
…rt completed

Signed-off-by: Smruti Prakash Sahoo <smruti.sahoo@siemens.com>
  • Loading branch information
smrutis1 committed Apr 25, 2022
1 parent 5ecf9b5 commit 6dcc7b0
Showing 17 changed files with 322 additions and 88 deletions.
Original file line number Diff line number Diff line change
@@ -1553,6 +1553,12 @@ private void flattenlinkedReleaseOfRelease(Map<String, ReleaseRelationship> rele
}));
}

public void sendExportSpreadsheetSuccessMail(String url, String recepient) throws TException {
mailUtil.sendMail(recepient, MailConstants.SUBJECT_SPREADSHEET_EXPORT_SUCCESS,
MailConstants.TEXT_SPREADSHEET_EXPORT_SUCCESS, SW360Constants.NOTIFICATION_CLASS_PROJECT, "", false,
url);
}

private Map<String, String> createProjectCSRow(String relation, Project prj,
List<Map<String, String>> clearingStatusList) {
String projectId = prj.getId();
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ public class MailConstants {
public static final String SUBJECT_FOR_CLOSED_CLEARING_REQUEST = "subjectForClosedClearingRequest";
public static final String SUBJECT_FOR_REJECTED_CLEARING_REQUEST = "subjectForRejectedClearingRequest";
public static final String SUBJECT_FOR_UPDATED_PROJECT_WITH_CLEARING_REQUEST = "subjectForUpdatedProjectWithClearingRequest";
public static final String SUBJECT_SPREADSHEET_EXPORT_SUCCESS = "subjectForSuccessfulExport";

public static final String TEXT_FOR_NEW_MODERATION_REQUEST = "textForNewModerationRequest";
public static final String TEXT_FOR_UPDATE_MODERATION_REQUEST = "textForUpdateModerationRequest";
@@ -55,6 +56,7 @@ public class MailConstants {
public static final String TEXT_FOR_UPDATE_PROJECT = "textForUpdateProject";
public static final String TEXT_FOR_CLOSED_CLEARING_REQUEST = "textForClosedClearingRequest";
public static final String TEXT_FOR_REJECTED_CLEARING_REQUEST = "textForRejectedClearingRequest";
public static final String TEXT_SPREADSHEET_EXPORT_SUCCESS = "textForSuccessfulExport";

private MailConstants() {
// Utility class with only static functions
Original file line number Diff line number Diff line change
@@ -72,6 +72,7 @@ public class MailUtil extends BackendUtils {
private String enableSsl;
private String enableDebug;
private String supportMailAddress;
private String smtpSSLProtocol;

public MailUtil() {
mailExecutor = fixedThreadPoolWithQueueSize(MAIL_ASYNC_SEND_THREAD_LIMIT, MAIL_ASYNC_SEND_QUEUE_LIMIT);
@@ -96,6 +97,7 @@ private void setBasicProperties() {
password = loadedProperties.getProperty("MailUtil_password", "");
enableDebug = loadedProperties.getProperty("MailUtil_enableDebug", "false");
supportMailAddress = loadedProperties.getProperty("MailUtil_supportMailAddress","");
smtpSSLProtocol = loadedProperties.getProperty("MailUtil_smtpSSLProtocol", "");
}

private void setSession() {
@@ -111,6 +113,8 @@ private void setSession() {
properties.setProperty("mail.smtp.ssl.enable", enableSsl);

properties.setProperty("mail.debug", enableDebug);
properties.setProperty("mail.smtp.ssl.protocols", smtpSSLProtocol);


if (!"false".equals(isAuthenticationNecessary)) {
Authenticator auth = new SMTPAuthenticator(login, password);
3 changes: 3 additions & 0 deletions backend/src-common/src/main/resources/sw360.properties
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ MailUtil_login=
MailUtil_password=
MailUtil_enableDebug=
MailUtil_supportMailAddress=
MailUtil_smtpSSLProtocol=

# text patterns for mail utility
defaultBegin = \
@@ -53,7 +54,9 @@ subjectForUpdatedClearingRequest= Your clearing request <%s> has been updated fo
subjectForClosedClearingRequest= Your clearing request <%s> has been closed for Project <%s>
subjectForRejectedClearingRequest= Your clearing request <%s> has been rejected for Project <%s>
subjectForUpdatedProjectWithClearingRequest= Project <%s> with clearing request <%s> updated
subjectForSuccessfulExport = Spreadsheet Export Successful

textForSuccessfulExport = The project spreadsheet export successfully completed. Please find the download link(%s) here.
textForNewModerationRequest= a new moderation request has been added to your SW360-account.\n\n
textForUpdateModerationRequest= \
one of the moderation requests previously added to your \
Original file line number Diff line number Diff line change
@@ -430,4 +430,9 @@ public Set<String> getGroups() throws TException {
public int getMyAccessibleProjectCounts(User user) throws TException {
return handler.getMyAccessibleProjects(user);
}

@Override
public void sendExportSpreadsheetSuccessMail(String url, String recepient) throws TException {
handler.sendExportSpreadsheetSuccessMail(url, recepient);
}
}
Original file line number Diff line number Diff line change
@@ -587,6 +587,7 @@ public class PortalConstants {

// Excel export
public static final String EXPORT_TO_EXCEL = "export_to_excel";
public static final String DOWNLOAD_EXCEL = "download_excel";
public static final String EXPORT_CLEARING_TO_EXCEL = "export_clearing_to_excel";
public static final String EXPORT_ID = "export_id";

Original file line number Diff line number Diff line change
@@ -208,6 +208,8 @@ public void serveResource(ResourceRequest request, ResourceResponse response) th
updateVulnerabilityRating(request, response);
} else if (PortalConstants.EXPORT_TO_EXCEL.equals(action)) {
exportExcel(request, response);
} else if (PortalConstants.DOWNLOAD_EXCEL.equals(action)) {
downloadExcel(request, response);
} else if (PortalConstants.EXPORT_CLEARING_TO_EXCEL.equals(action)) {
exportReleasesSpreadsheet(request, response);
} else if (PortalConstants.DOWNLOAD_LICENSE_INFO.equals(action)) {
@@ -287,6 +289,25 @@ else if ((PortalConstants.LOAD_OBLIGATIONS_EDIT.equals(action)
}
}

private void downloadExcel(ResourceRequest request, ResourceResponse response) {
final User user = UserCacheHolder.getUserFromRequest(request);
final String token = request.getParameter("token");
String filename = null;

try {
boolean extendedByReleases = Boolean.valueOf(request.getParameter(PortalConstants.EXTENDED_EXCEL_EXPORT));
ProjectExporter exporter = new ProjectExporter(thriftClients.makeComponentClient(),
thriftClients.makeProjectClient(), user, extendedByReleases);
filename = String.format("projects-%s.xlsx", SW360Utils.getCreatedOn());
PortletResponseUtil.sendFile(request, response, filename, exporter.downloadExcelSheet(token),
CONTENT_TYPE_OPENXML_SPREADSHEET);
} catch (IOException | TException e) {
log.error("An error occurred while generating the Excel export", e);
response.setProperty(ResourceResponse.HTTP_STATUS_CODE,
Integer.toString(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
}
}

private void serveViewVendor(ResourceRequest request, ResourceResponse response) throws IOException, PortletException {
String what = request.getParameter(PortalConstants.WHAT);
String where = request.getParameter(PortalConstants.WHERE);
@@ -1021,23 +1042,53 @@ private void serveRemoveProject(ResourceRequest request, ResourceResponse respon
private void exportExcel(ResourceRequest request, ResourceResponse response) {
final User user = UserCacheHolder.getUserFromRequest(request);
final String projectId = request.getParameter(Project._Fields.ID.toString());
String filename = String.format("projects-%s.xlsx", SW360Utils.getCreatedOn());
ResourceBundle resourceBundle = ResourceBundleUtil.getBundle("content.Language", request.getLocale(), getClass());
String token = null;

try {
setSessionMessage(request, LanguageUtil.get(resourceBundle,"excel.report.generation.has.started.we.will.send.you.an.email.with.download.link.once.completed"));
ProjectService.Iface client = thriftClients.makeProjectClient();
boolean extendedByReleases = Boolean.valueOf(request.getParameter(PortalConstants.EXTENDED_EXCEL_EXPORT));
List<Project> projects = getFilteredProjectList(request);
int total = client.getMyAccessibleProjectCounts(user);
PaginationData pageData = new PaginationData();
pageData.setAscending(true);
Map<PaginationData, List<Project>> pageDtToProjects;
Set<Project> projects = new HashSet<>();
int displayStart = 0;
int rowsPerPage = 500;
while (0 < total) {
pageData.setDisplayStart(displayStart);
pageData.setRowsPerPage(rowsPerPage);
displayStart = displayStart + rowsPerPage;
pageDtToProjects = client.getAccessibleProjectsSummaryWithPagination(user, pageData);
projects.addAll(pageDtToProjects.entrySet().iterator().next().getValue());
total = total - rowsPerPage;
}

List<Project> listOfProjects = new ArrayList<Project>(projects);
if (!isNullOrEmpty(projectId)) {
Project project = projects.stream().filter(p -> p.getId().equals(projectId)).findFirst().get();
Project project = listOfProjects.stream().filter(p -> p.getId().equals(projectId)).findFirst().get();
fillVendor(project);
filename = String.format("project-%s-%s-%s.xlsx", project.getName(), project.getVersion(), SW360Utils.getCreatedOn());
}
ProjectExporter exporter = new ProjectExporter(
thriftClients.makeComponentClient(),
thriftClients.makeProjectClient(),
user,
projects,
extendedByReleases);
PortletResponseUtil.sendFile(request, response, filename, exporter.makeExcelExport(projects), CONTENT_TYPE_OPENXML_SPREADSHEET);
} catch (IOException | SW360Exception e) {
ProjectExporter exporter = new ProjectExporter(thriftClients.makeComponentClient(),
thriftClients.makeProjectClient(), user, listOfProjects, extendedByReleases);

token = exporter.makeExcelExportForProject(listOfProjects, user);

String portletId = (String) request.getAttribute(WebKeys.PORTLET_ID);
ThemeDisplay tD = (ThemeDisplay) request.getAttribute(WebKeys.THEME_DISPLAY);
long plid = tD.getPlid();

LiferayPortletURL projectUrl = PortletURLFactoryUtil.create(request, portletId, plid,
PortletRequest.RESOURCE_PHASE);
projectUrl.setParameter("action", PortalConstants.DOWNLOAD_EXCEL);
projectUrl.setParameter("token", token);
projectUrl.setParameter(PortalConstants.EXTENDED_EXCEL_EXPORT, String.valueOf(extendedByReleases));

if(!CommonUtils.isNullEmptyOrWhitespace(token)) {
client.sendExportSpreadsheetSuccessMail(projectUrl.toString(), user.getEmail());
}
} catch (IOException | TException | PortletException e) {
log.error("An error occurred while generating the Excel export", e);
response.setProperty(ResourceResponse.HTTP_STATUS_CODE,
Integer.toString(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
Original file line number Diff line number Diff line change
@@ -71,6 +71,11 @@
<portlet:param name="<%=PortalConstants.ACTION%>" value='<%=PortalConstants.LOAD_PROJECT_LIST%>'/>
</portlet:resourceURL>

<portlet:resourceURL var="generateExcelReport">
<portlet:param name="<%=PortalConstants.ACTION%>" value="<%=PortalConstants.EXPORT_TO_EXCEL%>"/>
<portlet:param name="<%=PortalConstants.PROJECT_ID%>" value="${docid}"/>
</portlet:resourceURL>

<div class="container" style="display: none;">
<div class="row">
<div class="col-3 sidebar">
@@ -530,17 +535,15 @@
// Export Spreadsheet action
function exportSpreadsheet(type) {
var portletURL = PortletURL.createURL('<%= PortletURLFactoryUtil.create(request, portletDisplay.getId(), themeDisplay.getPlid(), PortletRequest.RESOURCE_PHASE) %>')
.setParameter('<%=PortalConstants.ACTION%>', '<%=PortalConstants.EXPORT_TO_EXCEL%>');
portletURL.setParameter('<%=Project._Fields.NAME%>', $('#project_name').val());
portletURL.setParameter('<%=Project._Fields.TYPE%>', $('#project_type').val());
portletURL.setParameter('<%=Project._Fields.PROJECT_RESPONSIBLE%>', $('#project_responsible').val());
portletURL.setParameter('<%=Project._Fields.BUSINESS_UNIT%>', $('#group').val());
portletURL.setParameter('<%=Project._Fields.STATE%>', $('#project_state').val());
portletURL.setParameter('<%=Project._Fields.TAG%>', $('#tag').val());
portletURL.setParameter('<%=PortalConstants.EXTENDED_EXCEL_EXPORT%>', type === 'projectWithReleases' ? 'true' : 'false');
window.location.href = portletURL.toString();
var isWithReleases = (type === 'projectWithReleases' ? 'true' : 'false');
$.ajax({
type: 'POST',
url: '<%=generateExcelReport%>',
cache: false,
data: {
"<portlet:namespace/><%=PortalConstants.EXTENDED_EXCEL_EXPORT%>": isWithReleases,
}
});
}
// delete action
Original file line number Diff line number Diff line change
@@ -1496,6 +1496,7 @@ object=Object
import.obligation.element=Import Obligation Element
input=Input
an.obligation.with.the.same.name.already.exists=An Obligation with the same name already exists.
excel.report.generation.has.started.we.will.send.you.an.email.with.download.link.once.completed=Excel report generation has started. We will send you an email with download link once completed.
## Refer to http://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/ and add your datatables language

datatables.lang=https://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/English.json
Original file line number Diff line number Diff line change
@@ -1489,6 +1489,7 @@ list.of.licenses.could.not.be.imported=インポート失敗ライセンス一
list.of.licenses.were.imported=インポート成功ライセンス一覧:
index=No.
importing.process.is.already.running.please.try.again.later=インポートプロセスはすでに実行されています。 後でもう一度やり直してください。
excel.report.generation.has.started.we.will.send.you.an.email.with.download.link.once.completed=Excel report generation has started. We will send you an email with download link once completed.

## Refer to http://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/ and add your datatables language

Original file line number Diff line number Diff line change
@@ -1501,6 +1501,7 @@ object=Đối tượng
import.obligation.element=Nhập nghĩa vụ thành phần
input=Nhập
an.obligation.with.the.same.name.already.exists=Nghĩa vụ có cùng tên đã tồn tại.
excel.report.generation.has.started.we.will.send.you.an.email.with.download.link.once.completed=Excel report generation has started. We will send you an email with download link once completed.
## Refer to http://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/ and add your datatables language

datatables.lang=https://cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Vietnamese.json
Original file line number Diff line number Diff line change
@@ -10,11 +10,16 @@
package org.eclipse.sw360.exporter;


import org.apache.commons.compress.archivers.zip.Zip64Mode;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.eclipse.sw360.datahandler.common.SW360Utils;
import org.eclipse.sw360.datahandler.thrift.SW360Exception;
import org.eclipse.sw360.datahandler.thrift.users.User;
import org.eclipse.sw360.exporter.helper.ExporterHelper;
import org.eclipse.sw360.exporter.utils.SubTable;

@@ -27,7 +32,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.List;
import java.util.UUID;

@@ -38,16 +42,19 @@
*/
public class ExcelExporter<T, U extends ExporterHelper<T>> {

private static final Logger log = LogManager.getLogger(ExcelExporter.class);

protected final U helper;
private static final String SLASH = "/";
private static final String TMP_EXPORTEDFILES = "/tmp/";

public ExcelExporter(U helper) {
this.helper = helper;
}

public String makeExcelExport(List<T> documents) throws IOException, SW360Exception {
public InputStream makeExcelExport(List<T> documents) throws IOException, SW360Exception {
final SXSSFWorkbook workbook = new SXSSFWorkbook();
//final ByteArrayInputStream stream;
String token = UUID.randomUUID().toString();
final ByteArrayInputStream stream;
try {
SXSSFSheet sheet = workbook.createSheet("Data");

@@ -68,24 +75,61 @@ public String makeExcelExport(List<T> documents) throws IOException, SW360Except
/** Copy the streams */
final ByteArrayOutputStream out = new ByteArrayOutputStream();
workbook.write(out);

try(OutputStream outputStream = new FileOutputStream("/tmp/"+token)) {
out.writeTo(outputStream);
out.flush();
}
//stream = new ByteArrayInputStream(out.toByteArray());
stream = new ByteArrayInputStream(out.toByteArray());
}finally{
workbook.dispose();
}
return token;
return stream;
}

public String makeExcelExportForProject(List<T> documents, User user) throws IOException, SW360Exception {
final SXSSFWorkbook workbook = new SXSSFWorkbook();
String token = UUID.randomUUID().toString();
String filePath = TMP_EXPORTEDFILES + user.getEmail() + SLASH;
File file;
try {
File dir = new File(filePath);
dir.mkdir();
file = new File(dir.getPath() + SLASH + SW360Utils.getCreatedOn() + "_" + token);
file.createNewFile();
SXSSFSheet sheet = workbook.createSheet("Data");

/** Adding styles to cells */
CellStyle cellStyle = createCellStyle(workbook);
CellStyle headerStyle = createHeaderStyle(workbook);

/** Create header row */
Row headerRow = sheet.createRow(0);
List<String> headerNames = helper.getHeaders();
fillRow(headerRow, headerNames, headerStyle);

/** Create data rows */
fillValues(sheet, documents, cellStyle);

// removed autosizing of spreadsheet columns for performance reasons

/** Copy the streams */

try (OutputStream outputStream = new FileOutputStream(file.getPath())) {
workbook.setZip64Mode(Zip64Mode.Always);
workbook.write(outputStream);
outputStream.close();
}
} finally {
workbook.dispose();
}
return file.getPath();
}

public InputStream downloadExcelSheet(String token) {
InputStream stream = null;
try {
stream = new FileInputStream(new File("/tmp/" + token));
File file = new File(token);
if (file.exists()) {
stream = new FileInputStream(new File(token));
}
} catch (FileNotFoundException e) {
// logger
log.error("Error getting file", e);
}

return stream;
Loading

0 comments on commit 6dcc7b0

Please sign in to comment.