package org.akaza.openclinica.domain.rule.action; import org.akaza.openclinica.bean.admin.CRFBean; import org.akaza.openclinica.bean.login.ParticipantDTO; import org.akaza.openclinica.bean.login.UserAccountBean; import org.akaza.openclinica.bean.managestudy.EventDefinitionCRFBean; import org.akaza.openclinica.bean.managestudy.StudyBean; import org.akaza.openclinica.bean.managestudy.StudyEventBean; import org.akaza.openclinica.bean.managestudy.StudyEventDefinitionBean; import org.akaza.openclinica.bean.managestudy.StudySubjectBean; import org.akaza.openclinica.bean.service.StudyParameterValueBean; import org.akaza.openclinica.bean.submit.EventCRFBean; import org.akaza.openclinica.bean.submit.ItemDataBean; import org.akaza.openclinica.core.EmailEngine; import org.akaza.openclinica.dao.admin.CRFDAO; import org.akaza.openclinica.dao.core.CoreResources; import org.akaza.openclinica.dao.hibernate.RuleActionRunLogDao; import org.akaza.openclinica.dao.hibernate.RuleSetDao; import org.akaza.openclinica.dao.hibernate.StudyEventDao; import org.akaza.openclinica.dao.hibernate.StudyEventDefinitionDao; import org.akaza.openclinica.dao.login.UserAccountDAO; import org.akaza.openclinica.dao.managestudy.EventDefinitionCRFDAO; import org.akaza.openclinica.dao.managestudy.StudyDAO; import org.akaza.openclinica.dao.managestudy.StudyEventDAO; import org.akaza.openclinica.dao.managestudy.StudyEventDefinitionDAO; import org.akaza.openclinica.dao.managestudy.StudySubjectDAO; import org.akaza.openclinica.dao.service.StudyParameterValueDAO; import org.akaza.openclinica.dao.submit.EventCRFDAO; import org.akaza.openclinica.dao.submit.ItemDataDAO; import org.akaza.openclinica.domain.datamap.EventDefinitionCrf; import org.akaza.openclinica.domain.rule.RuleSetBean; import org.akaza.openclinica.domain.rule.RuleSetRuleBean; import org.akaza.openclinica.exception.OpenClinicaSystemException; import org.akaza.openclinica.logic.rulerunner.ExecutionMode; import org.akaza.openclinica.logic.rulerunner.RuleSetBulkRuleRunner; import org.akaza.openclinica.logic.rulerunner.RuleRunner.RuleRunnerMode; import org.akaza.openclinica.patterns.ocobserver.OnStudyEventUpdated; import org.akaza.openclinica.patterns.ocobserver.StudyEventChangeDetails; import org.akaza.openclinica.service.BulkEmailSenderService; import org.akaza.openclinica.service.pmanage.Authorization; import org.akaza.openclinica.service.pmanage.ParticipantPortalRegistrar; import org.akaza.openclinica.service.rule.RuleSetService; import org.akaza.openclinica.service.rule.expression.ExpressionService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.mail.MailException; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.mail.javamail.MimeMessagePreparator; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.xml.MarshallingHttpMessageConverter; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.StringTokenizer; import javax.mail.MessagingException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import javax.sql.DataSource; public class NotificationActionProcessor implements ActionProcessor, Runnable { protected final Logger logger = LoggerFactory.getLogger(getClass().getName()); DataSource ds; EmailEngine emailEngine; JavaMailSenderImpl mailSender; RuleSetRuleBean ruleSetRule; StudySubjectDAO ssdao; UserAccountDAO udao; StudyParameterValueDAO spvdao; RuleSetService ruleSetService; RuleSetDao ruleSetDao; ParticipantDTO pDTO; RuleActionBean ruleActionBean; ParticipantPortalRegistrar participantPortalRegistrar; String email; String[] listOfEmails; StudySubjectBean ssBean; UserAccountBean uBean; StudyBean studyBean; String message; String url; String emailSubject; String participateStatus; public NotificationActionProcessor(DataSource ds, JavaMailSenderImpl mailSender, RuleActionBean ruleActionBean, ParticipantDTO pDTO, ParticipantPortalRegistrar participantPortalRegistrar, String email) { this.ds = ds; this.mailSender = mailSender; this.ruleActionBean = ruleActionBean; this.pDTO = pDTO; this.participantPortalRegistrar = participantPortalRegistrar; this.email = email; } public NotificationActionProcessor(String[] listOfEmails, UserAccountBean uBean, StudyBean studyBean, String message, String emailSubject, ParticipantPortalRegistrar participantPortalRegistrar, JavaMailSenderImpl mailSender , String participateStatus) { this.listOfEmails = listOfEmails; this.message = message; this.emailSubject = emailSubject; this.uBean = uBean; this.participantPortalRegistrar = participantPortalRegistrar; this.mailSender = mailSender; this.studyBean = studyBean; this.participateStatus=participateStatus; } public NotificationActionProcessor(DataSource ds, JavaMailSenderImpl mailSender, RuleSetRuleBean ruleSetRule) { this.ds = ds; this.mailSender = mailSender; this.ruleSetRule = ruleSetRule; ssdao = new StudySubjectDAO(ds); udao = new UserAccountDAO(ds); spvdao = new StudyParameterValueDAO(ds); } public RuleActionBean execute(ExecutionMode executionMode, RuleActionBean ruleActionBean, ParticipantDTO pDTO , String email ) { switch (executionMode) { case DRY_RUN: { return ruleActionBean; } case SAVE: { createMimeMessagePreparator(pDTO, email); return null; } default: return null; } } private void createMimeMessagePreparator(final ParticipantDTO pDTO, final String email){ MimeMessagePreparator preparator = new MimeMessagePreparator() { public void prepare(MimeMessage mimeMessage) throws Exception { MimeMessageHelper message = new MimeMessageHelper(mimeMessage); message.setFrom(EmailEngine.getAdminEmail()); message.setTo(email); message.setSubject(pDTO.getEmailSubject()); message.setText(pDTO.getMessage()); } }; BulkEmailSenderService.addMimeMessage(preparator); } private void sendEmail(RuleActionBean ruleAction, ParticipantDTO pDTO) throws OpenClinicaSystemException { logger.info("Sending email..."); try { MimeMessage mimeMessage = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(mimeMessage); helper.setFrom(EmailEngine.getAdminEmail()); helper.setTo(pDTO.getEmailAccount()); helper.setSubject(pDTO.getEmailSubject()); helper.setText(pDTO.getMessage()); mailSender.send(mimeMessage); logger.debug("Email sent successfully on {}", new Date()); } catch (MailException me) { logger.error("Email could not be sent"); throw new OpenClinicaSystemException(me.getMessage()); } catch (MessagingException me) { logger.error("Email could not be sent"); throw new OpenClinicaSystemException(me.getMessage()); } } @Override public RuleActionBean execute(RuleRunnerMode ruleRunnerMode, ExecutionMode executionMode, RuleActionBean ruleAction, ItemDataBean itemDataBean, String itemData, StudyBean currentStudy, UserAccountBean ub, Object... arguments) { // TODO Auto-generated method stub return null; } public void runNotificationAction(RuleActionBean ruleActionBean, RuleSetBean ruleSet, int studySubjectBeanId, int eventOrdinal) { String emailList = ((NotificationActionBean) ruleActionBean).getTo(); String message = ((NotificationActionBean) ruleActionBean).getMessage(); String emailSubject = ((NotificationActionBean) ruleActionBean).getSubject(); int sed_Id = ruleSet.getStudyEventDefinitionId(); int studyId = ruleSet.getStudyId(); String eventName = getStudyEventDefnBean(sed_Id).getName(); if (eventOrdinal != 1) eventName = eventName + "(" + eventOrdinal + ")"; String studyName = getStudyBean(studyId).getName(); if (message==null) message=""; if (emailSubject==null) emailSubject=""; message = message.replaceAll("\\$\\{event.name}", eventName); message = message.replaceAll("\\$\\{study.name}", studyName); emailSubject = emailSubject.replaceAll("\\$\\{event.name}", eventName); emailSubject = emailSubject.replaceAll("\\$\\{study.name}", studyName); ParticipantDTO pDTO = null; StudyBean studyBean = getStudyBean(studyId); String[] listOfEmails = emailList.split(","); StudySubjectBean ssBean = (StudySubjectBean) ssdao.findByPK(studySubjectBeanId); StudyBean parentStudyBean = getParentStudy(ds, studyBean); String pUserName = parentStudyBean.getOid() + "." + ssBean.getOid(); UserAccountBean uBean = (UserAccountBean) udao.findByUserName(pUserName); StudyParameterValueBean pStatus = spvdao.findByHandleAndStudy(studyBean.getId(), "participantPortal"); String participateStatus = pStatus.getValue().toString(); // enabled , disabled Thread thread = new Thread(new NotificationActionProcessor(listOfEmails, uBean, studyBean, message, emailSubject, participantPortalRegistrar, mailSender,participateStatus)); thread.start(); } @Override public void run() { String hostname = ""; String url = ""; participantPortalRegistrar = new ParticipantPortalRegistrar(); try { hostname = participantPortalRegistrar.getStudyHost(studyBean.getOid()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } url = hostname.replaceAll("login", "plogin"); message = message.replaceAll("\\$\\{participant.url}", url); emailSubject = emailSubject.replaceAll("\\$\\{participant.url}", url); pDTO = getParticipantInfo(uBean); if (pDTO != null) { String msg = null; String eSubject = null; msg = message.replaceAll("\\$\\{participant.accessCode}", pDTO.getAccessCode()); msg = msg.replaceAll("\\$\\{participant.firstname}", pDTO.getfName()); eSubject = emailSubject.replaceAll("\\$\\{participant.accessCode}", pDTO.getAccessCode()); eSubject = eSubject.replaceAll("\\$\\{participant.firstname}", pDTO.getfName()); String loginUrl = url + "?access_code=" + pDTO.getAccessCode() + "&auto_login=true"; msg = msg.replaceAll("\\$\\{participant.loginurl}", loginUrl); eSubject = eSubject.replaceAll("\\$\\{participant.loginurl}", loginUrl); msg = msg.replaceAll("\\\\n", "\n"); eSubject = eSubject.replaceAll("\\\\n", "\n"); message = message.replaceAll("\\\\n", "\n"); emailSubject = emailSubject.replaceAll("\\\\n", "\n"); pDTO.setMessage(msg); pDTO.setEmailSubject(eSubject); pDTO.setUrl(url); pDTO.setOrigMessage(message); pDTO.setOrigEmailSubject(emailSubject); pDTO.setParticipantEmailAccount(pDTO.getEmailAccount()); } else { pDTO = buildNewPDTO(); message = message.replaceAll("\\\\n", "\n"); emailSubject = emailSubject.replaceAll("\\\\n", "\n"); pDTO.setOrigMessage(message); pDTO.setOrigEmailSubject(emailSubject); } for (String email : listOfEmails) { if (email.trim().equals("${participant}") || participateStatus.equals("enabled")) { if (email.trim().equals("${participant}")){ pDTO.setEmailAccount(pDTO.getParticipantEmailAccount()); pDTO.setEncryptedEmailAccount(Boolean.TRUE); }else{ pDTO.setEmailAccount(email.trim()); pDTO.setPhone(null); pDTO.setEncryptedEmailAccount(Boolean.FALSE); } // Send Email thru Mandrill Mail Server try { participantPortalRegistrar.sendEmailThruMandrillViaOcui(pDTO,hostname); } catch (Exception e) { e.getStackTrace(); } System.out.println(pDTO.getMessage() + " (Email Send to Participant from Mandrill : " + pDTO.getEmailAccount() + ")"); } else { pDTO.setEmailAccount(email.trim()); // System.out.println(); // Send Email thru Local Mail Server execute(ExecutionMode.SAVE, ruleActionBean, pDTO , email.trim()); System.out.println(pDTO.getMessage() + " (Email sent to Hard Coded email address from OC Mail Server : " + pDTO.getEmailAccount() + ")"); } } } public ParticipantDTO buildNewPDTO() { pDTO = new ParticipantDTO(); String msg = null; msg = message.replaceAll("\\$\\{participant.accessCode}", ""); msg = msg.replaceAll("\\$\\{participant.firstname}", ""); msg = msg.replaceAll("\\$\\{participant.loginurl}", ""); msg = msg.replaceAll("\\\\n", "\n"); pDTO.setMessage(msg); String eSubject = null; eSubject = emailSubject.replaceAll("\\$\\{participant.accessCode}", ""); eSubject = eSubject.replaceAll("\\$\\{participant.firstname}", ""); eSubject = eSubject.replaceAll("\\$\\{participant.loginurl}", ""); eSubject = eSubject.replaceAll("\\\\n", "\n"); pDTO.setEmailSubject(eSubject); return pDTO; } public ParticipantDTO getParticipantInfo(UserAccountBean uBean) { ParticipantDTO pDTO = null; if (uBean != null && uBean.isActive()) { if (uBean.getEmail() == null) return null; pDTO = new ParticipantDTO(); pDTO.setAccessCode(uBean.getAccessCode()); pDTO.setfName(uBean.getFirstName()); pDTO.setEmailAccount(uBean.getEmail()); pDTO.setPhone(uBean.getPhone()); } else { return null; } return pDTO; } public ArrayList<StudySubjectBean> getAllParticipantStudySubjectsPerStudy(int studyId, DataSource ds) { StudySubjectDAO ssdao = new StudySubjectDAO(ds); ArrayList<StudySubjectBean> ssBeans = ssdao.findAllByStudyId(studyId); return ssBeans; } public StudyEventBean getStudyEvent(StudySubjectBean ssBean, DataSource ds) { StudyEventDAO studyEventDao = new StudyEventDAO(ds); StudyEventBean seBean = (StudyEventBean) studyEventDao.getNextScheduledEvent(ssBean.getOid()); return seBean; } private StudyBean getParentStudy(DataSource ds, StudyBean study) { StudyDAO sdao = new StudyDAO(ds); if (study.getParentStudyId() == 0) { return study; } else { StudyBean parentStudy = (StudyBean) sdao.findByPK(study.getParentStudyId()); return parentStudy; } } public StudyEventDefinitionBean getStudyEventDefnBean(int sed_Id) { StudyEventDefinitionDAO sedao = new StudyEventDefinitionDAO(ds); return (StudyEventDefinitionBean) sedao.findByPK(sed_Id); }; public StudyBean getStudyBean(int studyId) { StudyDAO sdao = new StudyDAO(ds); return (StudyBean) sdao.findByPK(studyId); } public RuleSetService getRuleSetService() { return ruleSetService; } private List<RuleSetBean> createRuleSet(Integer studyEventDefId) { return getRuleSetDao().findAllByStudyEventDefIdWhereItemIsNull(studyEventDefId); } public RuleSetDao getRuleSetDao() { return ruleSetDao; } }