diff --git a/docs/index.md b/docs/index.md index 5acd957298dbc83806c7c459b47500eb6590eb1a..f32feacf0fd796d36218407a0c9eb01c38f3fa2d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,6 +4,8 @@ [Authentication](./authentication.md) +[Messaging](./messaging.md) + [Troubleshooting](./troubleshooting.md) diff --git a/docs/messaging.md b/docs/messaging.md new file mode 100644 index 0000000000000000000000000000000000000000..7991cc23ebe401d2e3faba171985593da46700b2 --- /dev/null +++ b/docs/messaging.md @@ -0,0 +1,15 @@ +# VIPSLogic messaging + +## Configuration +These system properties must be set in order for the messaging system to function: + +```xml +<property name="no.nibio.vips.logic.messaging.dist.SIMULATE_MAIL_SENDING" value="true"/> +<property name="no.nibio.vips.logic.messaging.dist.MAIL_SENDER_ADDRESS" value="noreply@foobar.com"/> +<property name="no.nibio.vips.logic.messaging.dist.SMS_SERVER" value="smsgateway.foobar.com"/> +<property name="no.nibio.vips.logic.messaging.dist.SMS_USERNAME" value="foobar"/> +<property name="no.nibio.vips.logic.messaging.dist.SMS_PASSWORD" value="foobar"/> +<property name="no.nibio.vips.logic.messaging.dist.SMS_SENDER_SRC" value="foobar"/> +<property name="no.nibio.vips.logic.messaging.dist.TRAFFIC_LOG_DIRECTORY" value="/var/log/trafficLog/"/> + +``` \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8c0aa4b57af4ff9b79b76648c67cc64ebd6a9e15..0ac89a0fa4aa684b70e7438baa3b601657169c7a 100755 --- a/pom.xml +++ b/pom.xml @@ -25,19 +25,27 @@ <url>https://nexus.bedatadriven.com/content/groups/public/</url> </repository> <repository> - <id>osgeo</id> - <name>OSGeo Release Repository</name> - <url>https://repo.osgeo.org/repository/release/</url> - <snapshots><enabled>false</enabled></snapshots> - <releases><enabled>true</enabled></releases> - </repository> - <repository> - <id>osgeo-snapshot</id> - <name>OSGeo Snapshot Repository</name> - <url>https://repo.osgeo.org/repository/snapshot/</url> - <snapshots><enabled>true</enabled></snapshots> - <releases><enabled>false</enabled></releases> - </repository> + <id>osgeo</id> + <name>OSGeo Release Repository</name> + <url>https://repo.osgeo.org/repository/release/</url> + <snapshots> + <enabled>false</enabled> + </snapshots> + <releases> + <enabled>true</enabled> + </releases> + </repository> + <repository> + <id>osgeo-snapshot</id> + <name>OSGeo Snapshot Repository</name> + <url>https://repo.osgeo.org/repository/snapshot/</url> + <snapshots> + <enabled>true</enabled> + </snapshots> + <releases> + <enabled>false</enabled> + </releases> + </repository> <repository> <id>unidata-releases</id> <name>Unidata Releases</name> @@ -46,12 +54,12 @@ </repositories> <dependencies> - <dependency> - <groupId>javax.xml.bind</groupId> - <artifactId>jaxb-api</artifactId> - <version>2.3.1</version> - <scope>compile</scope> - </dependency> + <dependency> + <groupId>javax.xml.bind</groupId> + <artifactId>jaxb-api</artifactId> + <version>2.3.1</version> + <scope>compile</scope> + </dependency> <dependency> <groupId>edu.ucar</groupId> <artifactId>cdm</artifactId> @@ -72,16 +80,16 @@ <groupId>postgresql</groupId> </exclusion> <exclusion> - <groupId>org.dom4j</groupId> - <artifactId>dom4j</artifactId> + <groupId>org.dom4j</groupId> + <artifactId>dom4j</artifactId> </exclusion> </exclusions> </dependency> <dependency> - <groupId>javax.servlet</groupId> - <artifactId>javax.servlet-api</artifactId> - <version>4.0.1</version> - <scope>test</scope> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <version>4.0.1</version> + <scope>test</scope> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> @@ -181,10 +189,10 @@ <artifactId>hibernate-core</artifactId> <version>5.6.3.Final</version> <exclusions> - <exclusion> - <groupId>org.dom4j</groupId> - <artifactId>dom4j</artifactId> - </exclusion> + <exclusion> + <groupId>org.dom4j</groupId> + <artifactId>dom4j</artifactId> + </exclusion> </exclusions> </dependency> <dependency> @@ -216,6 +224,12 @@ <artifactId>jts2geojson</artifactId> <version>0.16.1</version> </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-csv</artifactId> + <version>1.2</version> + <type>jar</type> + </dependency> <dependency> <groupId>javax</groupId> <artifactId>javaee-web-api</artifactId> @@ -303,6 +317,12 @@ <artifactId>jackson-datatype-jts</artifactId> <version>2.4</version> </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>1.7.36</version> + <scope>provided</scope> + </dependency> </dependencies> <build> diff --git a/src/main/java/no/nibio/vips/logic/messaging/MessagingBean.java b/src/main/java/no/nibio/vips/logic/messaging/MessagingBean.java index 2479e85dceaf8aa7921555f867091fa297be671d..c18f42d83240ceaac6488f63d7934281008ab815 100755 --- a/src/main/java/no/nibio/vips/logic/messaging/MessagingBean.java +++ b/src/main/java/no/nibio/vips/logic/messaging/MessagingBean.java @@ -45,6 +45,9 @@ import no.nibio.vips.logic.entity.Message; import no.nibio.vips.logic.entity.MessageLocale; import no.nibio.vips.logic.entity.Observation; import no.nibio.vips.logic.entity.VipsLogicUser; +import no.nibio.vips.logic.messaging.distribution.IVipsMessageHandler; +import no.nibio.vips.logic.messaging.distribution.VipsMessageInputHandler; +import no.nibio.vips.logic.messaging.distribution.entity.VipsMessage; import no.nibio.vips.logic.util.Globals; import no.nibio.vips.logic.util.RESTAuthenticator; import no.nibio.vips.logic.util.SystemTime; @@ -114,7 +117,7 @@ public class MessagingBean { // Store it em.persist(uMessage); - + /* ResteasyClient client = (ResteasyClient) ResteasyClientBuilder.newClient();//new ResteasyClientBuilder().build(); //client.register(new RESTAuthenticator("user", "userPass")); client.register(new RESTAuthenticator("VIPSLogic", "plmoknijbuhv000")); @@ -148,7 +151,28 @@ public class MessagingBean { { System.out.println("Messaging system disabled. This message was not sent: " + uMessage.toString()); } + */ + // TODO Handle errors better! + try + { + if ( + System.getProperty("no.nibio.vips.logic.DISABLE_MESSAGING_SYSTEM") == null + || System.getProperty("no.nibio.vips.logic.DISABLE_MESSAGING_SYSTEM").equals("false") + ) + { + IVipsMessageHandler vipsMessageHandler = new VipsMessageInputHandler(); + vipsMessageHandler.sendMessage(new VipsMessage(uMessage)); + } + else + { + System.out.println("Messaging system disabled. This message was not sent: " + uMessage.toString()); + } + } + catch(Exception ex) + { + ex.printStackTrace(); + } return uMessage; } diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/IVipsMessageHandler.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/IVipsMessageHandler.java new file mode 100755 index 0000000000000000000000000000000000000000..aff13fc27d51cddfeeb5bddf8a717549ab41586e --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/IVipsMessageHandler.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ +package no.nibio.vips.logic.messaging.distribution; + +import no.nibio.vips.logic.messaging.distribution.entity.VipsMessage; +import no.nibio.vips.logic.messaging.distribution.entity.VipsSendMsgResult; + + + +/** + * This is a interface to handle request responses from the the JSON interface + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + * + */ +public interface IVipsMessageHandler { + + + /** + * Send given message to given list of recipients + * + * @param vm + * @return + * @throws Exception + */ + public VipsSendMsgResult sendMessage(VipsMessage vm) throws Exception; + + +} diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/VipsMessageInputHandler.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/VipsMessageInputHandler.java new file mode 100755 index 0000000000000000000000000000000000000000..317e9ea4b4420b0753fad5bdf57d6765ed62b385 --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/VipsMessageInputHandler.java @@ -0,0 +1,515 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ +package no.nibio.vips.logic.messaging.distribution; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.Hashtable; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicLong; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import no.nibio.vips.logic.messaging.distribution.entity.DistributionTypeEnum; +import no.nibio.vips.logic.messaging.distribution.entity.MsgDistResultEnum; +import no.nibio.vips.logic.messaging.distribution.entity.MsgReceiver; +import no.nibio.vips.logic.messaging.distribution.entity.MsgToSend; +import no.nibio.vips.logic.messaging.distribution.entity.VipsMessage; +import no.nibio.vips.logic.messaging.distribution.entity.VipsSendMsgResult; +import no.nibio.vips.logic.messaging.distribution.send.CSVTrafficFileLogger; +import no.nibio.vips.logic.messaging.distribution.send.IDeliveryMsgHandler; +import no.nibio.vips.logic.messaging.distribution.send.MailMsgDeliveryHandler; +import no.nibio.vips.logic.messaging.distribution.send.SingleMsgSendResult; +import no.nibio.vips.logic.messaging.distribution.send.SingleMsgSentStateEnum; +import no.nibio.vips.logic.messaging.distribution.send.SmsMsgDeliveryHandler; + + + +/** + * Handles client communication with the different types of channels that are + * available + * + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + * + */ +public class VipsMessageInputHandler implements IVipsMessageHandler { + + private static Logger LOGGER = LoggerFactory.getLogger(VipsMessageInputHandler.class); + + + // where to out log files for th etraf + private String trafficLogDirectory; + + // mail server properties + private String smtpMailserver; + private String mailSenderAddress; + private Boolean simulateMailSending; + + // smcs server properties + private String smscServer; + private String smscUsername; + private String smscPassword; + private String smscSenderSrc; + + // the default locale be used if there are no matching value between the sender and the messages + // if the there are no messages in this local the message will just be taken. + private String msgLocaleIfNoMatch = "en"; + + // the blocker queue to avoid to many to many results to be fetched at at time + // TODO fix this to work inside boundig box + private BlockingQueue subJobBlockingQueue; + + // A thread safe temporary job counter + // Will be reset when tomcat restarts + private final AtomicLong jobnr = new AtomicLong(0); + + /** + * ExecutorService to hadle message sending + */ + private ExecutorService executorService; + + // The list of message output handlers + Hashtable<DistributionTypeEnum, IDeliveryMsgHandler> msgHandlerList = new Hashtable<>(); + + // TODO maybe move this to a config file + public VipsMessageInputHandler() { + this.init(); + } + + public void init() { + IDeliveryMsgHandler mailHandler = new MailMsgDeliveryHandler(getSmtpMailserver(), getMailSenderAddress(), isSimumlateMailSending()); + msgHandlerList.put(mailHandler.getDistributionType(), mailHandler); + + IDeliveryMsgHandler smsHandler = new SmsMsgDeliveryHandler(getSmscServer(), getSmscUsername(), getSmscPassword(), getSmscSenderSrc(), + isSimumlateMailSending()); + msgHandlerList.put(smsHandler.getDistributionType(), smsHandler); + + // check if log directory exist + File f = new File(this.getTrafficLogDirectory()); + if (!f.exists()) { + f.mkdir(); + /* + if (logger.isDebugEnabled()) { + logger.debug("create traffic log file directory " + trafficLogDirectory); + } + */ + } + + // set up a job queue with max + subJobBlockingQueue = new ArrayBlockingQueue(1); + this.executorService = Executors.newFixedThreadPool(10); + + } + + @Override + public VipsSendMsgResult sendMessage(VipsMessage vm) throws Exception { + + + LOGGER.debug("vm message expiresAt " + vm.expiresAt); + + VipsSendMsgResult vipsSendMsgResult = new VipsSendMsgResult(); + + Long nextJob = jobnr.incrementAndGet(); + + try { + + LOGGER.debug("Ready to start next job" + nextJob); + + // add to job queue or wait to many jobs are running + subJobBlockingQueue.put(nextJob); + + // start vips message job, this does take a long time, because we here initiate the job sending + vipsSendMsgResult = startsVipsMessageJob(vm); + + } catch (InterruptedException e) { + vipsSendMsgResult.status = MsgDistResultEnum.FailedNotSentWithException; + LOGGER.error("Failed to send message: ", e); + + } finally { + // remove the job so the next job can run + subJobBlockingQueue.remove(nextJob); + + } + + return vipsSendMsgResult; + } + + /** + * Starts the vips message job + * + * @param vm + * @param vipsSendMsgResult + * @param msgSentResult + * @return + */ + private VipsSendMsgResult startsVipsMessageJob(VipsMessage vm) { + + + Date currentTime = new Date(); + String pattern = "yyyy_MM_dd_H_m"; + SimpleDateFormat format = new SimpleDateFormat(pattern); + + VipsSendMsgResult vipsSendMsgResult = new VipsSendMsgResult(); + vipsSendMsgResult.status = MsgDistResultEnum.FailedNotSent; + UUID uuid = UUID.randomUUID(); + String jobId = uuid.toString(); + vipsSendMsgResult.jobId = jobId; + vipsSendMsgResult.numRecipients = vm.distributionList.size(); + + // trafficLogDirectory + String fileNameReceived = getTrafficLogDirectory() + vipsSendMsgResult.jobId + "_received_" + format.format(currentTime); + // create a log with jobid name and received time + // the file should contain the following fileds + CSVTrafficFileLogger.writeCsvFilerReceived(fileNameReceived, vm.distributionList); + + // the filename to keep the results + String fileNameSentResult = getTrafficLogDirectory() + vipsSendMsgResult.jobId + "_sent_" + format.format(currentTime); + + // check if message is to old before trying to send it + // TODO may be move this check to when sending message, but then some messages may be sent and other not ???? + if (vm.expiresAt != null && vm.expiresAt.before(currentTime)) { + vipsSendMsgResult.status = MsgDistResultEnum.FailedNotSentToOld; + // list of result to used for logging + ArrayList<SingleMsgSendResult> msgSentResult = new ArrayList<>(); + + vm.distributionList.stream().map((msgReceiver) -> new SingleMsgSendResult(msgReceiver, SingleMsgSentStateEnum.FailedNotSentToOld)).forEachOrdered((msgSendResult) -> { + msgSentResult.add(msgSendResult); + }); + // create a log with jobid name and received time + // the file should contain the following fileds + CSVTrafficFileLogger.writeCsvFilerReceived(fileNameSentResult, msgSentResult); + + } else { + + // submit the job and leave, dont't wiath for any results + RunVipsMessageJob runVipsMessageJob = new RunVipsMessageJob(vm, vipsSendMsgResult, fileNameSentResult); + executorService.submit(runVipsMessageJob); + + } + + + return vipsSendMsgResult; + } + + /** + * + * Runs a job against and get info about single farm + * + */ + class RunVipsMessageJob implements Callable<VipsSendMsgResult> { + + private final VipsMessage vm; + private final VipsSendMsgResult vipsSendMsgResult; + private final String fileNameSentResult; + + public RunVipsMessageJob(VipsMessage vm, VipsSendMsgResult vipsSendMsgResult, String fileNameSentResult) { + this.vm = vm; + this.vipsSendMsgResult = vipsSendMsgResult; + this.fileNameSentResult = fileNameSentResult; + } + + @Override + public VipsSendMsgResult call() { + + + // list of result to used for logging + ArrayList<SingleMsgSendResult> msgSentResult = new ArrayList<>(); + + try { + + Integer messageCount = 0; + + LOGGER.debug("start sending messages "); + + // loop through all rescievers + for (MsgReceiver msgReceiver : vm.distributionList) { + + LOGGER.debug("start with message number " + (messageCount + 1)); + + IDeliveryMsgHandler iSendMsg = msgHandlerList.get(msgReceiver.type); + if (iSendMsg != null && vm.getMessageLocalVersions() != null && !vm.getMessageLocalVersions().isEmpty()) { + List<MsgToSend> messageLocalVersions = vm.getMessageLocalVersions(); + + // set a default message to send + MsgToSend msgToSend = null; + + if (msgReceiver.preferredLocale != null) { + for (MsgToSend msgTo : messageLocalVersions) { + if (msgReceiver.preferredLocale.equals(msgTo.getLocale())) { + msgToSend = msgTo; + LOGGER.debug("use correct locale " + msgTo.getLocale()); + break; + } + } + } + + if (msgToSend == null) { + for (MsgToSend msgTo : messageLocalVersions) { + if (msgLocaleIfNoMatch.equals(msgTo.getLocale())) { + msgToSend = msgTo; + + LOGGER.debug("use system locale " + msgTo.getLocale()); + + break; + } + } + } + + if (msgToSend == null) { + LOGGER.debug("No loacale found for " + msgReceiver.preferredLocale); + msgToSend = messageLocalVersions.get(0); + } + + SingleMsgSentStateEnum sendMessageResult = iSendMsg.sendMessage(vm, msgReceiver, msgToSend); + + if (!SingleMsgSentStateEnum.Ok.equals(sendMessageResult)) { + System.out.println( + "Send message " + msgToSend.msgBody + " of type " + msgReceiver.type + " failed for " + msgReceiver.msgDeliveryAddress); + } else { + messageCount++; + } + + LOGGER.debug("Valid handler of type " + iSendMsg.getDistributionType() + " found for " + msgReceiver.msgDeliveryAddress + + " send mesage result " + sendMessageResult); + SingleMsgSendResult msgSendResult = new SingleMsgSendResult(msgReceiver, sendMessageResult); + msgSentResult.add(msgSendResult); + + } else { + SingleMsgSendResult msgSendResult = new SingleMsgSendResult(msgReceiver, SingleMsgSentStateEnum.FailedNotSentNoDistType); + msgSentResult.add(msgSendResult); + + System.out.println("No valid handler of type " + msgReceiver.type + " found for " + msgReceiver.msgDeliveryAddress); + } + + LOGGER.debug("done with message number " + messageCount); + + } + + if (messageCount == 0) { + vipsSendMsgResult.status = MsgDistResultEnum.FailedNotSent; + vipsSendMsgResult.numRecipients = 0; + } else if (messageCount != vm.distributionList.size()) { + vipsSendMsgResult.status = MsgDistResultEnum.SomeMessagesFailed; + vipsSendMsgResult.numRecipients = messageCount; + } else { + vipsSendMsgResult.status = MsgDistResultEnum.Ok; + } + + LOGGER.debug("Done sending messages " + messageCount); + + } catch (Exception e) { + vipsSendMsgResult.status = MsgDistResultEnum.FailedNotSentWithException; + LOGGER.error("Failed to send message",e); + } catch (Throwable e1) { + vipsSendMsgResult.status = MsgDistResultEnum.FailedNotSentWithException; + LOGGER.error("Failed to send message",e1); + } finally { + CSVTrafficFileLogger.writeCsvFilerReceived(fileNameSentResult, msgSentResult); + + } + + + + return vipsSendMsgResult; + + } + + } + + /** + * @return the smtpMailserver + */ + public String getSmtpMailserver() { + if(this.smtpMailserver == null) + { + this.smtpMailserver = System.getProperty("no.nibio.vips.logic.SMTP_SERVER"); + } + return smtpMailserver; + } + + /** + * @param smtpMailserver the smtpMailserver to set + */ + public void setSmtpMailserver(String smtpMailserver) { + this.smtpMailserver = smtpMailserver; + } + + /** + * @return the mailSenderAddress + */ + public String getMailSenderAddress() { + if(this.mailSenderAddress == null) + { + this.mailSenderAddress = System.getProperty("no.nibio.vips.logic.messaging.dist.MAIL_SENDER_ADDRESS"); + } + return mailSenderAddress; + } + + /** + * @param mailSenderAddress the mailSenderAddress to set + */ + public void setMailSenderAddress(String mailSenderAddress) { + this.mailSenderAddress = mailSenderAddress; + } + + /** + * @return the simumlateMailSending. DEFAULT is false + */ + public boolean isSimumlateMailSending() { + if(this.simulateMailSending == null) + { + String simulateMailsendingProp = System.getProperty("no.nibio.vips.logic.messaging.dist.SIMULATE_MAIL_SENDING"); + this.simulateMailSending = simulateMailsendingProp == null ? true: simulateMailsendingProp.equals("true"); + } + return simulateMailSending; + } + + /** + * @param simumlateMailSending the simumlateMailSending to set + */ + public void setSimumlateMailSending(boolean simumlateMailSending) { + this.simulateMailSending = simumlateMailSending; + } + + /** + * @return the trafficLogDirectory + */ + public String getTrafficLogDirectory() { + if(this.trafficLogDirectory == null) + { + this.trafficLogDirectory = System.getProperty("no.nibio.vips.logic.messaging.dist.TRAFFIC_LOG_DIRECTORY"); + } + return trafficLogDirectory; + } + + /** + * @param trafficLogDirectory the trafficLogDirectory to set + */ + public void setTrafficLogDirectory(String trafficLogDirectory) { + this.trafficLogDirectory = trafficLogDirectory; + } + + /** + * @return the smscServer + */ + public String getSmscServer() { + if(this.smscServer == null) + { + this.smscServer = System.getProperty("no.nibio.vips.logic.messaging.dist.SMS_SERVER"); + } + return smscServer; + } + + /** + * @param smscServer the smscServer to set + */ + public void setSmscServer(String smscServer) { + this.smscServer = smscServer; + } + + /** + * @return the smscUsername + */ + public String getSmscUsername() { + if(this.smscUsername == null) + { + this.smscUsername = System.getProperty("no.nibio.vips.logic.messaging.dist.SMS_USERNAME"); + } + return smscUsername; + } + + /** + * @param smscUsername the smscUsername to set + */ + public void setSmscUsername(String smscUsername) { + this.smscUsername = smscUsername; + } + + /** + * @return the smscPassword + */ + public String getSmscPassword() { + if(this.smscPassword == null) + { + this.smscPassword = System.getProperty("no.nibio.vips.logic.messaging.dist.SMS_PASSWORD"); + } + return smscPassword; + } + + /** + * @param smscPassword the smscPassword to set + */ + public void setSmscPassword(String smscPassword) { + this.smscPassword = smscPassword; + } + + /** + * @return the smscSenderSrc + */ + public String getSmscSenderSrc() { + if(this.smscSenderSrc == null) + { + this.smscSenderSrc = System.getProperty("no.nibio.vips.logic.messaging.dist.SMS_SENDER_SRC"); + } + return smscSenderSrc; + } + + /** + * @param smscSenderSrc the smscSenderSrc to set + */ + public void setSmscSenderSrc(String smscSenderSrc) { + this.smscSenderSrc = smscSenderSrc; + } + + /** + * @return the executorService + */ + public ExecutorService getExecutorService() { + return executorService; + } + + /** + * @param executorService the executorService to set + */ + public void setExecutorService(ExecutorService executorService) { + this.executorService = executorService; + } + + /** + * @return the msgLocaleIfNoMatch + */ + public String getMsgLocaleIfNoMatch() { + return msgLocaleIfNoMatch; + } + + /** + * @param msgLocaleIfNoMatch the msgLocaleIfNoMatch to set + */ + public void setMsgLocaleIfNoMatch(String msgLocaleIfNoMatch) { + this.msgLocaleIfNoMatch = msgLocaleIfNoMatch; + } +} diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/VipsMsgDummyDistImpl.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/VipsMsgDummyDistImpl.java new file mode 100755 index 0000000000000000000000000000000000000000..643609eeed7373c5fec3e2a01a286f515f7040ff --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/VipsMsgDummyDistImpl.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ +package no.nibio.vips.logic.messaging.distribution; + +import java.util.UUID; +import no.nibio.vips.logic.messaging.distribution.entity.MsgDistResultEnum; +import no.nibio.vips.logic.messaging.distribution.entity.VipsMessage; +import no.nibio.vips.logic.messaging.distribution.entity.VipsSendMsgResult; + +/** + * Handles client communication requests used by the topo client + * + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + * + */ +public class VipsMsgDummyDistImpl implements IVipsMessageHandler { + + + public VipsSendMsgResult sendMessage(VipsMessage vm) throws Exception { + + + VipsSendMsgResult vipsSendMsgResult = new VipsSendMsgResult(); + vipsSendMsgResult.status = MsgDistResultEnum.FailedNotSent; + + try { + + UUID uuid = UUID.randomUUID(); + String jobId = uuid.toString(); + vipsSendMsgResult.jobId = jobId; + vipsSendMsgResult.numRecipients = vm.distributionList.size(); + + vipsSendMsgResult.status = MsgDistResultEnum.FailedNotSent; + + } catch (Exception e) { + vipsSendMsgResult.status = MsgDistResultEnum.FailedNotSentWithException; + + System.out.println("Failed to send message: " + e.getMessage()); + + } finally { + } + + return vipsSendMsgResult; + } + +} diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/DistributionTypeEnum.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/DistributionTypeEnum.java new file mode 100644 index 0000000000000000000000000000000000000000..ca2bed64f59aa073d9ec9e1b670cb80a4203abed --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/DistributionTypeEnum.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ + +package no.nibio.vips.logic.messaging.distribution.entity; + +/** + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +public enum DistributionTypeEnum { + Sms, + Mail + +} diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/MsgDistResultEnum.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/MsgDistResultEnum.java new file mode 100644 index 0000000000000000000000000000000000000000..d6836be1fc313f88337c25d3fc1d2afa8f25336f --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/MsgDistResultEnum.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ +package no.nibio.vips.logic.messaging.distribution.entity; + +/** + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +public enum MsgDistResultEnum { + Ok, + FailedNotSent, + FailedNotSentWithException, + FailedNotSentToOld, + SomeMessagesFailed; + + +} diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/MsgReceiver.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/MsgReceiver.java new file mode 100644 index 0000000000000000000000000000000000000000..74d3da62a5808d0c1c2adb70585fcd2d6da5eafe --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/MsgReceiver.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ +package no.nibio.vips.logic.messaging.distribution.entity; + +/** + * This contains the info needed to send a message + * + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + * + */ +public class MsgReceiver { + + public MsgReceiver() { + } + + + public MsgReceiver(DistributionTypeEnum messageDistributionType, String string) { + type = messageDistributionType; + msgDeliveryAddress = string; + } + + // if this should be sent to sms or mail + public DistributionTypeEnum type; + + // the address for delivery either a mail address or phone number + public String msgDeliveryAddress; + + // the name of the recipient of the message + public String name; + + // a internal id of the recipient + public String recipientId; + + // The user's preffered language for messages + public String preferredLocale; + + // If SMS messages should be free of charge + public Boolean freeSms; + + + +} diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/MsgToSend.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/MsgToSend.java new file mode 100644 index 0000000000000000000000000000000000000000..4c2fe6473320a84390ca3d1646ddc7b47b3ee61c --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/MsgToSend.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ +package no.nibio.vips.logic.messaging.distribution.entity; + +import java.net.URL; + + +/** + * This is class that contains all info when you send message from vips + * + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + * + */ + +// TODO use get and setter +public class MsgToSend { + // The message subject, used when sending a email + public String msgSubject; + + // this message laguag + private String locale; + + // The message to be sent + public String msgBody; + + // The Download URL for the message + public URL msgDownloadUrl; + + // The lead paragraph (AKA "Ingress") + public String msgLeadParagraph; + + /* (non-Javadoc) + * @see no.nibio.vips_msg_dist.dao.Test#getMsgSubject() + */ + public String getMsgSubject() { + return msgSubject; + } + + /** + * @param msgSubject the msgSubject to set + */ + public void setMsgSubject(String msgSubject) { + this.msgSubject = msgSubject; + } + + /* (non-Javadoc) + * @see no.nibio.vips_msg_dist.dao.Test#getMsgBody() + */ + public String getMsgBody() { + return msgBody; + } + + /** + * @param msgBody the msgBody to set + */ + public void setMsgBody(String msgBody) { + this.msgBody = msgBody; + } + + /* (non-Javadoc) + * @see no.nibio.vips_msg_dist.dao.Test#getMsgDownloadUrl() + */ + public URL getMsgDownloadUrl() { + return msgDownloadUrl; + } + + /** + * @param msgDownloadUrl the msgDownloadUrl to set + */ + public void setMsgDownloadUrl(URL msgDownloadUrl) { + this.msgDownloadUrl = msgDownloadUrl; + } + + /* (non-Javadoc) + * @see no.nibio.vips_msg_dist.dao.Test#getMsgLeadParagraph() + */ + public String getMsgLeadParagraph() { + return msgLeadParagraph; + } + + /** + * @param msgLeadParagraph the msgLeadParagraph to set + */ + public void setMsgLeadParagraph(String msgLeadParagraph) { + this.msgLeadParagraph = msgLeadParagraph; + } + + /** + * @return the locale + */ + public String getLocale() { + return locale; + } + + /** + * @param locale the locale to set + */ + public void setLocale(String locale) { + this.locale = locale; + } + + +} diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/VipsMessage.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/VipsMessage.java new file mode 100644 index 0000000000000000000000000000000000000000..1c616617270a02048a63b4a04a7dbfc387b1c588 --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/VipsMessage.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ +package no.nibio.vips.logic.messaging.distribution.entity; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; +import no.nibio.vips.logic.messaging.UniversalMessage; +import no.nibio.vips.logic.messaging.distribution.send.IMsgContent; + + +/** + * This is class that contains all info when you send message from vips + * + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + * + */ + +// TODO use get and setter +public class VipsMessage implements IMsgContent { + + /** + * Create from UniversalMessage + * TODO: Complete integration of entities! + * @param universalMessage + */ + public VipsMessage(UniversalMessage universalMessage) + { + this.expiresAt = universalMessage.getExpiresAt(); + this.distributionList = universalMessage.getDistributionListObjects().stream().map(umRecipient->{ + MsgReceiver msgReceiver = new MsgReceiver(); + msgReceiver.type = umRecipient.getType().toLowerCase().equals("mail") ? DistributionTypeEnum.Mail : DistributionTypeEnum.Sms; + msgReceiver.freeSms = umRecipient.getFreeSms(); + msgReceiver.msgDeliveryAddress = umRecipient.getMsgDeliveryAddress(); + msgReceiver.name = umRecipient.getName(); + msgReceiver.preferredLocale = umRecipient.getPreferredLocale(); + msgReceiver.recipientId = umRecipient.getRecipientId(); + + return msgReceiver; + }).collect(Collectors.toList()); + this.messageLocalVersions = universalMessage.getMessageLocalVersionObjects().stream().map(umLocalV->{ + MsgToSend msgToSend = new MsgToSend(); + msgToSend.msgBody = umLocalV.getMsgBody(); + try + { + msgToSend.msgDownloadUrl = new URL(umLocalV.getMsgDownloadUrl()); + } + catch(MalformedURLException ex) + { + + } + msgToSend.msgLeadParagraph = umLocalV.getMsgLeadParagraph(); + msgToSend.msgBody = umLocalV.getMsgBody(); + msgToSend.msgSubject = umLocalV.getMsgSubject(); + msgToSend.setLocale(umLocalV.getLocale()); + return msgToSend; + }).collect(Collectors.toList()); + + } + + + + // The list of message to be sent + private List<MsgToSend> messageLocalVersions = new ArrayList<MsgToSend>(); + + // The list of message receiver + public List<MsgReceiver> distributionList = new ArrayList<MsgReceiver>(); + + // when the message should expiere, after this time the message should not be sent. + public Date expiresAt; + + /** + * @return the messageLocalVersions + */ + public List<MsgToSend> getMessageLocalVersions() { + return messageLocalVersions; + } + + /** + * @param messageLocalVersions the messageLocalVersions to set + */ + public void setMessageLocalVersions(List<MsgToSend> messageLocalVersions) { + this.messageLocalVersions = messageLocalVersions; + } + + +} diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/VipsSendMsgResult.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/VipsSendMsgResult.java new file mode 100644 index 0000000000000000000000000000000000000000..441f3399af3eab74bd543a744b23b57aadc952ab --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/entity/VipsSendMsgResult.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ +package no.nibio.vips.logic.messaging.distribution.entity; + +/** + * + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +public class VipsSendMsgResult { + + public MsgDistResultEnum status; + public String jobId; + public int numRecipients; + +} diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/send/CSVTrafficFileLogger.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/send/CSVTrafficFileLogger.java new file mode 100644 index 0000000000000000000000000000000000000000..2ee3dd2a7755ed31d7317dc522e538bcf95f3129 --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/send/CSVTrafficFileLogger.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ + +package no.nibio.vips.logic.messaging.distribution.send; + +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import no.nibio.vips.logic.messaging.distribution.entity.MsgReceiver; + +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVPrinter; + +/** + * Writes sent/received logs to chosen unix directory (e.g. /var/log/trafficLog) + * Property config is System.getProperty("no.nibio.vips.logic.messaging.dist.TRAFFIC_LOG_DIRECTORY"); + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + */ +public class CSVTrafficFileLogger { + + // Delimiter used in CSV file + private static final String NEW_LINE_SEPARATOR = "\n"; + + // received + public static void writeCsvFilerReceived(String fileName, List<MsgReceiver> msgList) { + + // CSV file header + // msgDeliveryAddress; + // recipientId; + // msgDeliverySent + Object[] FILE_HEADER_RECEIVED = {"recipientId", "msgType", "msgDeliveryAddress"}; + + FileWriter fileWriter = null; + + CSVPrinter csvFilePrinter = null; + + // Create the CSVFormat object with "\n" as a record delimiter + CSVFormat csvFileFormat = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR); + + try { + + // initialize FileWriter object + fileWriter = new FileWriter(fileName); + + // initialize CSVPrinter object + csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat); + + // Create CSV file header + csvFilePrinter.printRecord(FILE_HEADER_RECEIVED); + + // Write a new student object list to the CSV file + for (MsgReceiver mr : msgList) { + List msgReceiverDataRecord = new ArrayList(); + msgReceiverDataRecord.add(mr.recipientId); + msgReceiverDataRecord.add(mr.type); + msgReceiverDataRecord.add(mr.msgDeliveryAddress); + csvFilePrinter.printRecord(msgReceiverDataRecord); + } + + } catch (Exception e) { + System.out.println("Failed to write result to file " + fileName + ": " + e); + } finally { + try { + fileWriter.flush(); + fileWriter.close(); + csvFilePrinter.close(); + } catch (IOException e) { + System.out.println("Failed to write result to file " + fileName + ": " + e); + } + } + + } + + public static void writeCsvFilerReceived(String fileNameSentResult, ArrayList<SingleMsgSendResult> msgSentResult) { + // CSV file header + // msgDeliveryAddress; + // recipientId; + // msgDeliverySent + + Object[] FILE_HEADER_RECEIVED = {"recipientId", "msgType", "msgDeliveryAddress", "time", "result"}; + + FileWriter fileWriter = null; + + CSVPrinter csvFilePrinter = null; + + // Create the CSVFormat object with "\n" as a record delimiter + CSVFormat csvFileFormat = CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR); + + try { + + // initialize FileWriter object + fileWriter = new FileWriter(fileNameSentResult); + + // initialize CSVPrinter object + csvFilePrinter = new CSVPrinter(fileWriter, csvFileFormat); + + // Create CSV file header + csvFilePrinter.printRecord(FILE_HEADER_RECEIVED); + + // Write a new student object list to the CSV file + for (SingleMsgSendResult mr : msgSentResult) { + List msgReceiverDataRecord = new ArrayList(); + msgReceiverDataRecord.add(mr.msgReceivier.recipientId); + msgReceiverDataRecord.add(mr.msgReceivier.type); + msgReceiverDataRecord.add(mr.msgReceivier.msgDeliveryAddress); + msgReceiverDataRecord.add(mr.delievery); + msgReceiverDataRecord.add(mr.res); + + csvFilePrinter.printRecord(msgReceiverDataRecord); + } + + } catch (Exception e) { + System.out.println("Failed to write result to file " + fileNameSentResult + ": " + e); + } finally { + try { + fileWriter.flush(); + fileWriter.close(); + csvFilePrinter.close(); + } catch (IOException e) { + System.out.println("Failed to write result to file " + fileNameSentResult + ": " + e); + } + } + + } +} diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/send/IDeliveryMsgHandler.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/send/IDeliveryMsgHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..a5be9e6b60c9c7bd30022b5d7f6f6ba2bc349b66 --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/send/IDeliveryMsgHandler.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ +package no.nibio.vips.logic.messaging.distribution.send; + +import no.nibio.vips.logic.messaging.distribution.entity.DistributionTypeEnum; +import no.nibio.vips.logic.messaging.distribution.entity.MsgReceiver; +import no.nibio.vips.logic.messaging.distribution.entity.MsgToSend; +import no.nibio.vips.logic.messaging.distribution.entity.VipsMessage; + + + +/** + * This is the interface implemented by the different distribution channels like sm, mail..... + * + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + * + */ +public interface IDeliveryMsgHandler { + + + + /** + * Returns what kind distribution this handler accepts + * + * @return + */ + public DistributionTypeEnum getDistributionType(); + + + /** + * Send given message to given user and update the logfile + * + * @param vm the message content + * @param msgReceiver the reciver of the message + * @return + */ + public SingleMsgSentStateEnum sendMessage(VipsMessage vm, MsgReceiver msgReceiver, MsgToSend msgToSend); +} diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/send/IMsgContent.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/send/IMsgContent.java new file mode 100644 index 0000000000000000000000000000000000000000..c2c2b0e9c7d08c91ca04803aa5865986e3c78b46 --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/send/IMsgContent.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ +package no.nibio.vips.logic.messaging.distribution.send; + +import java.util.List; +import no.nibio.vips.logic.messaging.distribution.entity.MsgToSend; + + + +/** + * This the content of a message that will be common for handlers, but not all handler may use all fileds. + * + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + * + */ + +public interface IMsgContent { + + List<MsgToSend> getMessageLocalVersions(); +// +// +// /** +// * @return the msgSubject +// */ +// String getMsgSubject(); +// +// /** +// * @return the msgBody +// */ +// String getMsgBody(); +// +// /** +// * @return the msgDownloadUrl +// */ +// URL getMsgDownloadUrl(); +// +// /** +// * @return the msgLeadParagraph +// */ +// String getMsgLeadParagraph(); +// +// +// /** +// * @return the locale +// */ +// String getLocale(); + +} diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/send/MailMsgDeliveryHandler.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/send/MailMsgDeliveryHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..cb57ba7b9c9c920afcfc1be9d6e58586bd846b42 --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/send/MailMsgDeliveryHandler.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ +package no.nibio.vips.logic.messaging.distribution.send; + +import java.io.UnsupportedEncodingException; +import java.util.Date; +import java.util.Properties; + +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Session; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeUtility; + +import com.sun.mail.smtp.SMTPTransport; +import no.nibio.vips.logic.messaging.distribution.entity.DistributionTypeEnum; +import no.nibio.vips.logic.messaging.distribution.entity.MsgReceiver; +import no.nibio.vips.logic.messaging.distribution.entity.MsgToSend; +import no.nibio.vips.logic.messaging.distribution.entity.VipsMessage; + + +/** + * Handles sending off mail messages by SMPTP + * + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + * + */ +public class MailMsgDeliveryHandler implements IDeliveryMsgHandler { + + private final String mailserver; + private final String sender; + + // if this no mail will be sent, but the return result is true + private final boolean testOnly; + + public MailMsgDeliveryHandler(String mailserver, String sender, boolean testOnly) { + this.mailserver = mailserver; + this.sender = sender; + this.testOnly = testOnly; + } + + private boolean sendMessage(String subjekt, String leadParagraph, StringBuffer mailText, String mailaddress) + throws MessagingException, UnsupportedEncodingException { + boolean result = false; + + SMTPTransport t = null; + String message = "Failed to send message to " + mailaddress + " using server " + mailserver; + try { + + Properties props = System.getProperties(); + if (props == null) { + System.out.println( this.getClass().getName() + " ERRROR: no mail sent System.getProperties() is null"); + return result; + } + props.put("mail.smtp.host", mailserver); + //props.put("mail.smtp.port", "587"); + props.put("mail.smtp.auth", "false"); + + props.put("mail.mime.charset", "UTF-8"); + props.put("user.language", "no_NO"); + props.put("sun.jnu.encoding", "UTF-8"); + props.put("file.encoding", "UTF-8"); + + // Get a Session object + Session session = Session.getInstance(props, null); + session.setDebug(true); + + // construct the message + MimeMessage msg = new MimeMessage(session); + /*if (logger.isDebugEnabled()) { + logger.debug("Done create SMPTMessage"); + }*/ + + msg.addHeader("charset", "UTF-8"); + + msg.setFrom(new InternetAddress(sender)); + msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(mailaddress, false)); + String encodeSubjektText = MimeUtility.encodeText(subjekt); + msg.setSubject(encodeSubjektText); + + msg.setHeader("X-Mailer", "smtpsend"); + String mailMessageBody = leadParagraph; + + if (leadParagraph != null && leadParagraph.length() > 0) { + mailMessageBody = leadParagraph + " \r\n" + mailText.toString(); + } else { + mailMessageBody = mailText.toString(); + + } + + msg.setText(mailMessageBody, "UTF-8"); + + msg.setSentDate(new Date()); + boolean ssl = false; + + /* + if (logger.isDebugEnabled()) { + logger.debug("Message reday to send : " + mailMessageBody); + } + */ + + t = (SMTPTransport) session.getTransport(ssl ? "smtps" : "smtp"); + t.connect(); + t.sendMessage(msg, msg.getAllRecipients()); + + /* + if (logger.isDebugEnabled()) { + logger.debug("Mail was sent successfully. Response: " + t.getLastServerResponse()); + }*/ + + } finally { + try { + if (t != null) { + t.close(); + } + } catch (MessagingException e) { + // TODO Auto-generated catch block + System.out.println("Failed to close " + mailaddress + " using server " + mailserver); + } + } + return result; + + } + + /** + * Send a mail message + * + * {@link IDeliveryMsgHandler#sendMessage(IMsgContent, SingleMsgSendResult)} + */ + @Override + public SingleMsgSentStateEnum sendMessage(VipsMessage vm, MsgReceiver msgReceiver, MsgToSend msgToSend) { + try { + if (this.testOnly) { + System.out.println("Test only is true so this message is not sent " + msgToSend.getMsgBody() + " to " + msgReceiver.msgDeliveryAddress + + " using server " + mailserver); + } else { + sendMessage(msgToSend.getMsgSubject(), msgToSend.getMsgLeadParagraph(), new StringBuffer(msgToSend.getMsgBody()).append("\n\n") + .append(msgToSend.getMsgDownloadUrl() != null ? msgToSend.getMsgDownloadUrl():""), + msgReceiver.msgDeliveryAddress); + } + return SingleMsgSentStateEnum.Ok; + } catch (UnsupportedEncodingException | MessagingException e) { + System.out.println("Failed to send message " + msgToSend.getMsgBody() + " to " + msgReceiver.msgDeliveryAddress + " using server " + mailserver); + return SingleMsgSentStateEnum.FailedNotSentWithException; + } + + } + + /** + * Get content type for this handler + * + * {@link IDeliveryMsgHandler#sendMessage(IMsgContent, SingleMsgSendResult)} + */ + @Override + public DistributionTypeEnum getDistributionType() { + return DistributionTypeEnum.Mail; + } + +} diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/send/SingleMsgSendResult.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/send/SingleMsgSendResult.java new file mode 100644 index 0000000000000000000000000000000000000000..55b7a822441877dd30919d7627f3929fe477bbde --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/send/SingleMsgSendResult.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ +package no.nibio.vips.logic.messaging.distribution.send; + +import java.util.Date; +import no.nibio.vips.logic.messaging.distribution.entity.MsgReceiver; + + +/** + * This contains the info needed to send a message + * + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + * + */ +public class SingleMsgSendResult { + + + // infor baout the message + public MsgReceiver msgReceivier; + + // the message send result + public SingleMsgSentStateEnum res; + + // when the message was delivered + public Date delievery; + + public SingleMsgSendResult(MsgReceiver msgReceivier, SingleMsgSentStateEnum res ) { + this.msgReceivier = msgReceivier; + this.res = res; + delievery = new Date(); + } + + +} diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/send/SingleMsgSentStateEnum.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/send/SingleMsgSentStateEnum.java new file mode 100644 index 0000000000000000000000000000000000000000..af12201ac5f5f99eddc6e8203e723cfdb744b73c --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/send/SingleMsgSentStateEnum.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ +package no.nibio.vips.logic.messaging.distribution.send; +/** + * Used to keep track each single message delivery state + * + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + * + */ +public enum SingleMsgSentStateEnum { + Ok, // the message is sent + FailedNotSentWithException, // got exception when sending + FailedNotSentToOld, // the message was to old + FailedNotSentNoDistType; // tried to send to invanlid medium + +} diff --git a/src/main/java/no/nibio/vips/logic/messaging/distribution/send/SmsMsgDeliveryHandler.java b/src/main/java/no/nibio/vips/logic/messaging/distribution/send/SmsMsgDeliveryHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..4d9bb0847d82d0f8a78f61f60b827edd640fe597 --- /dev/null +++ b/src/main/java/no/nibio/vips/logic/messaging/distribution/send/SmsMsgDeliveryHandler.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2022 NIBIO <http://www.nibio.no/>. + * + * This file is part of VIPSLogic. + * VIPSLogic is free software: you can redistribute it and/or modify + * it under the terms of the NIBIO Open Source License as published by + * NIBIO, either version 1 of the License, or (at your option) any + * later version. + * + * VIPSLogic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * NIBIO Open Source License for more details. + * + * You should have received a copy of the NIBIO Open Source License + * along with VIPSLogic. If not, see <http://www.nibio.no/licenses/>. + * + */ +package no.nibio.vips.logic.messaging.distribution.send; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; + +import javax.mail.MessagingException; +import no.nibio.vips.logic.messaging.distribution.entity.MsgReceiver; +import no.nibio.vips.logic.messaging.distribution.entity.MsgToSend; +import no.nibio.vips.logic.messaging.distribution.entity.VipsMessage; +import no.nibio.vips.logic.messaging.distribution.entity.DistributionTypeEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Handles sending off sms messages + * + * @author Lars Aksel Opsahl <lars.opsahl@nibio.no> + * @author Tor-Einar Skog <tor-einar.skog@nibio.no> + * + */ +public class SmsMsgDeliveryHandler implements IDeliveryMsgHandler { + + private final static Logger LOGGER = LoggerFactory.getLogger(SmsMsgDeliveryHandler.class); + + // properties needed by the smsc connection handler + private final String smscServer; + private final String smscUsername; + private final String smscPassword; + private final String smscSenderSrc; + + // if this no mail will be sent, but the return result is true + private final boolean testOnly; + + public SmsMsgDeliveryHandler(String smscServer, String smscUsername, String smscPassword, String smscSenderSrc, boolean testOnly) { + this.smscServer = smscServer; + this.smscUsername = smscUsername; + this.smscPassword = smscPassword; + this.smscSenderSrc = smscSenderSrc; + this.testOnly = testOnly; + } + + /** + * This is used to check to Authorization + * + * @param userToken + * @return + * @throws MalformedURLException + * @throws IOException + */ + private boolean sendMessage(String subjekt, String smsText, String smsAddress, String pricegroup) throws MessagingException, MalformedURLException, IOException { + boolean result = false; + InputStream response = null; + URLConnection connection = null; + try { + LOGGER.debug("Message ready to send : " + smsText); + + // http://smsc.vianett.no/v3/send.ashx?src=xxxxx&dst=xxxxx&msg=Hello+world&username=xxxxx&password=xxxxx&pricegroup=xx + String charset = "UTF-8"; // Or in Java 7 and later, use the constant: java.nio.charset.StandardCharsets.UTF_8.name() + String query = String.format("src=%s", URLEncoder.encode(smscSenderSrc, charset)) + "&" + + String.format("dst=%s", URLEncoder.encode(smsAddress, charset)) + "&" + String.format("msg=%s", URLEncoder.encode(smsText, charset)) + "&" + + String.format("username=%s", URLEncoder.encode(smscUsername, charset)) + "&" + + String.format("password=%s", URLEncoder.encode(smscPassword, charset)) + "&" + + String.format("pricegroup=%s", URLEncoder.encode(pricegroup, charset)); + + String sendUrl = "https://" + smscServer + "/v3/send.ashx"; + + connection = new URL(sendUrl + "?" + query).openConnection(); + connection.setRequestProperty("Accept-Charset", charset); + response = connection.getInputStream(); + + BufferedReader br = new BufferedReader(new InputStreamReader(response)); + // Works with java 1.8 only + // String collect = br.lines().collect(Collectors.joining(System.lineSeparator())); + + // Works with java 1.7 + StringBuilder collectBuffer = new StringBuilder(); + int value = 0; + while ((value = br.read()) != -1) { + // converts int to character + char c = (char) value; + collectBuffer.append(c); + } + + String collect = collectBuffer.toString(); + + if ("200|OK".equals(collect)) { + result = true; + } else { + LOGGER.error("Result was invalid, got '" + collect + "' from " + sendUrl + " to " + smsAddress); + } + + LOGGER.debug("Result was " + result + " from " + sendUrl + " to " + smsAddress); + + } finally { + if (response != null) { + response.close(); + } + } + return result; + + } + + /** + * Send a mail message + * + * {@link IDeliveryMsgHandler#sendMessage(IMsgContent, SingleMsgSendResult)} + */ + @Override + public SingleMsgSentStateEnum sendMessage(VipsMessage vm, MsgReceiver msgReceiver, MsgToSend msgToSend) { + String smsText = msgToSend.getMsgSubject() + "\n" + + msgToSend.getMsgLeadParagraph() + "\n" + + msgToSend.getMsgBody() + + (msgToSend.getMsgDownloadUrl() != null ? "\n" + msgToSend.getMsgDownloadUrl().toString(): ""); + LOGGER.debug(smsText); + LOGGER.debug("Teksten er på " + smsText.length() + " tegn."); + + try { + // TODO: Make the price part of VipsMessage + String pricegroup = msgReceiver.freeSms ? "00" : "100"; +/* + if (smsText.length() > 179) { + smsText = msgToSend.getMsgSubject() + "\n" + + msgToSend.getMsgLeadParagraph() + "\n" + + "Les mer: " + msgToSend.getMsgDownloadUrl(); + } + + if (smsText.length() > 179) { + smsText = msgToSend.getMsgSubject() + "\n" + + "Les mer: " + msgToSend.getMsgDownloadUrl().toString(); + } + + if (smsText.length() > 179) { + smsText = msgToSend.getMsgSubject() + "\n" + + "Les mer: " + msgToSend.getMsgDownloadUrl().toString(); + } + + if (smsText.length() > 179) { + smsText = "Les melding fra Vips:" + msgToSend.getMsgDownloadUrl().toString(); + } +*/ + if (testOnly) { + + LOGGER.info("Test only is true so this message is not sent " + smsText + " to " + msgReceiver.msgDeliveryAddress + " using server " + smscServer); + + } else { + + sendMessage(msgToSend.getMsgSubject(), smsText, msgReceiver.msgDeliveryAddress, pricegroup); + } + return SingleMsgSentStateEnum.Ok; + } catch (MessagingException | IOException e) { + LOGGER.error("Failed to send message " + smsText + " to " + msgReceiver.msgDeliveryAddress + " using server " + smscServer,e); + return SingleMsgSentStateEnum.FailedNotSentWithException; + } catch (Throwable e1) { + LOGGER.error("Failed to send message " + smsText + " to " + msgReceiver.msgDeliveryAddress + " using server " + smscServer,e1); + return SingleMsgSentStateEnum.FailedNotSentWithException; + + } + } + + /** + * Get content type for this handler + * + * {@link IDeliveryMsgHandler#sendMessage(IMsgContent, SingleMsgSendResult)} + */ + @Override + public DistributionTypeEnum getDistributionType() { + return DistributionTypeEnum.Sms; + } + +} diff --git a/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleBean.java b/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleBean.java index 05f595ffa8ea19269fd2c41fd72f39907691bd49..5807d5cbe5a920f7d117759eed7a4b0ed762aa0d 100644 --- a/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleBean.java +++ b/src/main/java/no/nibio/vips/logic/modules/barkbeetle/BarkbeetleBean.java @@ -70,6 +70,8 @@ import no.nibio.vips.logic.messaging.UniversalMessageFormat; import no.nibio.vips.logic.util.GISEntityUtil; import no.nibio.vips.logic.util.Globals; import no.nibio.vips.logic.util.SimpleMailSender; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @copyright 2022 <a href="http://www.nibio.no/">NIBIO</a> @@ -78,6 +80,9 @@ import no.nibio.vips.logic.util.SimpleMailSender; @LocalBean @Stateless public class BarkbeetleBean { + + private static Logger LOGGER = LoggerFactory.getLogger(BarkbeetleBean.class); + @PersistenceContext(unitName="VIPSLogic-PU") EntityManager em; @@ -769,6 +774,15 @@ public class BarkbeetleBean { public void checkAndSendTrapEmptyingReminder(Date currentDate) { + + VipsLogicUser testRecipient = new VipsLogicUser(); + testRecipient.setUserId(1); + testRecipient.setEmail("tor-einar.skog@nibio.no"); + testRecipient.setPhone("91303819"); + testRecipient.setApprovesSmsBilling(false); + testRecipient.setFreeSms(true); + testRecipient.setPreferredLocale("nb"); + // Is it time to send the first reminder? if(this.isTimeToSendFirstReminder(currentDate)) { @@ -778,42 +792,38 @@ public class BarkbeetleBean { Calendar cal = Calendar.getInstance(BarkbeetleBean.NORGE_MITT_NORGE); cal.setTime(currentDate); + + + String heading = "Barkbilleregistrering: Første påminnelse for uke " + (cal.get(Calendar.WEEK_OF_YEAR) + 1); + // Get all trapsites for this season List<SeasonTrapsite> allSeasonTrapsites = this.getSeasonTrapsites(cal.get(Calendar.YEAR)); for(SeasonTrapsite st:allSeasonTrapsites) { - String heading = "Barkbilleregistrering: Første påminnelse for uke " + (cal.get(Calendar.WEEK_OF_YEAR) + 1); + String message = this.getIndividualFirstReminderText(st, cal.get(Calendar.YEAR), cal.get(Calendar.WEEK_OF_YEAR) + 1); //VipsLogicUser recipient = st.getUserId(); // TESTING - VipsLogicUser recipient = new VipsLogicUser(); - recipient.setEmail("tor-einar.skog@nibio.no"); - recipient.setPhone("91303819"); - this.sendReminder(List.of(recipient), heading, message); - /*String recipientMail = "tor-einar.skog@nibio.no"; - //String recipientMail = st.getUserId().getEmail(); - String registrantPhone = "+4791303819"; - System.out.println("Phone number would have been " + st.getUserId().getPhoneCountryCode() + st.getUserId().getPhone()); - //String registrantPhone = st.getUserId().getPhoneCountryCode() + st.getUserId().getPhone(); - System.out.println("Email would have been " + st.getUserId().getEmail()); - // Alternative 1: Send email - mailSender.sendMail("noreply-vips@nibio.no", recipientMail, "Barkbilleregistrering: Første påminnelse for uke " + (cal.get(Calendar.WEEK_OF_YEAR) + 1), message); - - // Alternative 2: Send SMS - */ + + this.sendReminder(List.of(testRecipient), heading, message); + break; } // We also send a reminder to the county contacts Organization NIBIO = this.userBean.getOrganization(1); // !!! This is hard coded!!! List<VipsLogicUser> countyContacts = this.userBean.findOrganizationUsersByRole(NIBIO, VipsLogicRole.BARKBEETLE_COUNTY_ADMIN); - String recipientList = countyContacts.stream().map(cc->cc.getEmail()).collect((Collectors.joining(","))); - System.out.println("RecipientList would have been: " + recipientList); + + LOGGER.debug("RecipientList would have been: " + (countyContacts.stream().map(cc->cc.getEmail()).collect((Collectors.joining(","))))); + String message = this.getCountyContactReminderText(cal.get(Calendar.YEAR), cal.get(Calendar.WEEK_OF_YEAR) + 1); + this.sendReminder(List.of(testRecipient), heading, message); // TODO Replace List.of(testRecipient) with countyContacts + + // TESTING - recipientList = "tor-einar.skog@nibio.no"; + /*recipientList = "tor-einar.skog@nibio.no"; String message = this.getCountyContactReminderText(cal.get(Calendar.YEAR), cal.get(Calendar.WEEK_OF_YEAR) + 1); - mailSender.sendMail("noreply-vips@nibio.no", recipientList, "Barkbilleregistrering: Første påminnelse for uke " + cal.get(Calendar.WEEK_OF_YEAR), message); + mailSender.sendMail("noreply-vips@nibio.no", recipientList, "Barkbilleregistrering: Første påminnelse for uke " + (cal.get(Calendar.WEEK_OF_YEAR) + 1), message);*/ } // Is it time to send the second reminder? else if(this.isTimeToSendSecondReminder(currentDate)) @@ -825,11 +835,16 @@ public class BarkbeetleBean { //System.out.println("We think that " + currentDate + " is in week " + cal.get(Calendar.WEEK_OF_YEAR)); Integer season = cal.get(Calendar.YEAR); Integer week = cal.get(Calendar.WEEK_OF_YEAR); + String heading = "Barkbilleregistrering: Andre påminnelse for uke " + cal.get(Calendar.WEEK_OF_YEAR); // Get all trapsites behind on registering List<SeasonTrapsite> sitesBehindOnData = this.getSeasonTrapsitesBehindOnData(currentDate); for(SeasonTrapsite st:sitesBehindOnData) { String message = this.getIndividualSecondReminderText(st, season, week); + + this.sendReminder(List.of(testRecipient), heading, message); + + /* String recipientMail = "tor-einar.skog@nibio.no"; //String recipientMail = st.getUserId().getEmail(); String registrantPhone = "+4791303819"; @@ -837,10 +852,10 @@ public class BarkbeetleBean { //String registrantPhone = st.getUserId().getPhoneCountryCode() + st.getUserId().getPhone(); System.out.println("Email would have been " + st.getUserId().getEmail()); // Alternative 1: Send email - mailSender.sendMail("noreply-vips@nibio.no", recipientMail, "Barkbilleregistrering: Andre påminnelse for uke " + cal.get(Calendar.WEEK_OF_YEAR), message); + mailSender.sendMail("noreply-vips@nibio.no", recipientMail, , message); // Alternative 2: Send SMS - + */ break; } } @@ -852,9 +867,9 @@ public class BarkbeetleBean { } - final String firstRegistrantReminderTpl = "Barkbilleregistrering: Tømmeuke %s er forestående. For din fellelokalitet " + final String firstRegistrantReminderTpl = "For din fellelokalitet " + "i %s fylke, %s kommune, skal tømming og registrering utføres mandag %s eller tirsdag %s " - + "neste uke. Frist for innlegging av data er onsdag %s. For ytterligere instruksjoner, les mer her: %s."; + + "neste uke. Frist for innlegging av data er onsdag %s. For ytterligere instruksjoner, les mer her: %s"; @@ -863,16 +878,16 @@ public class BarkbeetleBean { { Map<Integer, Date> weekdaysInWeek = this.getWeekdaysInWeek(season, week); SimpleDateFormat format = new SimpleDateFormat("d. MMM", BarkbeetleBean.NORGE_MITT_NORGE); - return String.format(firstRegistrantReminderTpl, week, seasonTrapsite.getCountyName(), seasonTrapsite.getMunicipalityName(), + return String.format(firstRegistrantReminderTpl, seasonTrapsite.getCountyName(), seasonTrapsite.getMunicipalityName(), format.format(weekdaysInWeek.get(Calendar.MONDAY)), format.format(weekdaysInWeek.get(Calendar.TUESDAY)), format.format(weekdaysInWeek.get(Calendar.WEDNESDAY)), String.format("https://logic.vips.nibio.no/images/modules/barkbeetle/%s", BarkbeetleController.FILENAME_INSTRUKS_REGISTRANTER) ); } - final String secondReminderTpl = "Barkbilleregistrering: Vi er inne i tømmeuke %s. For din fellelokalitet " + final String secondReminderTpl = "Vi er inne i tømmeuke %s. For din fellelokalitet " + "i %s fylke, %s kommune, skulle tømming og registrering vært utført mandag %s eller tirsdag %s " + "denne uke. Frist for innlegging av data var onsdag %s. Vennligst ferdigstill tømming og registrering " - + "så raskt som overhodet mulig. For ytterligere instruksjoner, les mer her: %s."; + + "så raskt som overhodet mulig. For ytterligere instruksjoner, les mer her: %s"; public String getIndividualSecondReminderText(SeasonTrapsite seasonTrapsite, Integer season, Integer week) { @@ -884,7 +899,7 @@ public class BarkbeetleBean { ); } - final String countyContactReminderTpl = "Barkbilleregistrering: Tømmeuke %s er forestående. Tømming og registrering utføres " + final String countyContactReminderTpl = "Tømming og registrering utføres " + "mandag %s eller tirsdag %s neste uke. Frist for innlegging av data er onsdag %s. " + "Sjekk her for å se hvem som (ikke) har lagt inn data i portalen: %s"; @@ -892,7 +907,7 @@ public class BarkbeetleBean { { Map<Integer, Date> weekdaysInWeek = this.getWeekdaysInWeek(season, week); SimpleDateFormat format = new SimpleDateFormat("d. MMM", BarkbeetleBean.NORGE_MITT_NORGE); - return String.format(countyContactReminderTpl, week, + return String.format(countyContactReminderTpl, format.format(weekdaysInWeek.get(Calendar.MONDAY)), format.format(weekdaysInWeek.get(Calendar.TUESDAY)), format.format(weekdaysInWeek.get(Calendar.WEDNESDAY)), String.format("https://logic.vips.nibio.no/barkbeetle?action=listSeasonTrapsitesStatus&season=%s", season) ); @@ -920,21 +935,23 @@ public class BarkbeetleBean { /** * Using the VIPS messaging system - * @param recipients + * @param users * @param heading - * @param body + * @param message + * @param url */ - public void sendReminder(List<VipsLogicUser> users, String heading, String body) { + public void sendReminder(List<VipsLogicUser> users, String heading, String message) { + UniversalMessage uMessage = new UniversalMessage(); Calendar cal = Calendar.getInstance(BarkbeetleBean.NORGE_MITT_NORGE); cal.setTime(new Date()); cal.add(Calendar.DATE, 2); uMessage.setExpiresAt(cal.getTime()); - uMessage.addMessageLocalVersion("nb", heading, "", body, ""); + uMessage.addMessageLocalVersion("nb", heading, message, "",null); List<MessageRecipient> recipients = users.stream().map(user->{ MessageRecipient recipient = new MessageRecipient(); UniversalMessageFormat umf = messagingBean.getUniversalMessageFormat( - user.isApprovesSmsBilling() && !user.getPhone().trim().isBlank() ? + (user.isApprovesSmsBilling() || user.isFreeSms()) && !user.getPhone().trim().isBlank() ? UniversalMessageFormat.FORMAT_SMS : UniversalMessageFormat.FORMAT_EMAIL ); @@ -945,6 +962,7 @@ public class BarkbeetleBean { : user.getEmail() ); recipient.setFreeSms(user.isFreeSms()); + recipient.setPreferredLocale(user.getPreferredLocale()); return recipient; }) .collect(Collectors.toList());