From ab2a09467110646768c5de5bb79522ca7a74ef74 Mon Sep 17 00:00:00 2001 From: Jym Dyer Date: Fri, 22 Nov 2024 12:41:12 -0800 Subject: [PATCH 1/4] OTP-1465 Utility function for next occurrence of time of day. --- .../middleware/utils/DateTimeUtils.java | 15 +++++++++++++++ .../middleware/utils/DateTimeUtilsTest.java | 10 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/main/java/org/opentripplanner/middleware/utils/DateTimeUtils.java b/src/main/java/org/opentripplanner/middleware/utils/DateTimeUtils.java index 7c5c2376d..6781c85d0 100644 --- a/src/main/java/org/opentripplanner/middleware/utils/DateTimeUtils.java +++ b/src/main/java/org/opentripplanner/middleware/utils/DateTimeUtils.java @@ -312,6 +312,21 @@ public static List getTimeUnitsBetween( .collect(Collectors.toList()); } + /** + * Given a date/timestamp, find the next occurrence of a specified time of day. + * This could be the same day as the timestamp, or the next day. Only the hours + * and minutes precision are recognized in the time of day value, so for example + * {@code LocalTime.parse("08:15")} would work as a time of day. + * @param timeOfDay time of day that we want to find the next occurrence of + * @param zonedDateTime the date/timestamp to start from + */ + public static ZonedDateTime getNextTimeFrom(LocalTime timeOfDay, ZonedDateTime zonedDateTime) { + var nextDateTime = zonedDateTime.truncatedTo(ChronoUnit.DAYS) + .plusHours(timeOfDay.getHour()) + .plusMinutes(timeOfDay.getMinute()); + return nextDateTime.isAfter(zonedDateTime) ? nextDateTime : nextDateTime.plusDays(1); + } + /** * Return the previous whole hour from a given date. E.g. If the time is 07:30, return 06:00. */ diff --git a/src/test/java/org/opentripplanner/middleware/utils/DateTimeUtilsTest.java b/src/test/java/org/opentripplanner/middleware/utils/DateTimeUtilsTest.java index 4dbbe4e3b..91e00c1e3 100644 --- a/src/test/java/org/opentripplanner/middleware/utils/DateTimeUtilsTest.java +++ b/src/test/java/org/opentripplanner/middleware/utils/DateTimeUtilsTest.java @@ -6,6 +6,7 @@ import org.junit.jupiter.params.provider.MethodSource; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.ZonedDateTime; import java.util.Date; import java.util.List; @@ -15,6 +16,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.text.MatchesPattern.matchesPattern; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.opentripplanner.middleware.utils.DateTimeUtils.getDaysBetween; import static org.opentripplanner.middleware.utils.DateTimeUtils.getHoursBetween; import static org.opentripplanner.middleware.utils.DateTimeUtils.getPreviousDayFrom; @@ -46,6 +48,14 @@ private static Stream createDateFormatCases() { ); } + @Test + void canGetNextTimeFrom() { + var zdt = ZonedDateTime.of(2024, 11, 11, 15, 34, 17, 0, DateTimeUtils.getOtpZoneId()); + var timeOfDay = LocalTime.parse("05:15"); + var zdtNext = DateTimeUtils.getNextTimeFrom(timeOfDay, zdt); + assertTrue(zdtNext.isAfter(zdt)); + } + @Test void canGetPreviousDay() { var date = LocalDateTime.of(2024, 8, 10, 15, 34, 17); From caa9f2db491f725ac4dcda3c5f3b29588b540687 Mon Sep 17 00:00:00 2001 From: Jym Dyer Date: Fri, 22 Nov 2024 12:42:06 -0800 Subject: [PATCH 2/4] OTP-1465 Implement start time for trip history upload. --- .../ConnectedDataManager.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/opentripplanner/middleware/connecteddataplatform/ConnectedDataManager.java b/src/main/java/org/opentripplanner/middleware/connecteddataplatform/ConnectedDataManager.java index c38bf17a1..7f656e907 100644 --- a/src/main/java/org/opentripplanner/middleware/connecteddataplatform/ConnectedDataManager.java +++ b/src/main/java/org/opentripplanner/middleware/connecteddataplatform/ConnectedDataManager.java @@ -27,8 +27,10 @@ import java.io.File; import java.io.IOException; import java.time.DayOfWeek; +import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; @@ -63,6 +65,9 @@ public class ConnectedDataManager { private static final int CONNECTED_DATA_PLATFORM_TRIP_HISTORY_UPLOAD_JOB_FREQUENCY_IN_MINUTES = getConfigPropertyAsInt("CONNECTED_DATA_PLATFORM_TRIP_HISTORY_UPLOAD_JOB_FREQUENCY_IN_MINUTES", 5); + private static final String CONNECTED_DATA_PLATFORM_TRIP_HISTORY_UPLOAD_START_TIME = + getConfigPropertyAsText("CONNECTED_DATA_PLATFORM_TRIP_HISTORY_UPLOAD_START_TIME", "03:00"); + private static final Logger LOG = LoggerFactory.getLogger(ConnectedDataManager.class); public static final String CONNECTED_DATA_PLATFORM_S3_BUCKET_NAME = @@ -110,11 +115,18 @@ public static boolean canScheduleUploads() { public static void scheduleTripHistoryUploadJob() { if (canScheduleUploads()) { - LOG.info("Scheduling trip history upload for every {} minute(s)", - CONNECTED_DATA_PLATFORM_TRIP_HISTORY_UPLOAD_JOB_FREQUENCY_IN_MINUTES); + LOG.info("Scheduling trip history upload for every {} minute(s) starting at {}", + CONNECTED_DATA_PLATFORM_TRIP_HISTORY_UPLOAD_JOB_FREQUENCY_IN_MINUTES, + CONNECTED_DATA_PLATFORM_TRIP_HISTORY_UPLOAD_START_TIME); + + var now = DateTimeUtils.nowAsZonedDateTime(DateTimeUtils.getOtpZoneId()); + var timeOfDay = LocalTime.parse(CONNECTED_DATA_PLATFORM_TRIP_HISTORY_UPLOAD_START_TIME); + var startAt = DateTimeUtils.getNextTimeFrom(timeOfDay, now); + long initialDelayMinutes = Duration.between(now, startAt).toMinutes(); + Scheduler.scheduleJob( new TripHistoryUploadJob(), - 0, + initialDelayMinutes, CONNECTED_DATA_PLATFORM_TRIP_HISTORY_UPLOAD_JOB_FREQUENCY_IN_MINUTES, TimeUnit.MINUTES); } From 7cb21018f5465731600423f428610d984bb2371b Mon Sep 17 00:00:00 2001 From: Jym Dyer Date: Fri, 22 Nov 2024 13:13:41 -0800 Subject: [PATCH 3/4] OTP-1465 New config setting. --- configurations/default/env.yml.tmp | 1 + src/main/resources/env.schema.json | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/configurations/default/env.yml.tmp b/configurations/default/env.yml.tmp index c7996a62e..b05b4bf05 100644 --- a/configurations/default/env.yml.tmp +++ b/configurations/default/env.yml.tmp @@ -17,6 +17,7 @@ CONNECTED_DATA_PLATFORM_S3_FOLDER_NAME: folder-name CONNECTED_DATA_PLATFORM_REPORTING_INTERVAL: hourly CONNECTED_DATA_PLATFORM_FOLDER_GROUPING: none CONNECTED_DATA_PLATFORM_TRIP_HISTORY_UPLOAD_JOB_FREQUENCY_IN_MINUTES: 5 +CONNECTED_DATA_PLATFORM_TRIP_HISTORY_UPLOAD_START_TIME: 03:00 CONNECTED_DATA_PLATFORM_UPLOAD_BLANK_FILES: true CONNECTED_DATA_PLATFORM_REPORTED_ENTITIES: MonitoredTrip: all diff --git a/src/main/resources/env.schema.json b/src/main/resources/env.schema.json index f40de5414..82f28eb4b 100644 --- a/src/main/resources/env.schema.json +++ b/src/main/resources/env.schema.json @@ -118,6 +118,11 @@ ], "description": "CDP trip history upload frequency." }, + "CONNECTED_DATA_PLATFORM_TRIP_HISTORY_UPLOAD_START_TIME": { + "type": "string", + "examples": ["03:30"], + "description": "CDP trip history upload start time of day in HH:MM format." + }, "CONNECTED_DATA_PLATFORM_UPLOAD_BLANK_FILES": { "type": "boolean", "examples": ["true"], From 858766c29c987c7f0a1782621c9c1b74e4a332e3 Mon Sep 17 00:00:00 2001 From: Jym Dyer Date: Fri, 22 Nov 2024 13:37:03 -0800 Subject: [PATCH 4/4] OTP-1465 README with new config setting. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d2627da9e..ca47fde8e 100644 --- a/README.md +++ b/README.md @@ -264,6 +264,7 @@ The special E2E client settings should be defined in `env.yml`: | CONNECTED_DATA_PLATFORM_S3_FOLDER_NAME | string | Optional | folder-name | Specifies the S3 folder name for the CDP trip history push. | | CONNECTED_DATA_PLATFORM_REPORTED_ENTITIES | object | Optional | { "MonitoredTrip": "all", "OtpUser": "all", "TripRequest": "interval" } | Use 'all' to report all full records. Use 'interval' to report full records whose dateCreated is within a reporting interval (e.g. day, hour). For TripRequest, you can use 'all anonymized' or 'interval anonymized' to anonymize records. Omitted entities are ignored. | | CONNECTED_DATA_PLATFORM_TRIP_HISTORY_UPLOAD_JOB_FREQUENCY_IN_MINUTES | integer | Optional | 5 | CDP trip history upload frequency. | +| CONNECTED_DATA_PLATFORM_TRIP_HISTORY_UPLOAD_START_TIME | string | Optional | 03:30 | CDP trip history upload start time of day in HH:MM format. | | CONNECTED_DATA_PLATFORM_UPLOAD_BLANK_FILES | boolean | Optional | true | Whether to upload files where no records have been written. Defaults to true. | | DEFAULT_USAGE_PLAN_ID | string | Required | 123e45 | AWS API gateway default usage plan used when creating API keys for API users. | | MAXIMUM_MONITORED_TRIP_ITINERARY_CHECKS | integer | Optional | 3 | The maximum number of attempts to obtain a monitored trip itinerary. |