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

TSPS-140 Send email notifications for succeeded and failed jobs #181

Merged
merged 28 commits into from
Jan 3, 2025

Conversation

mmorgantaylor
Copy link
Collaborator

@mmorgantaylor mmorgantaylor commented Dec 11, 2024

Description

Add the ability for Teaspoons to send email notifications upon job completion, via PubSub messages sent to a topic that Thurloe (Terra service) subscribes to and uses SendGrid to send the email. Success for Teaspoons is posting the PubSub message.

If the PipelineRun succeeds, the final step in the flight is to send the "job succeeded" notification.
If the PipelineRun fails, the StairwaySendFailedJobNotificationHook is called that sends the "job failed" notification.

Email notifications from BEE testing:
succeeded:
image

failed:
image

Related PRs:

Jira Ticket

https://broadworkbench.atlassian.net/browse/TSPS-140

Copy link
Collaborator

@jsotobroad jsotobroad left a comment

Choose a reason for hiding this comment

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

havent looked through the tests yet. have a couple of questions/suggestions

@@ -7,6 +7,7 @@
<include file="changesets/20241106-add-indexes.yaml" relativeToChangelogFile="true"/>
<include file="changesets/20241106-base-data-insertion.yaml" relativeToChangelogFile="true"/>
<include file="changesets/20241125_drop_result_url_column.yaml" relativeToChangelogFile="true"/>
<include file="changesets/20241212_add_quota_consumed_update_pipeline_display_name.yaml" relativeToChangelogFile="true"/>
Copy link
Collaborator

@jsotobroad jsotobroad Dec 18, 2024

Choose a reason for hiding this comment

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

it shouldn't actually matter but to be safe this should probably go after the min_quota one in this file

}

/** helper method to create a PipelineRun object for a completed job. */
private PipelineRun getPipelineRunWithStatus(CommonPipelineRunStatusEnum status) {
private PipelineRun getPipelineRunWithStatus(
Copy link
Collaborator

Choose a reason for hiding this comment

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

i would either rename this function to getPipelineRunWithStatusAndQuotaConsumed or probably more cleanly select an appropriate value for quotaConsumed in this function depending on the status passed in.

if (flightMapKeyIsTrue(inputParameters, JobMapKeys.DO_SEND_JOB_FAILURE_NOTIFICATION_HOOK)
&& context.getFlightStatus() != FlightStatus.SUCCESS) {
logger.info(
"Flight has status {}, sending failed job notification email", context.getFlightStatus());
Copy link
Collaborator

Choose a reason for hiding this comment

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

can we log the flight id as well here

Copy link
Collaborator

Choose a reason for hiding this comment

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

chatted with faces, this already has the flight id associated with the log itself

import lombok.Getter;

@Getter
public class BaseTeaspoonsJobNotification {
Copy link
Collaborator

Choose a reason for hiding this comment

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

a light description would be nice here since its the base class

* @param jobId the job id
* @param userId the user id
*/
public void configureAndSendPipelineRunSucceededNotification(UUID jobId, String userId) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

it looks liek this function and the failure equivalent are really the ones that should be called outside of this class, can we maek the rest of the functions private?

Comment on lines 8 to 9
public final String notificationType;
public final String quotaConsumedByJob;
Copy link
Collaborator

Choose a reason for hiding this comment

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

these two fields seem to be in both subclasses of the base class. Any reason to not put them in the base class?

public final String quotaConsumedByJob;

public TeaspoonsJobSucceededNotification(
BaseTeaspoonsJobNotification baseTeaspoonsJobNotification, String quotaConsumedByJob) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

this is a bit of an awkward pattern for a sub class to have its parent class as constructor argument. prob worth talkign about to see if there is a way to not do this

import org.slf4j.LoggerFactory;

/**
* Step to send an email notification that a job has succeeded. This step cannot fail (we catch all
Copy link
Collaborator

Choose a reason for hiding this comment

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

can we add the expectations from the working map and stuff like we do for other steps (i know its nothing but easier just to read it in the description)

} catch (Exception e) {
logger.error("Failed to send email notification", e);
}
return StepResult.getStepResultSuccess();
Copy link
Collaborator

Choose a reason for hiding this comment

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

always success!!

@@ -34,6 +34,9 @@ env:
imputation:
# the default currently points to the GCP dev workspace teaspoons-imputation-dev/teaspoons_imputation_dev_storage_workspace_20240726
storageWorkspaceStorageUrl: ${IMPUTATION_STORAGE_WORKSPACE_STORAGE_URL:gs://fc-secure-10efd4d7-392a-4e9e-89ea-d6629fbb06cc}
notifications:
projectId: ${NOTIFICATION_PROJECT_ID:broad-dsde-dev}
Copy link
Collaborator

Choose a reason for hiding this comment

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

nice you already have the helmfile pr created, woot!

@mmorgantaylor mmorgantaylor force-pushed the TSPS-140_send_email_notifications branch from cabd972 to 7d35e9b Compare December 19, 2024 18:33
@mmorgantaylor mmorgantaylor marked this pull request as ready for review December 19, 2024 19:44
Copy link
Collaborator

@jsotobroad jsotobroad left a comment

Choose a reason for hiding this comment

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

woohoo! just had a question about the mocking in some of the tests. looks great though

int expectedQuotaRemaining = updatedUserQuota.getQuota() - updatedUserQuota.getQuotaConsumed();

// success is a void method
doNothing().when(pubsubService).publishMessage(any(), any(), any());
Copy link
Collaborator

Choose a reason for hiding this comment

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

can this be made any more specific than any()s. same for the other mocking

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

yes, good call - are you ok leaving the any()s when it's mocking throwing an exception?

Copy link
Collaborator

Choose a reason for hiding this comment

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

yup totally fine!

@Test
void initPublisher() throws IOException {
TopicName topicName = TopicName.of("projectId", "topicId");
try (MockedStatic<Publisher> mockedStaticPublisher = mockStatic(Publisher.class)) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

staticccccccc!!

@mmorgantaylor mmorgantaylor merged commit aa748b5 into main Jan 3, 2025
15 checks passed
@mmorgantaylor mmorgantaylor deleted the TSPS-140_send_email_notifications branch January 3, 2025 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants