diff --git a/build.xml b/build.xml index fcb3bb07ab..94e7b7e7b2 100644 --- a/build.xml +++ b/build.xml @@ -92,8 +92,6 @@ - - @@ -237,8 +235,6 @@ - - diff --git a/docs/action_plans.md b/docs/action_plans.md index 21f2bb84e0..6eaf816265 100644 --- a/docs/action_plans.md +++ b/docs/action_plans.md @@ -231,8 +231,8 @@ be `NULL` for "any": On the **Plan** tab of the client interface, users can manually change the phase of an action plan. If the user is in the list specified by the -`action_plan_alert_list` [system attribute], an email will be sent to the -address specified by the `email_recipient_action_plan` [system attribute]. +`action_plan_alert_list` [system attribute], an email event will be logged +to the `email_event` table. ## Events diff --git a/docs/gate_arms.md b/docs/gate_arms.md index 6d09dd3aff..08237be957 100644 --- a/docs/gate_arms.md +++ b/docs/gate_arms.md @@ -113,8 +113,7 @@ interlock_. Once they are both open, the prerequisite will have a _close interlock_ until the dependent is closed. If a constraint is broken, IRIS will not automatically try to resolve it. -Instead, an _alert_ email will be sent to the address in the -`email_recipient_gate_arm` [system attribute]. +Instead, an _alert_ will logged in the `email_event` table. ## Security diff --git a/docs/system_attributes.md b/docs/system_attributes.md index 543667c7bf..c2c39052c9 100644 --- a/docs/system_attributes.md +++ b/docs/system_attributes.md @@ -50,11 +50,7 @@ System Attribute | Description `dms_pixel_test_timeout_secs` | Time to wait for [DMS] pixel test to complete `dms_send_confirmation_enable` | Enable a confirmation dialog box when the [DMS] Send button is pressed `dms_update_font_table` | Enable the updating of the [DMS] controller font table to match the font table in IRIS -`dmsxml_reinit_detect` | Enable [DMS] reinitialization detection for DMSXML controllers `email_rate_limit_hours` | Hours to wait before sending duplicate emails -`email_recipient_action_plan` | Recipient of [action plan] emails -`email_recipient_dmsxml_reinit` | Recipient of [DMS] reinit detection emails -`email_recipient_gate_arm` | Recipient of gate arm alert emails `email_sender_server` | Sender email address of IRIS server `email_smtp_host` | SMTP host for sending email `gate_arm_alert_timeout_secs` | Time to wait before sending gate arm alerts after comm failure diff --git a/etc/i18n/messages_en.properties b/etc/i18n/messages_en.properties index 75a4924664..ba0696eb9a 100644 --- a/etc/i18n/messages_en.properties +++ b/etc/i18n/messages_en.properties @@ -1404,11 +1404,7 @@ dms_pixel_on_limit=Number of adjacent stuck-on pixels allowed in a DMS message o dms_pixel_test_timeout_secs=Time to wait for DMS pixel test to complete. dms_send_confirmation_enable=Enable a confirmation dialog box when the DMS Send button is pressed. dms_update_font_table=Enable the updating of the DMS controller font table to match the font table in IRIS. -dmsxml_reinit_detect=Enable DMS reinitialization detection for DMSXML controllers. email_rate_limit_hours=Hours to wait before sending duplicate emails. -email_recipient_action_plan=Recipient of Action Plan emails. -email_recipient_dmsxml_reinit=Recipient of DMS reinit detection emails. -email_recipient_gate_arm=Recipient of gate arm alert emails. email_sender_server=Sender email address of IRIS server. email_smtp_host=SMTP host for sending email. gate_arm_alert_timeout_secs=Time to wait before sending gate arm alerts after comm failure. diff --git a/etc/i18n/messages_en_US_CA.properties b/etc/i18n/messages_en_US_CA.properties index 49fad5488d..520c5eca7a 100644 --- a/etc/i18n/messages_en_US_CA.properties +++ b/etc/i18n/messages_en_US_CA.properties @@ -67,6 +67,4 @@ dms_pixel_off_limit=Number of stuck-off pixels allowed in a CMS message or -1 to dms_pixel_on_limit=Number of adjacent stuck-on pixels allowed in a CMS message or -1 to ignore. dms_pixel_test_timeout_secs=Time to wait for CMS pixel test to complete. dms_send_confirmation_enable=Enable a confirmation dialog box when the CMS Send button is pressed. -dmsxml_reinit_detect=Enable CMS reinitialization detection for DMSXML controllers. -email_recipient_dmsxml_reinit=Recipient of CMS reinit detection emails. msg_feed_verify=Require CMS messages from msg_feed to exist in message library. diff --git a/etc/iris.spec b/etc/iris.spec index a81af072b3..3d7dd396db 100644 --- a/etc/iris.spec +++ b/etc/iris.spec @@ -112,8 +112,6 @@ ln -sf /usr/lib/jvm/jre-openjdk/lib/amd64/jli/libjli.so /usr/lib64 %dir %{_serverdir} %{_serverdir}/iris-server-%{version}.jar %{_serverdir}/iris-common-%{version}.jar -%{_serverdir}/javax.activation.jar -%{_serverdir}/mail.jar %{_serverdir}/json-@@JSON.VERSION@@.jar %{_serverdir}/postgis-jdbc-@@POSTGIS.VERSION@@.jar %{_serverdir}/postgis-geometry-@@POSTGIS.VERSION@@.jar diff --git a/lib/README.md b/lib/README.md index b84f8673b6..0b3f046038 100644 --- a/lib/README.md +++ b/lib/README.md @@ -1,3 +1,2 @@ -mail.jar is GPL licensed from Oracle. jna is LGPL / Apache-2.0 licensed gst1-java-core is LPGL licensed diff --git a/lib/javax.activation.jar b/lib/javax.activation.jar deleted file mode 100644 index 9637479ad2..0000000000 Binary files a/lib/javax.activation.jar and /dev/null differ diff --git a/lib/mail.jar b/lib/mail.jar deleted file mode 100644 index ab4d021256..0000000000 Binary files a/lib/mail.jar and /dev/null differ diff --git a/sql/migrate-5.64.sql b/sql/migrate-5.64.sql index 03b1089ea1..ac3e455f60 100644 --- a/sql/migrate-5.64.sql +++ b/sql/migrate-5.64.sql @@ -81,10 +81,37 @@ CREATE TRIGGER toll_zone_table_notify_trig -- Delete obsolete system attributes DELETE FROM iris.system_attribute WHERE name IN ( 'camera_wiper_precip_mm_hr', - 'email_recipient_aws' + 'dmsxml_reinit_detect', + 'email_recipient_action_plan', + 'email_recipient_aws', + 'email_recipient_dmsxml_reinit', + 'email_recipient_gate_arm' ); -- Reset all controller status to blank UPDATE iris.controller SET status = NULL; +-- Add email events +INSERT INTO iris.event_config (name, enable_store, enable_purge, purge_days) +VALUES ('email_event', true, true, 30); + +INSERT INTO event.event_description (event_desc_id, description) +VALUES + (308, 'Gate Arm SYSTEM'), + (903, 'Action Plan SYSTEM'); + +CREATE TABLE event.email_event ( + id SERIAL PRIMARY KEY, + event_date TIMESTAMP WITH time zone DEFAULT NOW() NOT NULL, + event_desc INTEGER NOT NULL REFERENCES event.event_description, + subject VARCHAR(32) NOT NULL, + message VARCHAR NOT NULL +); + +CREATE VIEW email_event_view AS + SELECT ev.id, event_date, ed.description, subject, message + FROM event.email_event ev + JOIN event.event_description ed ON ev.event_desc = ed.event_desc_id; +GRANT SELECT ON email_event_view TO PUBLIC; + COMMIT; diff --git a/sql/remove_private_data.sql b/sql/remove_private_data.sql index 0a7ed24f66..74369e9cf3 100644 --- a/sql/remove_private_data.sql +++ b/sql/remove_private_data.sql @@ -52,7 +52,6 @@ DELETE FROM iris.map_extent; UPDATE iris.system_attribute SET value = '' WHERE name = 'clearguide_key'; UPDATE iris.system_attribute SET value = '' WHERE name = 'email_smtp_host'; UPDATE iris.system_attribute SET value = '' WHERE name = 'email_sender_server'; -UPDATE iris.system_attribute SET value = '' WHERE name LIKE 'email_recipient_%'; UPDATE iris.system_attribute SET value = '' WHERE name = 'work_request_url'; UPDATE iris.system_attribute SET value = '' WHERE name LIKE 'subnet_target_%'; UPDATE iris.system_attribute SET value = '' WHERE name LIKE 'camera_%_url'; diff --git a/sql/tms-template.sql b/sql/tms-template.sql index 423e4fe85f..8d67fb54fa 100644 --- a/sql/tms-template.sql +++ b/sql/tms-template.sql @@ -82,11 +82,7 @@ dms_pixel_on_limit 1 dms_pixel_test_timeout_secs 30 dms_send_confirmation_enable false dms_update_font_table true -dmsxml_reinit_detect false email_rate_limit_hours 0 -email_recipient_action_plan -email_recipient_dmsxml_reinit -email_recipient_gate_arm email_sender_server email_smtp_host gate_arm_alert_timeout_secs 90 @@ -324,6 +320,7 @@ VALUES ('client_event', true, false, 0), ('comm_event', true, true, 14), ('detector_event', true, true, 90), + ('email_event', true, true, 30), ('gate_arm_event', true, false, 0), ('incident', true, false, 0), ('incident_update', true, false, 0), @@ -392,6 +389,7 @@ COPY event.event_description (event_desc_id, description) FROM stdin; 305 Gate Arm WARN CLOSE 306 Gate Arm CLOSING 307 Gate Arm CLOSED +308 Gate Arm SYSTEM 401 Meter event 402 Meter LOCK 501 Beacon STATE @@ -408,8 +406,23 @@ COPY event.event_description (event_desc_id, description) FROM stdin; 900 Action Plan ACTIVATED 901 Action Plan DEACTIVATED 902 Action Plan Phase CHANGED +903 Action Plan SYSTEM \. +CREATE TABLE event.email_event ( + id SERIAL PRIMARY KEY, + event_date TIMESTAMP WITH time zone DEFAULT NOW() NOT NULL, + event_desc INTEGER NOT NULL REFERENCES event.event_description, + subject VARCHAR(32) NOT NULL, + message VARCHAR NOT NULL +); + +CREATE VIEW email_event_view AS + SELECT ev.id, event_date, ed.description, subject, message + FROM event.email_event ev + JOIN event.event_description ed ON ev.event_desc = ed.event_desc_id; +GRANT SELECT ON email_event_view TO PUBLIC; + -- -- Lane Codes, Direction, Road, Map Extent, Geo Loc -- diff --git a/src/us/mn/state/dot/tms/EventType.java b/src/us/mn/state/dot/tms/EventType.java index 4d011250e5..6339eb0623 100644 --- a/src/us/mn/state/dot/tms/EventType.java +++ b/src/us/mn/state/dot/tms/EventType.java @@ -41,7 +41,7 @@ public enum EventType { CLIENT_UPDATE_PASSWORD(209), GATE_ARM_UNKNOWN(301), GATE_ARM_FAULT(302), GATE_ARM_OPENING(303), GATE_ARM_OPEN(304), GATE_ARM_WARN_CLOSE(305), GATE_ARM_CLOSING(306), - GATE_ARM_CLOSED(307), + GATE_ARM_CLOSED(307), GATE_ARM_SYSTEM(308), METER_EVENT(401), METER_LOCK_EVENT(402), BEACON_EVENT(501), TAG_READ(601), @@ -51,7 +51,7 @@ public enum EventType { CAMERA_SWITCHED(801), CAMERA_VIDEO_LOST(811), CAMERA_VIDEO_RESTORED(812), ACTION_PLAN_ACTIVATED(900), ACTION_PLAN_DEACTIVATED(901), - ACTION_PLAN_PHASE_CHANGED(902); + ACTION_PLAN_PHASE_CHANGED(902), ACTION_PLAN_SYSTEM(903); /** Event type ID */ public final int id; diff --git a/src/us/mn/state/dot/tms/SystemAttrEnum.java b/src/us/mn/state/dot/tms/SystemAttrEnum.java index 7ecff8b629..0f8b858026 100644 --- a/src/us/mn/state/dot/tms/SystemAttrEnum.java +++ b/src/us/mn/state/dot/tms/SystemAttrEnum.java @@ -60,11 +60,7 @@ public enum SystemAttrEnum { DMS_PIXEL_TEST_TIMEOUT_SECS(30, 5, 90), DMS_SEND_CONFIRMATION_ENABLE(false, Change.RESTART_CLIENT), DMS_UPDATE_FONT_TABLE(true), - DMSXML_REINIT_DETECT(false), EMAIL_RATE_LIMIT_HOURS(0, 0), - EMAIL_RECIPIENT_ACTION_PLAN(String.class), - EMAIL_RECIPIENT_DMSXML_REINIT(String.class), - EMAIL_RECIPIENT_GATE_ARM(String.class), EMAIL_SENDER_SERVER(String.class), EMAIL_SMTP_HOST(String.class), GATE_ARM_ALERT_TIMEOUT_SECS(90, 10), diff --git a/src/us/mn/state/dot/tms/server/ActionPlanSystem.java b/src/us/mn/state/dot/tms/server/ActionPlanSystem.java index 876e665184..17485b9e63 100644 --- a/src/us/mn/state/dot/tms/server/ActionPlanSystem.java +++ b/src/us/mn/state/dot/tms/server/ActionPlanSystem.java @@ -1,7 +1,7 @@ /* * IRIS -- Intelligent Roadway Information System * Copyright (C) 2018 Iteris Inc. - * Copyright (C) 2018 Minnesota Department of Transportation + * Copyright (C) 2018-2024 Minnesota Department of Transportation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,6 +16,7 @@ package us.mn.state.dot.tms.server; import java.util.Date; +import us.mn.state.dot.tms.EventType; import us.mn.state.dot.tms.SystemAttrEnum; /** @@ -54,9 +55,8 @@ static public void sendEmailAlert(String usr, boolean active, (active ? " actived" : " deactivated") + " action plan " + "'" + pname + "' on " + new Date().toString(); - String recip = SystemAttrEnum. - EMAIL_RECIPIENT_ACTION_PLAN.getString(); - EmailHandler.sendEmail(sub, msg, recip); + EmailHandler.send(EventType.ACTION_PLAN_SYSTEM, sub, + msg); } } } diff --git a/src/us/mn/state/dot/tms/server/EmailHandler.java b/src/us/mn/state/dot/tms/server/EmailHandler.java index d819fbf27c..6f60a5dec0 100644 --- a/src/us/mn/state/dot/tms/server/EmailHandler.java +++ b/src/us/mn/state/dot/tms/server/EmailHandler.java @@ -1,7 +1,6 @@ /* * IRIS -- Intelligent Roadway Information System - * Copyright (C) 2013-2024 Minnesota Department of Transportation - * Copyright (C) 2018 Iteris Inc. + * Copyright (C) 2024 Minnesota Department of Transportation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,99 +14,20 @@ */ package us.mn.state.dot.tms.server; -import java.util.HashMap; -import javax.mail.MessagingException; -import us.mn.state.dot.sched.Job; -import us.mn.state.dot.sched.Scheduler; -import us.mn.state.dot.sched.TimeSteward; -import us.mn.state.dot.tms.SystemAttrEnum; -import us.mn.state.dot.tms.units.Interval; -import static us.mn.state.dot.tms.units.Interval.Units.HOURS; +import us.mn.state.dot.tms.EventType; +import us.mn.state.dot.tms.server.event.EmailEvent; /** - * Handler for email. + * Email event handler * * @author Douglas Lau - * @author Michael Darter */ public class EmailHandler { - /** Interval value of one hour (ms) */ - static private final long HOUR_MS = new Interval(1, HOURS).ms(); - - /** Get email rate limiting time (hours) */ - static private int getEmailRateLimitHours() { - return SystemAttrEnum.EMAIL_RATE_LIMIT_HOURS.getInt(); - } - - /** Get email rate limiting time (ms) */ - static private long getEmailRateLimitMs() { - return getEmailRateLimitHours() * HOUR_MS; - } - - /** Mapping of messages to last sent time */ - static private final HashMap MSG_TIME = - new HashMap(); - - /** Scheduler for email jobs */ - static private final Scheduler EMAIL = new Scheduler("email"); - - /** Disallow instantiation */ - private EmailHandler() { } - - /** Log an error to stderr */ - static private void logEmailError(String msg, String reason) { - System.err.println(TimeSteward.currentDateTimeString(true) + - " Email not sent (" + msg + "), " + reason); - } - - /** Send an email. This method does not block. - * @param sub Subject of email. - * @param msg Text of email. - * @param recip Recipient of email. */ - static public void sendEmail(final String sub, final String msg, - final String recip) + /** Send an email */ + static public void send(final EventType et, final String sub, + final String msg) { - EMAIL.addJob(new Job(0) { - @Override public String getName() { - return sub; - } - @Override public void perform() { - doSendEmail(sub, msg, recip); - } - }); - } - - /** Send an email. This method blocks while sending. - * @param sub Subject of email. - * @param msg Text of email. - * @param recip Recipient of email. */ - static private void doSendEmail(String sub, String msg, String recip) { - Long p = MSG_TIME.get(msg); - if (p != null) { - long elapsed_ms = TimeSteward.currentTimeMillis() - p; - if (elapsed_ms < getEmailRateLimitMs()) - return; - } - if (null == recip || recip.length() <= 0) - return; - String host = SystemAttrEnum.EMAIL_SMTP_HOST.getString(); - if (null == host || host.length() <= 0) { - logEmailError(msg, "invalid host"); - return; - } - String sender = SystemAttrEnum.EMAIL_SENDER_SERVER.getString(); - if (null == sender || sender.length() <= 0) { - logEmailError(msg, "invalid sender"); - return; - } - try { - Emailer email = new Emailer(host, sender, recip); - email.send(sub, msg); - MSG_TIME.put(msg, TimeSteward.currentTimeMillis()); - } - catch (MessagingException e) { - logEmailError(msg, "failed: " + e.getMessage()); - } + BaseObjectImpl.logEvent(new EmailEvent(et, sub, msg)); } } diff --git a/src/us/mn/state/dot/tms/server/Emailer.java b/src/us/mn/state/dot/tms/server/Emailer.java deleted file mode 100644 index 9b3717230f..0000000000 --- a/src/us/mn/state/dot/tms/server/Emailer.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * IRIS -- Intelligent Roadway Information System - * Copyright (C) 2008-2024 Minnesota Department of Transportation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 - * GNU General Public License for more details. - */ -package us.mn.state.dot.tms.server; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.Date; -import java.util.Properties; -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.Session; -import javax.mail.Transport; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeMessage; - -/** - * A simple email abstraction. - * - * @author Douglas Lau - */ -public class Emailer { - - /** Email properties */ - private final Properties props = new Properties(); - - /** Address of sender */ - private final InternetAddress sender; - - /** Address of recipient(s) */ - private final InternetAddress[] recip; - - /** Create a new emailer. - * @param h Email host. - * @param s Sender email address. - * @param r Recipient email address(es). */ - public Emailer(String h, String s, String r) throws MessagingException { - props.setProperty("mail.smtp.host", h); - sender = new InternetAddress(s); - recip = InternetAddress.parse(r); - } - - /** Send an email. - * @param subject Subject of mail. - * @param text Text of mail. */ - public void send(String subject, String text) throws MessagingException{ - MimeMessage mm = createMessage(); - mm.setSubject(subject); - mm.setText(buildText(text)); - Transport.send(mm); - } - - /** Create a MIME Message */ - private MimeMessage createMessage() throws MessagingException { - Session session = Session.getInstance(props, null); - MimeMessage mm = new MimeMessage(session); - mm.setFrom(sender); - mm.addRecipients(Message.RecipientType.TO, recip); - return mm; - } - - /** Build message text */ - private String buildText(String text) { - StringBuilder sb = new StringBuilder(); - sb.append(new Date().toString()); - sb.append(": Host: "); - sb.append(getHostName()); - sb.append('\n'); - sb.append(text); - sb.append('\n'); - return sb.toString(); - } - - /** Get the local host name */ - private String getHostName() { - try { - return InetAddress.getLocalHost().getHostName(); - } - catch (UnknownHostException e) { - return "unknown"; - } - } -} diff --git a/src/us/mn/state/dot/tms/server/GateArmSystem.java b/src/us/mn/state/dot/tms/server/GateArmSystem.java index 6213322b9a..58d2db6e12 100644 --- a/src/us/mn/state/dot/tms/server/GateArmSystem.java +++ b/src/us/mn/state/dot/tms/server/GateArmSystem.java @@ -1,6 +1,6 @@ /* * IRIS -- Intelligent Roadway Information System - * Copyright (C) 2013-2022 Minnesota Department of Transportation + * Copyright (C) 2013-2024 Minnesota Department of Transportation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ import java.util.Iterator; import us.mn.state.dot.sched.TimeSteward; import us.mn.state.dot.tms.DeviceRequest; +import us.mn.state.dot.tms.EventType; import us.mn.state.dot.tms.GateArmArray; import us.mn.state.dot.tms.GateArmArrayHelper; import us.mn.state.dot.tms.GeoLoc; @@ -125,9 +126,8 @@ static public DeviceRequest checkRequest(DeviceRequest dr) { /** Send an email alert */ static public void sendEmailAlert(String msg) { - String recip = - SystemAttrEnum.EMAIL_RECIPIENT_GATE_ARM.getString(); - EmailHandler.sendEmail("Gate arm ALERT", msg, recip); + EmailHandler.send(EventType.GATE_ARM_SYSTEM, "Gate Arm ALERT", + msg); } /** Check all gate arm open interlocks for one road. diff --git a/src/us/mn/state/dot/tms/server/comm/dmsxml/Message.java b/src/us/mn/state/dot/tms/server/comm/dmsxml/Message.java index 82685fa879..2462c92612 100644 --- a/src/us/mn/state/dot/tms/server/comm/dmsxml/Message.java +++ b/src/us/mn/state/dot/tms/server/comm/dmsxml/Message.java @@ -21,7 +21,6 @@ import us.mn.state.dot.sched.TimeSteward; import us.mn.state.dot.tms.Controller; import us.mn.state.dot.tms.SystemAttrEnum; -import us.mn.state.dot.tms.server.EmailHandler; import us.mn.state.dot.tms.server.comm.CommMessage; import us.mn.state.dot.tms.server.comm.ControllerProperty; import us.mn.state.dot.tms.server.comm.ParsingException; diff --git a/src/us/mn/state/dot/tms/server/comm/dmsxml/OpDms.java b/src/us/mn/state/dot/tms/server/comm/dmsxml/OpDms.java index c8739222f8..c3ae484427 100644 --- a/src/us/mn/state/dot/tms/server/comm/dmsxml/OpDms.java +++ b/src/us/mn/state/dot/tms/server/comm/dmsxml/OpDms.java @@ -29,7 +29,6 @@ import us.mn.state.dot.tms.PageTimeHelper; import us.mn.state.dot.tms.SystemAttrEnum; import us.mn.state.dot.tms.server.DMSImpl; -import us.mn.state.dot.tms.server.EmailHandler; import us.mn.state.dot.tms.server.SignConfigImpl; import us.mn.state.dot.tms.server.SignDetailImpl; import us.mn.state.dot.tms.server.comm.CommMessage; @@ -205,30 +204,8 @@ void sendRead(Message mess) throws IOException { /** Check message owner */ public void checkMsgOwner(String o) { - if (ownerIsReinit(o)) { + if ("reinit".equalsIgnoreCase(o)) putCtrlFaults("Power cycle event"); - sendMaintenanceEmail(); - } - } - - /** Return true if the message owner is Reinit */ - private boolean ownerIsReinit(final String o) { - return SystemAttrEnum.DMSXML_REINIT_DETECT.getBoolean() - && (o != null) - && o.toLowerCase().equals("reinit"); - } - - /** Send power cycle email */ - private void sendMaintenanceEmail() { - String sub = "CMS maintenance alert: " + m_dms; - String msg = "IRIS has placed CMS " + m_dms + " into " - + "\"maintenance\" mode. One reason this may have " - + "happened is if IRIS has found the sign to be " - + "unexpectedly blank, which could indicate that the " - + "sign controller's power has been cycled."; - String recip = - SystemAttrEnum.EMAIL_RECIPIENT_DMSXML_REINIT.getString(); - EmailHandler.sendEmail(sub, msg, recip); } /** Phase to query the dms config, which is used by subclasses */ diff --git a/src/us/mn/state/dot/tms/server/event/EmailEvent.java b/src/us/mn/state/dot/tms/server/event/EmailEvent.java new file mode 100644 index 0000000000..ab5090ad79 --- /dev/null +++ b/src/us/mn/state/dot/tms/server/event/EmailEvent.java @@ -0,0 +1,74 @@ +/* + * IRIS -- Intelligent Roadway Information System + * Copyright (C) 2024 Minnesota Department of Transportation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 + * GNU General Public License for more details. + */ +package us.mn.state.dot.tms.server.event; + +import java.sql.Timestamp; +import java.util.HashMap; +import java.util.Map; +import us.mn.state.dot.tms.EventType; + +/** + * Email events in database. + * + * @author Douglas Lau + */ +public class EmailEvent extends BaseEvent { + + /** Is the specified event an email event? */ + static private boolean isEmailEvent(EventType et) { + return EventType.ACTION_PLAN_SYSTEM == et || + EventType.GATE_ARM_SYSTEM == et; + } + + /** Message subject */ + private final String subject; + + /** Message text */ + private final String message; + + /** Create a new email event. + * @param et Event type. + * @param sub Subject. + * @param msg Message text. */ + public EmailEvent(EventType et, String sub, String msg) { + super(et); + assert isEmailEvent(et); + subject = sub; + message = msg; + } + + /** Get the event config name */ + @Override + protected String eventConfigName() { + return "email_event"; + } + + /** Get the database table name */ + @Override + public String getTable() { + return "event.email_event"; + } + + /** Get a mapping of the columns */ + @Override + public Map getColumns() { + HashMap map = new HashMap(); + map.put("event_date", new Timestamp(event_date.getTime())); + map.put("event_desc", event_type.id); + map.put("subject", subject); + map.put("message", message); + return map; + } +}