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

[DSM] PEPPER-1402 PEPPER-1397 refactoring DSM event transmission into DSS and retrying failed events #2874

Merged
merged 36 commits into from
Jun 6, 2024

Conversation

pegahtah
Copy link
Contributor

@pegahtah pegahtah commented May 23, 2024

Context

Update 6/3

In the last commits I have made a super class BaseKitTestUtil (here) and two children classes ( PepperKitUtil and JuniperKitUtil ). I moved what was the base of both classes into the super class and created the two smaller classes

Original PR Context

This PR refactors the DSM event transmission process to DSS and implements a retry mechanism for failed events. Key changes include:

Checklist

  • I have labeled the type of changes involved using the C-* labels.
  • I have assessed potential risks and labeled using the R-* labels.
  • I have considered error handling and alerts, and added L-* labels as needed.
  • I have considered security and privacy, and added I-* labels as needed
  • I have analyzed my changes for stability, fault tolerance, graceful degradation, performance bottlenecks and written a brief summary in this PR.
  • If applicable, I have discussed the analytics needs at both a platform and study level with Product and instrumented code accordingly.
  • If applicable, my UI/UX changes have passed muster with Product/Design via an over-the-shoulder review, screenshots, etc.

If unsure or need help with any of the above items, add the help wanted label. For items that starts with If applicable, if it is not applicable, check it off and add n/a in front.

FUD Score

Overall, how are you feeling about these changes?

  • ☺️ All good, business as usual!
  • 😅 There might be some issues here
  • 😱 I'm sweaty and nervous

How do we demo these changes?

How does one observe these changes in a deployed system? Note that user visible encompasses many personas--not just patients and study staff, but also ops duty, your fellow devs, compliance, etc.

  • They are user-visible in dev as a regular user journey and require no additional instructions.
  • Getting dev into a state where this is user-visible requires some tech fiddling. I have documented these steps in the related ticket.
  • Requires other features before it's human visible. I have documented the blocking issues in jira.
  • I have no idea how to demo this. Please help me!

Testing

  • I have added regression test labels to the jira ticket
  • I have added verification steps to the jira ticket
  • I have written automated positive tests
  • I have written automated negative tests
  • I have written zero automated tests but have poked around locally to verify proper functionality
  • The jira ticket has acceptance criteria and QA has the needed information to test changes

Release

  • These changes require no special release procedures--just code!
  • Releasing these changes requires special handling and I have documented the special procedures in the release plan document

added retries
removed connections
renamed and made the code more readable
got rid of unnecessary codes and classes
some clean up
some more refactoring
renaming some classes
renaming some classes
# Conflicts:
#	pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/kits/TestKitUtil.java
…ass name to EventService and moved it to service, also changed the name of the test class and moved it,
@@ -404,31 +404,6 @@ public static DDPInstance getDDPInstanceWithRoleByParticipant(@NonNull String pa
return (DDPInstance) results.resultValue;
}

public static boolean getRole(@NonNull String realm, @NonNull String role) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Was not used

@@ -276,7 +276,7 @@ public static DDPInstance getDDPInstanceWithRole(@NonNull String realm, @NonNull
public static DDPInstance getDDPInstanceWithRoleByStudyGuid(@NonNull String studyGuid, @NonNull String role) {
SimpleResult results = inTransaction((conn) -> {
SimpleResult dbVals = new SimpleResult();
try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_INSTANCE_WITH_ROLE + QueryExtension.BY_STUDY_GUID)) {
try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_INSTANCE_WITH_ROLE.concat(QueryExtension.BY_STUDY_GUID))) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

the concat changes are a fix for sonar marking these as "blocker" issues

@@ -1,610 +0,0 @@
package org.broadinstitute.dsm.jobs;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got rid of this job

@@ -1,15 +0,0 @@
package org.broadinstitute.dsm.model;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We also don't need this event anymore

+ " realm.migrated_ddp, kit.receive_date, kit.scan_date from ddp_kit_request request, ddp_kit kit, event_type eve, "
+ " ddp_instance realm where request.dsm_kit_request_id = kit.dsm_kit_request_id and "
+ " request.ddp_instance_id = realm.ddp_instance_id and (eve.ddp_instance_id = request.ddp_instance_id "
+ " and eve.kit_type_id = request.kit_type_id) and eve.event_type = 'RECEIVED' and kit.kit_label = ?";
Copy link
Contributor Author

Choose a reason for hiding this comment

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

moved this from the conf file to the class for better testing and code readability

@@ -82,18 +82,18 @@ public static Optional<KitInfo> receiveKit(String kitLabel, BSPKitDto bspKitQuer

}

private static void updateKitAndExport(String kitLabel, BSPKitDao bspKitDao, BSPKitDto maybeBspKitQueryResult, boolean triggerDDP,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The maybe in the name was throwing me off and made we think we have an optional here, so I removed it

@@ -1,21 +0,0 @@
package org.broadinstitute.lddp.handlers.util;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Merged this and the KitEvent class into a new Event class because this original Event class was not used anywhere by its own, the only usage was that KitEvent inherited from it

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This role was needed in the test db for testing purposes

@@ -15,6 +15,7 @@
import java.util.List;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changes here are not really related to this ticket, just some clean up that came up when I was making changes in the TestKitUtil.

public class EventDto {

private int eventId;
private long eventDateCreated;
private String eventType;
private int ddpInstanceId;
private int dsmKitRequestId;
private Integer dsmKitRequestId;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

for participant events the dsmKitRequestId will be null

Copy link
Contributor

Choose a reason for hiding this comment

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

Worth putting this into a code comment!

import org.broadinstitute.dsm.model.mercury.BaseMercuryStatusMessage;

@Slf4j
public class MercuryOrderStatusListener {

private MercuryOrderStatusListener(){
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Checkstyle fixes here

@@ -1,276 +0,0 @@
package org.broadinstitute.dsm.util;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This has been changed to EventService

@pegahtah pegahtah requested a review from zyme May 23, 2024 19:32
@pegahtah pegahtah added C-bug Category: identifies or fixes a bug C-feature Category: non-breaking change which adds new functionality C-enhancement Category: code clean ups, refactors, or general enhancements java Pull requests that update Java code labels May 23, 2024
}
stmt.setString(5, eventType);
stmt.executeUpdate();
} catch (SQLException e) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think there's an antipattern here--the method returns void, but there's this two-step try/catch and then a check of results.resultException. To reduce the complexity, instead of handling the return value from inTransaction this way, just do what you need to do within inTransaction, returning null, and then catch SQLException and retrhwo as DsmInternalError.

RetryConfig retryConfig = RetryConfig.custom()
.maxAttempts(MAX_TRIES)
.intervalFunction(intervalFn)
.build();
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the initial interval needs to be longer. What are the typical response times when hitting this DSS endpoint? If the response time is shorter than the typical time it takes for the dss route to complete, does this run the risk of making repeated attempts that will actually get through, then causing further issues?

…r a response from dss , and also did a major refactoring for our util classes in test that were creating test kits.
…-1397_trigger_ddp

# Conflicts:
#	pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/kit/KitDao.java
@@ -1,339 +0,0 @@
package org.broadinstitute.dsm.juniperkits;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Was renamed and refactored into JuniperKitUtil

@@ -0,0 +1,264 @@
package org.broadinstitute.dsm.kits;
Copy link
Contributor Author

@pegahtah pegahtah Jun 3, 2024

Choose a reason for hiding this comment

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

This class consists of the overlapped functionality that used to be in the TestKitUtil and JuniperTestSetupUtil.
In the new structure this class contains what is a standard kit's journey and specific kit setup that belongs to only one of Juniper or Pepper is now in JuniperKitUtil and PepperKitUtil

throw new DsmInternalError(String.format("Unable to get primary key for %s", table));
}
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All moved to super class

stmt.executeUpdate();
ResultSet rs = stmt.getGeneratedKeys();
return getPrimaryKey(rs, "kit_dimension");
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

All moved into super class


return new Gson().fromJson(json, JuniperKitRequest.class);
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not relevant to PepperKitUtil

@@ -11,7 +11,7 @@
import org.broadinstitute.dsm.db.dao.ddp.instance.DDPInstanceDao;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Only change in this class is name changes of TestKitUtil to PepperKitUtil

@@ -107,7 +107,7 @@ public void createRealmAndStudyGroup(@NonNull String realmName, String studyGuid
* Setup study admin and study roles
*
* @param adminEmail for new admin user account
* @param adminRole PEPPER_ADMIN or STUDY_USER_ADMIN
Copy link
Contributor Author

Choose a reason for hiding this comment

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

PEPPER_ADMIN_ROLE is the correct one

@@ -3,40 +3,55 @@
import java.util.List;

import org.broadinstitute.dsm.DbTxnBaseTest;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This class was changes a little bit because it was using juniper kits while it should have been pepper kits. Now that we have two functionalities for creating kits, I changed this to use the correct one (otherwise tests would not pass)

@@ -3,9 +3,7 @@
import static org.broadinstitute.ddp.db.TransactionWrapper.inTransaction;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

TestKitUtil is not changed to PepperKitUtil, while lots of its kit functionality is now in the BaseKitTestUtil

@@ -30,6 +30,7 @@
import org.broadinstitute.dsm.model.nonpepperkit.NonPepperStatusKitService;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

the changes here are only name changes from JuniperTestSetupUtil to JuniperKitUtil

@@ -64,7 +64,7 @@ public class ClinicalOrderDaoTest extends DbTxnBaseTest {

private static int oncHistoryDetailId = -1;

public static TestKitUtil testKitUtil;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's basically the only change in this class, and below is only the name changed for pepperKitUtil

@@ -96,7 +96,7 @@ protected static boolean triggerDssByKitEvent(KitDDPNotification kitDDPNotificat
@VisibleForTesting
protected static boolean triggerDssWithEvent(@NonNull String eventType, DDPInstance ddpInstance, long eventDate,
@NotNull String ddpParticipantId, @NotNull String eventInfo, KitReasonType reason) {
final long initialInterval = 100; // base delay in milliseconds
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I increased the initial interval

*/
@Slf4j
@Getter
public class JuniperKitUtil extends BaseKitTestUtil {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This class has the config setup and what else that is only related to Juniper kits

@pegahtah pegahtah requested a review from zyme June 5, 2024 15:57
protected Integer kitDimensionId;
protected Integer kitReturnId;
protected Integer carrierId;
protected Integer ddpKitRequestSettingsId;
Copy link
Contributor

Choose a reason for hiding this comment

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

These don't need to be protected now that there's not a base class. I think they can all be private.

@pegahtah pegahtah merged commit 28f95a6 into develop Jun 6, 2024
8 checks passed
@pegahtah pegahtah deleted the PEPPER-1402_PEPPER-1397_trigger_ddp branch June 6, 2024 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: identifies or fixes a bug C-enhancement Category: code clean ups, refactors, or general enhancements C-feature Category: non-breaking change which adds new functionality dsm DDP Study Manager java Pull requests that update Java code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants