Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OTP-1465 Schedule Trip History Uploade #272

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. |
Expand Down
1 change: 1 addition & 0 deletions configurations/default/env.yml.tmp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One detail that I overlooked is that the configured start time should only apply if the uploads are daily (CONNECTED_DATA_PLATFORM_REPORTING_INTERVAL = "daily"). If the reporting interval is hourly, the job should still start immediately.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract a method to compute the initial delay (lines 122 to 125), and place it in DateTimeUtils or Scheduler, and add a unit test for that method.


Scheduler.scheduleJob(
new TripHistoryUploadJob(),
0,
initialDelayMinutes,
CONNECTED_DATA_PLATFORM_TRIP_HISTORY_UPLOAD_JOB_FREQUENCY_IN_MINUTES,
TimeUnit.MINUTES);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,21 @@ public static List<LocalDateTime> 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.
*/
Expand Down
5 changes: 5 additions & 0 deletions src/main/resources/env.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -46,6 +48,14 @@ private static Stream<Arguments> 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));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you are using an absolute date zdt, can you assert on the date, hour, and minutes instead?

}

@Test
void canGetPreviousDay() {
var date = LocalDateTime.of(2024, 8, 10, 15, 34, 17);
Expand Down
Loading