diff --git a/pepper-apis/ddp-common/pom.xml b/pepper-apis/ddp-common/pom.xml index 324f78b3bd..79a2478888 100644 --- a/pepper-apis/ddp-common/pom.xml +++ b/pepper-apis/ddp-common/pom.xml @@ -143,5 +143,11 @@ + + jakarta.validation + jakarta.validation-api + 2.0.2 + compile + diff --git a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/model/dsm/DsmNotificationEventType.java b/pepper-apis/ddp-common/src/main/java/org/broadinstitute/ddp/notficationevent/DsmNotificationEventType.java similarity index 97% rename from pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/model/dsm/DsmNotificationEventType.java rename to pepper-apis/ddp-common/src/main/java/org/broadinstitute/ddp/notficationevent/DsmNotificationEventType.java index 9fc1dee264..6d0215e7b3 100644 --- a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/model/dsm/DsmNotificationEventType.java +++ b/pepper-apis/ddp-common/src/main/java/org/broadinstitute/ddp/notficationevent/DsmNotificationEventType.java @@ -1,4 +1,4 @@ -package org.broadinstitute.ddp.model.dsm; +package org.broadinstitute.ddp.notficationevent; public enum DsmNotificationEventType { /** diff --git a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/json/dsm/DsmNotificationPayload.java b/pepper-apis/ddp-common/src/main/java/org/broadinstitute/ddp/notficationevent/DsmNotificationPayload.java similarity index 77% rename from pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/json/dsm/DsmNotificationPayload.java rename to pepper-apis/ddp-common/src/main/java/org/broadinstitute/ddp/notficationevent/DsmNotificationPayload.java index 508bb1d186..df80a2a701 100644 --- a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/json/dsm/DsmNotificationPayload.java +++ b/pepper-apis/ddp-common/src/main/java/org/broadinstitute/ddp/notficationevent/DsmNotificationPayload.java @@ -1,12 +1,10 @@ -package org.broadinstitute.ddp.json.dsm; +package org.broadinstitute.ddp.notficationevent; import java.util.Optional; import javax.validation.constraints.NotBlank; import com.google.gson.JsonElement; import com.google.gson.annotations.SerializedName; -import org.broadinstitute.ddp.model.dsm.DsmNotificationEventType; -import org.broadinstitute.ddp.model.dsm.KitReasonType; public class DsmNotificationPayload { @@ -39,6 +37,17 @@ public DsmNotificationPayload(String eventType, String kitRequestId, KitReasonTy this.kitReasonType = kitReasonType; } + /** + * Creates a new event to be sent to DSS. + * eventInfo could be ddpParticipantId for participant events, or ddpKitRequestId for kit events. + * **/ + public DsmNotificationPayload(String eventType, long eventDate, KitReasonType kitReasonType, String eventInfo) { + this.eventType = eventType; + this.eventDate = eventDate; + this.eventInfo = eventInfo; + this.kitReasonType = kitReasonType; + } + public String getEventType() { return eventType; } diff --git a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/model/dsm/KitReasonType.java b/pepper-apis/ddp-common/src/main/java/org/broadinstitute/ddp/notficationevent/KitReasonType.java similarity index 93% rename from pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/model/dsm/KitReasonType.java rename to pepper-apis/ddp-common/src/main/java/org/broadinstitute/ddp/notficationevent/KitReasonType.java index b186b9af03..a3db9ae3cb 100644 --- a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/model/dsm/KitReasonType.java +++ b/pepper-apis/ddp-common/src/main/java/org/broadinstitute/ddp/notficationevent/KitReasonType.java @@ -1,4 +1,4 @@ -package org.broadinstitute.ddp.model.dsm; +package org.broadinstitute.ddp.notficationevent; /** * The reason of a kit. What each reason means and how it affects workflow will depend on the study's configuration. diff --git a/pepper-apis/ddp-common/src/main/java/org/broadinstitute/ddp/util/LiquibaseUtil.java b/pepper-apis/ddp-common/src/main/java/org/broadinstitute/ddp/util/LiquibaseUtil.java index 99b000d60c..5755c54f43 100644 --- a/pepper-apis/ddp-common/src/main/java/org/broadinstitute/ddp/util/LiquibaseUtil.java +++ b/pepper-apis/ddp-common/src/main/java/org/broadinstitute/ddp/util/LiquibaseUtil.java @@ -10,7 +10,6 @@ import java.util.List; import com.typesafe.config.Config; - import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import liquibase.Contexts; diff --git a/pepper-apis/dsm-core/pom.xml b/pepper-apis/dsm-core/pom.xml index 15baa01e97..2ae8823d9e 100644 --- a/pepper-apis/dsm-core/pom.xml +++ b/pepper-apis/dsm-core/pom.xml @@ -249,6 +249,11 @@ 2.4.11 compile + + io.github.resilience4j + resilience4j-retry + 2.2.0 + diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/DSMServer.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/DSMServer.java index ba9c0536df..47632bca45 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/DSMServer.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/DSMServer.java @@ -98,10 +98,10 @@ import org.broadinstitute.dsm.route.NDIRoute; import org.broadinstitute.dsm.route.OncHistoryTemplateRoute; import org.broadinstitute.dsm.route.OncHistoryUploadRoute; -import org.broadinstitute.dsm.route.ParticipantEventRoute; import org.broadinstitute.dsm.route.ParticipantExitRoute; import org.broadinstitute.dsm.route.ParticipantStatusRoute; import org.broadinstitute.dsm.route.PatchRoute; +import org.broadinstitute.dsm.route.SkippedParticipantEventRoute; import org.broadinstitute.dsm.route.TriggerSomaticResultSurveyRoute; import org.broadinstitute.dsm.route.TriggerSurveyRoute; import org.broadinstitute.dsm.route.UserSettingRoute; @@ -136,13 +136,13 @@ import org.broadinstitute.dsm.route.tag.cohort.DeleteCohortTagRoute; import org.broadinstitute.dsm.route.util.JacksonResponseTransformer; import org.broadinstitute.dsm.security.Auth0Util; +import org.broadinstitute.dsm.service.EventService; import org.broadinstitute.dsm.service.FileDownloadService; import org.broadinstitute.dsm.service.SomaticResultUploadService; import org.broadinstitute.dsm.statics.ApplicationConfigConstants; import org.broadinstitute.dsm.statics.RequestParameter; import org.broadinstitute.dsm.statics.RoutePath; import org.broadinstitute.dsm.util.DSMConfig; -import org.broadinstitute.dsm.util.EventUtil; import org.broadinstitute.dsm.util.JWTRouteFilter; import org.broadinstitute.dsm.util.JavaHeapDumper; import org.broadinstitute.dsm.util.JsonNullTransformer; @@ -348,15 +348,17 @@ public static void createScheduleJob(@NonNull Scheduler scheduler, @NonNull Conf /** * Job to trigger ddp reminder emails and external shipper */ - public static void createScheduleJob(@NonNull Scheduler scheduler, EventUtil eventUtil, NotificationUtil notificationUtil, + public static void createScheduleJob(@NonNull Scheduler scheduler, EventService eventService, NotificationUtil notificationUtil, @NonNull Class jobClass, @NonNull String identity, @NonNull String cronExpression, @NonNull BasicTriggerListener basicTriggerListener) throws SchedulerException { //create job JobDetail job = JobBuilder.newJob(jobClass).withIdentity(identity, BasicTriggerListener.NO_CONCURRENCY_GROUP).build(); - if (eventUtil != null) { + if (eventService != null) { //pass parameters to JobDataMap for JobDetail - job.getJobDataMap().put(EVENT_UTIL, eventUtil); + job.getJobDataMap().put(EVENT_UTIL, eventService); + } else { + logger.error("EventService is null, some jobs might not work properly"); } if (notificationUtil != null) { //pass parameters to JobDataMap for JobDetail @@ -686,8 +688,8 @@ protected void setupCustomRouting(@NonNull Config cfg) { //no GET for USER_SETTINGS_REQUEST because UI gets them per AuthenticationRoute patch(UI_ROOT + RoutePath.USER_SETTINGS_REQUEST, new UserSettingRoute(), new GsonResponseTransformer()); - EventUtil eventUtil = new EventUtil(); - scheduler = setupJobs(cfg, kitUtil, notificationUtil, eventUtil); + EventService eventService = new EventService(); + scheduler = setupJobs(cfg, kitUtil, notificationUtil, eventService); //TODO - redo with pubsub JavaHeapDumper heapDumper = new JavaHeapDumper(); @@ -868,10 +870,10 @@ private void setupMiscellaneousRoutes() { get(UI_ROOT + RoutePath.EVENT_TYPES + RoutePath.ROUTE_SEPARATOR + RequestParameter.REALM, new EventTypeRoute(), new GsonResponseTransformer()); - ParticipantEventRoute participantEventRoute = new ParticipantEventRoute(); - get(UI_ROOT + RoutePath.PARTICIPANT_EVENTS + RoutePath.ROUTE_SEPARATOR + RequestParameter.REALM, participantEventRoute, + SkippedParticipantEventRoute skippedParticipantEventRoute = new SkippedParticipantEventRoute(); + get(UI_ROOT + RoutePath.PARTICIPANT_EVENTS + RoutePath.ROUTE_SEPARATOR + RequestParameter.REALM, skippedParticipantEventRoute, new GsonResponseTransformer()); - post(UI_ROOT + RoutePath.SKIP_PARTICIPANT_EVENTS, participantEventRoute, new GsonResponseTransformer()); + post(UI_ROOT + RoutePath.SKIP_PARTICIPANT_EVENTS, skippedParticipantEventRoute, new GsonResponseTransformer()); post(UI_ROOT + RoutePath.NDI_REQUEST, new NDIRoute(), new GsonResponseTransformer()); @@ -976,7 +978,7 @@ private void setupPubSubPublisherRoutes(Config config) { } private Scheduler setupJobs(@NonNull Config cfg, @NonNull KitUtil kitUtil, @NonNull NotificationUtil notificationUtil, - @NonNull EventUtil eventUtil) { + @NonNull EventService eventService) { String schedulerName = null; Scheduler scheduler = null; if (cfg.getBoolean(ApplicationConfigConstants.QUARTZ_ENABLE_JOBS)) { @@ -997,7 +999,7 @@ private Scheduler setupJobs(@NonNull Config cfg, @NonNull KitUtil kitUtil, @NonN createScheduleJob(scheduler, cfg, notificationUtil, kitUtil, GPNotificationJob.class, "GP_SCHEDULE_JOB", cfg.getString(ApplicationConfigConstants.EMAIL_CRON_EXPRESSION_FOR_GP_NOTIFICATION)); - createScheduleJob(scheduler, eventUtil, notificationUtil, DDPEventJob.class, "TRIGGER_DDP_EVENT", + createScheduleJob(scheduler, eventService, notificationUtil, DDPEventJob.class, "TRIGGER_DDP_EVENT", cfg.getString(ApplicationConfigConstants.QUARTZ_CRON_EXPRESSION_FOR_DDP_EVENT_TRIGGER), new DDPEventTriggerListener()); diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/DDPInstance.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/DDPInstance.java index 89fdda2f42..00d5add437 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/DDPInstance.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/DDPInstance.java @@ -154,7 +154,7 @@ public DDPInstance(int ddpInstanceId, String name) { public static DDPInstance getDDPInstance(@NonNull String realm) { SimpleResult results = inTransaction((conn) -> { SimpleResult dbVals = new SimpleResult(); - try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_ALL_ACTIVE_REALMS + QueryExtension.BY_INSTANCE_NAME)) { + try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_ALL_ACTIVE_REALMS.concat(QueryExtension.BY_INSTANCE_NAME))) { stmt.setString(1, realm); try (ResultSet rs = stmt.executeQuery()) { if (rs.next()) { @@ -178,7 +178,7 @@ public static DDPInstance getDDPInstance(@NonNull String realm) { public static DDPInstance getDDPInstanceByGuid(@NonNull String studyGuid) { SimpleResult results = inTransaction(conn -> { SimpleResult dbVals = new SimpleResult(); - try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_ALL_ACTIVE_REALMS + QueryExtension.BY_STUDY_GUID)) { + try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_ALL_ACTIVE_REALMS.concat(QueryExtension.BY_STUDY_GUID))) { stmt.setString(1, studyGuid); try (ResultSet rs = stmt.executeQuery()) { if (rs.next()) { @@ -200,7 +200,7 @@ public static DDPInstance getDDPInstanceByGuid(@NonNull String studyGuid) { public static DDPInstance getDDPInstanceById(@NonNull Integer ddpInstanceId) { SimpleResult results = inTransaction((conn) -> { SimpleResult dbVals = new SimpleResult(); - try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_ALL_ACTIVE_REALMS + QueryExtension.BY_INSTANCE_ID)) { + try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_ALL_ACTIVE_REALMS.concat(QueryExtension.BY_INSTANCE_ID))) { stmt.setInt(1, ddpInstanceId); try (ResultSet rs = stmt.executeQuery()) { if (rs.next()) { @@ -258,7 +258,7 @@ public static DDPInstance getDDPInstanceWithRole(@NonNull String realm, @NonNull // and by Covid19OrderRegistrar public static DDPInstance getDDPInstanceWithRole(@NonNull String realm, @NonNull String role, Connection conn) { SimpleResult dbVals = new SimpleResult(); - try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_INSTANCE_WITH_ROLE + QueryExtension.BY_INSTANCE_NAME)) { + try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_INSTANCE_WITH_ROLE.concat(QueryExtension.BY_INSTANCE_NAME))) { stmt.setString(1, role); stmt.setString(2, realm); try (ResultSet rs = stmt.executeQuery()) { @@ -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))) { stmt.setString(1, role); stmt.setString(2, studyGuid); try (ResultSet rs = stmt.executeQuery()) { @@ -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) { - SimpleResult results = inTransaction((conn) -> { - SimpleResult dbVals = new SimpleResult(); - try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_INSTANCE_WITH_ROLE + QueryExtension.BY_INSTANCE_NAME)) { - stmt.setString(1, role); - stmt.setString(2, realm); - try (ResultSet rs = stmt.executeQuery()) { - if (rs.next()) { - dbVals.resultValue = rs.getBoolean(DBConstants.HAS_ROLE); - } - } catch (SQLException e) { - throw new RuntimeException("Error getting role of realm " + realm, e); - } - } catch (SQLException ex) { - dbVals.resultException = ex; - } - return dbVals; - }); - - if (results.resultException != null) { - throw new RuntimeException("Couldn't get role of realm " + realm, results.resultException); - } - return (boolean) results.resultValue; - } - public static DDPInstance getDDPInstanceWithRoleFormResultSet(@NonNull ResultSet rs) throws SQLException { String notificationRecipient = rs.getString(DBConstants.NOTIFICATION_RECIPIENT); List recipients = null; @@ -536,8 +511,9 @@ public static DDPInstance from(DDPInstanceDto ddpInstanceDto) { .withCollaboratorIdPrefix(ddpInstanceDto.getCollaboratorIdPrefix()) .withDaysMrAttentionNeeded(ddpInstanceDto.getMrAttentionFlagD()) .withDaysTissueAttentionNeeded(ddpInstanceDto.getTissueAttentionFlagD()) - .withHasAuth0Token(ddpInstanceDto.getAuth0Token() != null) - .withNotificationRecipient(ddpInstanceDto.getNotificationRecipients()) + .withHasAuth0Token(ddpInstanceDto.getAuth0Token() != null && ddpInstanceDto.getAuth0Token()) + .withNotificationRecipient(ddpInstanceDto.getNotificationRecipients().isEmpty() + ? null : ddpInstanceDto.getNotificationRecipients()) .withBillingReference(ddpInstanceDto.getBillingReference()) .withParticipantIndexES(ddpInstanceDto.getEsParticipantIndex()) .withActivityDefinitionIndexES(ddpInstanceDto.getEsActivityDefinitionIndex()) diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/KitRequestShipping.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/KitRequestShipping.java index 8330e9c358..9013a31c06 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/KitRequestShipping.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/KitRequestShipping.java @@ -203,7 +203,7 @@ public class KitRequestShipping extends KitRequest implements HasDdpInstanceId { private static final String ERROR = "error"; private static final String SENT = "sent"; private static final String RECEIVED = "received"; - private static final String OVERVIEW = "overview"; + public static final String OVERVIEW = "overview"; private static final String DEACTIVATED = "deactivated"; private static final String TRIGGERED = "triggered"; private static final String WAITING = "waiting"; diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/ParticipantEvent.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/SkippedParticipantEventDao.java similarity index 68% rename from pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/ParticipantEvent.java rename to pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/SkippedParticipantEventDao.java index 81478e4881..64d0d8d2c9 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/ParticipantEvent.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/SkippedParticipantEventDao.java @@ -1,8 +1,7 @@ -package org.broadinstitute.dsm.db; +package org.broadinstitute.dsm.db.dao; import static org.broadinstitute.ddp.db.TransactionWrapper.inTransaction; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; @@ -10,6 +9,8 @@ import lombok.Data; import lombok.NonNull; +import org.broadinstitute.dsm.db.DDPInstance; +import org.broadinstitute.dsm.db.dto.queue.SkippedParticipantEventDto; import org.broadinstitute.dsm.model.ddp.DDPParticipant; import org.broadinstitute.dsm.statics.ApplicationConfigConstants; import org.broadinstitute.dsm.statics.DBConstants; @@ -20,28 +21,20 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +/** + * When a participant no longer wants to get emails or reminders about their kits, they ask the study's CRC, and they enter + * the participant's ID and the event type into the DSM, which is stored in the ddp_participant_event table. + * */ @Data -public class ParticipantEvent { +public class SkippedParticipantEventDao { - private static final Logger logger = LoggerFactory.getLogger(ParticipantEvent.class); + private static final Logger logger = LoggerFactory.getLogger(SkippedParticipantEventDao.class); private static String GET_PARTICIPANT_EVENT = "select event from ddp_participant_event ev where ev.ddp_instance_id = ? " + "and ev.ddp_participant_id = ?"; - private final String participantId; - private final String eventType; - private final String user; - private final long date; - private String shortId; - public ParticipantEvent(String participantId, String eventType, String user, long date) { - this.participantId = participantId; - this.eventType = eventType; - this.user = user; - this.date = date; - } - - public static Collection getSkippedParticipantEvents(@NonNull String realm) { - ArrayList skippedParticipantEvents = new ArrayList(); + public Collection getSkippedParticipantEvents(@NonNull String realm) { + ArrayList skippedParticipantEvents = new ArrayList(); SimpleResult results = inTransaction((conn) -> { SimpleResult dbVals = new SimpleResult(); try (PreparedStatement stmt = conn.prepareStatement( @@ -50,8 +43,8 @@ public static Collection getSkippedParticipantEvents(@NonNull try (ResultSet rs = stmt.executeQuery()) { while (rs.next()) { skippedParticipantEvents.add( - new ParticipantEvent(rs.getString(DBConstants.DDP_PARTICIPANT_ID), rs.getString(DBConstants.EVENT), - rs.getString(DBConstants.NAME), rs.getLong(DBConstants.DATE))); + new SkippedParticipantEventDto(rs.getString(DBConstants.DDP_PARTICIPANT_ID), + rs.getString(DBConstants.EVENT), rs.getString(DBConstants.NAME), rs.getLong(DBConstants.DATE))); } } } catch (Exception ex) { @@ -64,7 +57,7 @@ public static Collection getSkippedParticipantEvents(@NonNull logger.error("Couldn't get list of skipped participant events for " + realm, results.resultException); } else { DDPInstance instance = DDPInstance.getDDPInstance(realm); - for (ParticipantEvent skippedParticipant : skippedParticipantEvents) { + for (SkippedParticipantEventDto skippedParticipant : skippedParticipantEvents) { String sendRequest = instance.getBaseUrl() + RoutePath.DDP_PARTICIPANTS_PATH + "/" + skippedParticipant.getParticipantId(); try { DDPParticipant ddpParticipant = @@ -80,7 +73,36 @@ public static Collection getSkippedParticipantEvents(@NonNull return skippedParticipantEvents; } - public static void skipParticipantEvent(@NonNull String ddpParticipantId, @NonNull long currentTime, @NonNull String userId, + public Collection getSkippedParticipantEvents(@NonNull String ddpParticipantId, int instanceId) { + ArrayList skippedEvents = new ArrayList(); + SimpleResult result = inTransaction((conn) -> { + SimpleResult dbVals = new SimpleResult(); + try (PreparedStatement stmt = conn.prepareStatement(GET_PARTICIPANT_EVENT)) { + stmt.setInt(1, instanceId); + stmt.setString(2, ddpParticipantId); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + skippedEvents.add(rs.getString(DBConstants.EVENT)); + } + } + } catch (Exception ex) { + dbVals.resultException = ex; + } + return dbVals; + }); + if (result.resultException != null) { + logger.error("Couldn't get skipped participant events for " + instanceId, result.resultException); + } + return skippedEvents; + } + + public boolean isParticipantEventSkipped(@NonNull String ddpParticipantId, @NonNull String eventType, + int ddpInstanceId) { + Collection skippedParticipantEvents = getSkippedParticipantEvents(ddpParticipantId, ddpInstanceId); + return skippedParticipantEvents.contains(eventType); + } + + public void skipParticipantEvent(@NonNull String ddpParticipantId, @NonNull long currentTime, @NonNull String userId, @NonNull DDPInstance instance, @NonNull String eventType) { SimpleResult results = inTransaction((conn) -> { SimpleResult dbVals = new SimpleResult(); @@ -108,45 +130,4 @@ public static void skipParticipantEvent(@NonNull String ddpParticipantId, @NonNu logger.error("Couldn't skip event for participant w/ ddpParticipantId " + ddpParticipantId, results.resultException); } } - - public static Collection getParticipantEvent(@NonNull String ddpParticipantId, @NonNull String instanceId) { - ArrayList skippedEvents = new ArrayList(); - SimpleResult results = inTransaction((conn) -> { - SimpleResult dbVals = new SimpleResult(); - try (PreparedStatement stmt = conn.prepareStatement(GET_PARTICIPANT_EVENT)) { - stmt.setString(1, instanceId); - stmt.setString(2, ddpParticipantId); - try (ResultSet rs = stmt.executeQuery()) { - while (rs.next()) { - skippedEvents.add(rs.getString(DBConstants.EVENT)); - } - } - } catch (Exception ex) { - dbVals.resultException = ex; - } - return dbVals; - }); - - if (results.resultException != null) { - logger.error("Couldn't exited participants for " + instanceId, results.resultException); - } - return skippedEvents; - } - - public static Collection getParticipantEvent(Connection conn, @NonNull String ddpParticipantId, @NonNull String instanceId) { - ArrayList skippedEvents = new ArrayList(); - try (PreparedStatement stmt = conn.prepareStatement(GET_PARTICIPANT_EVENT)) { - stmt.setString(1, instanceId); - stmt.setString(2, ddpParticipantId); - try (ResultSet rs = stmt.executeQuery()) { - while (rs.next()) { - skippedEvents.add(rs.getString(DBConstants.EVENT)); - } - } - } catch (Exception ex) { - logger.error("Couldn't get exited participants for " + instanceId, ex); - } - - return skippedEvents; - } } diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/kit/BSPKitDao.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/kit/BSPKitDao.java index 1659d5e3f9..e6924ed88f 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/kit/BSPKitDao.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/kit/BSPKitDao.java @@ -23,7 +23,7 @@ public class BSPKitDao implements Dao { + "FROM ddp_kit GROUP BY dsm_kit_request_id) groupedKit ON kit.dsm_kit_request_id = groupedKit.dsm_kit_request_id " + "AND kit.dsm_kit_id = groupedKit.kit_id SET receive_date = ?, receive_by = ? " + "WHERE kit.receive_date IS NULL AND kit.kit_label = ?"; - private final String SQL_SELECT_METADATA_FOR_KIT = + private static final String SQL_SELECT_METADATA_FOR_KIT = "select realm.instance_name, realm.base_url, request.bsp_collaborator_sample_id, collection_date, " + "request.bsp_collaborator_participant_id, realm.bsp_group, realm.bsp_collection, " + "realm.bsp_organism, realm.notification_recipients, request.ddp_participant_id, " @@ -94,8 +94,8 @@ public Optional getBSPKitQueryResult(@NonNull String kitLabel) { } public void setKitReceivedAndTriggerDDP(String kitLabel, boolean triggerDDP, BSPKitDto bspKitDto, String receiver) { - TransactionWrapper.inTransaction(conn -> { - boolean firstTimeReceived = false; + boolean firstTimeReceived = TransactionWrapper.inTransaction(conn -> { + boolean firstTime = false; try (PreparedStatement stmt = conn.prepareStatement(sqlUpdateKitReceived)) { stmt.setLong(1, System.currentTimeMillis()); stmt.setString(2, receiver); @@ -104,16 +104,15 @@ public void setKitReceivedAndTriggerDDP(String kitLabel, boolean triggerDDP, BSP if (result > 1) { // 1 row or 0 row updated is perfect throw new DsmInternalError("Error updating kit w/label " + kitLabel + " (updated " + result + " rows)"); } - firstTimeReceived = result == 1; + firstTime = result == 1; } catch (Exception e) { logger.error("Failed to set kit w/ label " + kitLabel + " as received ", e); } - if (triggerDDP) { - BSPKit bspKit = new BSPKit(); - // TODO: this should not be in a DB transaction since it makes a call to an external service -DC - bspKit.triggerDDP(conn, bspKitDto, firstTimeReceived, kitLabel); - } - return firstTimeReceived; + return firstTime; }); + if (triggerDDP) { + BSPKit bspKit = new BSPKit(); + bspKit.triggerDDP(bspKitDto, firstTimeReceived, kitLabel); + } } } diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/kit/ClinicalKitDao.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/kit/ClinicalKitDao.java index 9cfa896312..a073759cb6 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/kit/ClinicalKitDao.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/kit/ClinicalKitDao.java @@ -8,6 +8,7 @@ import java.util.NoSuchElementException; import java.util.Optional; +import com.google.common.annotations.VisibleForTesting; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.broadinstitute.dsm.db.DDPInstance; @@ -16,14 +17,16 @@ import org.broadinstitute.dsm.db.dto.kit.ClinicalKitDto; import org.broadinstitute.dsm.db.dto.settings.EventTypeDto; import org.broadinstitute.dsm.model.gp.ClinicalKitWrapper; +import org.broadinstitute.dsm.service.EventService; import org.broadinstitute.dsm.statics.DBConstants; -import org.broadinstitute.dsm.util.EventUtil; import org.broadinstitute.lddp.db.SimpleResult; @Slf4j public class ClinicalKitDao { public static final String PECGS = "PE-CGS"; public static final String MERCURY = "MERCURY"; + final EventDao eventDao = new EventDao(); + final EventTypeDao eventTypeDao = new EventTypeDao(); private static final String SQL_GET_CLINICAL_KIT_BASED_ON_SM_ID_VALUE = "SELECT p.ddp_participant_id, accession_number, ddp.instance_name, t.collaborator_sample_id, date_px, " + "kit_type_name, bsp_material_type, bsp_receptacle_type, ddp.ddp_instance_id FROM sm_id sm " @@ -135,7 +138,7 @@ private void setAccessionTimeForSMID(String smIdValue) { } } - public static void ifTissueAccessionedTriggerDDP(String ddpParticipantId, DDPInstance ddpInstance) { + public void triggerRequiredSamplesReceivedEvent(String ddpParticipantId, DDPInstance ddpInstance) { if (hasTissueAccessioned(ddpParticipantId, ddpInstance)) { triggerParticipantEvent(ddpInstance, ddpParticipantId, DBConstants.REQUIRED_SAMPLES_RECEIVED_EVENT); } @@ -192,19 +195,16 @@ public boolean hasKitsAccessioned(String ddpParticipantId, DDPInstance ddpInstan return false; } - private static void triggerParticipantEvent(DDPInstance ddpInstance, String ddpParticipantId, String eventName) { - final EventDao eventDao = new EventDao(); - final EventTypeDao eventTypeDao = new EventTypeDao(); + @VisibleForTesting + public void triggerParticipantEvent(DDPInstance ddpInstance, String ddpParticipantId, String eventName) { Optional eventType = eventTypeDao.getEventTypeByEventNameAndInstanceId(eventName, ddpInstance.getDdpInstanceId()); eventType.ifPresent(eventTypeDto -> { boolean participantHasTriggeredEventByEventType = - eventDao.hasTriggeredEventByEventTypeAndDdpParticipantId(eventName, ddpParticipantId).orElse(false); + eventDao.isEventTriggeredForParticipant(eventName, ddpParticipantId); if (!participantHasTriggeredEventByEventType) { - inTransaction((conn) -> { - EventUtil.triggerDDP(conn, eventType, ddpParticipantId); - return null; - }); + String type = eventTypeDto.getEventName(); + EventService.sendParticipantEventToDss(type, ddpInstance, ddpParticipantId); } else { log.info("Participant " + ddpParticipantId + " was already triggered for event type " + eventName); } diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/kit/KitDao.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/kit/KitDao.java index 0f08053b5d..fc05815fb3 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/kit/KitDao.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/kit/KitDao.java @@ -35,7 +35,7 @@ public class KitDao { + " ddp_site.base_url, ddp_site.auth0_token, ddp_site.billing_reference, " + "ddp_site.migrated_ddp, ddp_site.collaborator_id_prefix, ddp_site.es_participant_index, " + "req.bsp_collaborator_participant_id, req.bsp_collaborator_sample_id, req.ddp_participant_id, req.ddp_label, " - + "req.dsm_kit_request_id, " + + "req.dsm_kit_request_id, req.ddp_kit_request_id," + "req.kit_type_id, req.external_order_status, req.external_order_number, req.external_order_date, " + "req.external_response, kt.no_return, req.created_by FROM kit_type kt, ddp_kit_request req, ddp_instance ddp_site " + "WHERE req.ddp_instance_id = ddp_site.ddp_instance_id AND req.kit_type_id = kt.kit_type_id) AS request " @@ -194,7 +194,7 @@ public Boolean hasTrackingScan(String kitLabel) { */ public Optional updateKitScanInfo(KitRequestShipping kitRequestShipping, String userId) { Optional result = Optional.empty(); - SimpleResult results = inTransaction((conn) -> { + SimpleResult results = inTransaction(conn -> { SimpleResult dbVals = new SimpleResult(); // check to make sure the kit request for the label exists @@ -290,7 +290,7 @@ public Optional updateKitScanInfo(KitRequestShipping kitRequestShipp public Optional updateKitReceived(KitRequestShipping kitRequestShipping, String userId) { Optional result = Optional.empty(); - SimpleResult results = inTransaction((conn) -> { + SimpleResult results = inTransaction(conn -> { SimpleResult dbVals = new SimpleResult(); try (PreparedStatement stmt = conn.prepareStatement(UPDATE_KIT_RECEIVED)) { stmt.setLong(1, System.currentTimeMillis()); @@ -316,7 +316,7 @@ public Optional updateKitReceived(KitRequestShipping kitRequestShipp } public Integer insertKit(KitRequestShipping kitRequestShipping) { - SimpleResult results = inTransaction((conn) -> { + SimpleResult results = inTransaction(conn -> { SimpleResult dbVals = new SimpleResult(); try (PreparedStatement stmt = conn.prepareStatement(INSERT_KIT, Statement.RETURN_GENERATED_KEYS)) { stmt.setLong(1, kitRequestShipping.getDsmKitRequestId()); @@ -351,7 +351,7 @@ public Integer insertKit(KitRequestShipping kitRequestShipping) { } public Integer insertKitRequest(KitRequestShipping kitRequestShipping) { - SimpleResult results = inTransaction((conn) -> { + SimpleResult results = inTransaction(conn -> { SimpleResult dbVals = new SimpleResult(); try (PreparedStatement stmt = conn.prepareStatement(INSERT_KIT_REQUEST, Statement.RETURN_GENERATED_KEYS)) { stmt.setLong(1, kitRequestShipping.getDdpInstanceId()); @@ -384,7 +384,7 @@ public Integer insertKitRequest(KitRequestShipping kitRequestShipping) { } public static Optional getKitRequest(int kitRequestId) { - SimpleResult results = inTransaction((conn) -> { + SimpleResult results = inTransaction(conn -> { SimpleResult dbVals = new SimpleResult(); try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_KIT_REQUEST + KIT_BY_KIT_REQUEST_ID)) { stmt.setInt(1, kitRequestId); @@ -412,7 +412,7 @@ public static Optional getKitRequest(int kitRequestId) { } public Optional getKit(Long kitId) { - SimpleResult results = inTransaction((conn) -> { + SimpleResult results = inTransaction(conn -> { SimpleResult dbVals = new SimpleResult(); try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_KIT_REQUEST + KIT_BY_KIT_ID)) { stmt.setLong(1, kitId); @@ -480,7 +480,7 @@ private int deleteKit(Connection conn, int kitId) throws SQLException { } public Optional getKitByDdpLabel(String ddpLabel, String kitLabel) { - SimpleResult results = inTransaction((conn) -> { + SimpleResult results = inTransaction(conn -> { SimpleResult dbVals = new SimpleResult(); try (PreparedStatement stmt = conn.prepareStatement(SQL_GET_KIT_BY_DDP_LABEL)) { stmt.setString(1, kitLabel); @@ -525,7 +525,7 @@ public Optional getKitByDdpLabel(String ddpLabel, String kit public Optional> getSubkitsByDdpLabel(String ddpLabel, String kitLabel) { List subkits = new ArrayList<>(); - SimpleResult results = inTransaction((conn) -> { + SimpleResult results = inTransaction(conn -> { SimpleResult dbVals = new SimpleResult(); String subKitDDpLabel = ddpLabel.concat("\\_%"); try (PreparedStatement stmt = conn.prepareStatement(SQL_GET_SUB_KIT_BY_DDP_LABEL)) { @@ -610,6 +610,9 @@ public static KitRequestShipping getKitRequestShipping(@NonNull ResultSet rs) th } } + if (DBUtil.columnExists(rs, DBConstants.DDP_KIT_REQUEST_ID)) { + kitRequestShipping.setDdpKitRequestId(rs.getString(DBConstants.DDP_KIT_REQUEST_ID)); + } return kitRequestShipping; } @@ -688,7 +691,7 @@ private Optional insertKitTrackingIfNotExists(KitRequestShipping kit } private boolean booleanCheckFoundAsName(String kitLabel, String query) { - SimpleResult results = inTransaction((conn) -> { + SimpleResult results = inTransaction(conn -> { SimpleResult dbVals = new SimpleResult(0); try (PreparedStatement stmt = conn.prepareStatement(query)) { stmt.setString(1, kitLabel); @@ -716,7 +719,7 @@ private boolean booleanCheckFoundAsName(String kitLabel, String query) { public List getKitsByHruid(String hruid) { List kitRequestList = new ArrayList<>(); - inTransaction((conn) -> { + inTransaction(conn -> { SimpleResult dbVals = new SimpleResult(); try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_KIT_REQUEST + KIT_BY_HRUID)) { stmt.setString(1, "%" + hruid + "%"); diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/queue/EventDao.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/queue/EventDao.java index 8c291052d0..5793268ca4 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/queue/EventDao.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/queue/EventDao.java @@ -5,44 +5,81 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; import java.util.Optional; import com.sun.istack.NotNull; import lombok.NonNull; +import org.apache.commons.lang3.NotImplementedException; +import org.apache.commons.lang3.StringUtils; import org.broadinstitute.dsm.db.dao.Dao; import org.broadinstitute.dsm.db.dto.queue.EventDto; +import org.broadinstitute.dsm.exception.DsmInternalError; +import org.broadinstitute.dsm.model.KitDDPNotification; +import org.broadinstitute.dsm.statics.DBConstants; import org.broadinstitute.lddp.db.SimpleResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class EventDao implements Dao { - - public static final String EVENT_TYPE = "EVENT_TYPE"; private static final Logger logger = LoggerFactory.getLogger(EventDao.class); - private static String GET_TRIGGERED_EVENT_QUEUE_BY_EVENT_TYPE_AND_DDP_PARTICIPANT_ID = "SELECT " - + "EVENT_ID, EVENT_DATE_CREATED, EVENT_TYPE, DDP_INSTANCE_ID, DSM_KIT_REQUEST_ID, DDP_PARTICIPANT_ID, EVENT_TRIGGERED " - + "FROM EVENT_QUEUE " + "WHERE EVENT_TYPE = ? AND DDP_PARTICIPANT_ID = ? AND EVENT_TRIGGERED = 1"; + private static String GET_EVENT_QUEUE_BY_EVENT_TYPE_AND_DDP_PARTICIPANT_ID = "SELECT " + + "event_id, event_date_created, event_type, ddp_instance_id, dsm_kit_request_id, ddp_participant_id, event_triggered " + + "FROM EVENT_QUEUE " + "WHERE event_type = ? and ddp_participant_id = ? "; + + private static String SQL_BY_TRIGGER_TRUE_CONDITION = "AND event_triggered = 1"; + + private static String GET_EVENT_BY_EVENT_TYPE_AND_KIT_REQUEST_ID = "SELECT " + + "event_id, event_date_created, event_type, ddp_instance_id, dsm_kit_request_id, ddp_participant_id, event_triggered " + + "FROM EVENT_QUEUE " + "WHERE event_type = ? AND dsm_kit_request_id = ?"; + + private static final String SQL_INSERT_EVENT = + "INSERT INTO EVENT_QUEUE SET event_date_created = ?, event_type = ?, ddp_instance_id = ?, " + + "ddp_participant_id = ?, dsm_kit_request_id = ?, event_triggered = ?"; + + public static final String SQL_SELECT_KIT_FOR_REMINDER_EMAILS = + "SELECT eve.event_name, eve.event_type, request.ddp_participant_id, request.dsm_kit_request_id, realm.instance_name, " + + "realm.base_url, " + + "realm.ddp_instance_id, realm.auth0_token, realm.notification_recipients, kit.receive_date, kit.scan_date, " + + "request.upload_reason, request.ddp_kit_request_id, " + + "(SELECT count(role.name) FROM ddp_instance realm2, ddp_instance_role inRol, instance_role role " + + "WHERE realm2.ddp_instance_id = inRol.ddp_instance_id AND inRol.instance_role_id = role.instance_role_id " + + "AND role.name = ? AND realm2.ddp_instance_id = realm.ddp_instance_id) AS 'has_role' " + + "FROM ddp_kit_request request LEFT JOIN ddp_kit kit ON (kit.dsm_kit_request_id = request.dsm_kit_request_id) " + + "LEFT JOIN ddp_instance realm ON (request.ddp_instance_id = realm.ddp_instance_id) " + + "LEFT JOIN ddp_participant_exit ex ON (ex.ddp_participant_id = request.ddp_participant_id " + + "AND ex.ddp_instance_id = request.ddp_instance_id) " + + "LEFT JOIN event_type eve ON (eve.ddp_instance_id = request.ddp_instance_id " + + "AND eve.kit_type_id = request.kit_type_id " + + "AND eve.event_type = 'REMINDER') " + + "LEFT JOIN EVENT_QUEUE queue ON (queue.DSM_KIT_REQUEST_ID = request.dsm_kit_request_id " + + "AND queue.EVENT_TYPE = eve.event_name) " + + "WHERE ex.ddp_participant_exit_id IS NULL AND kit.scan_date IS NOT NULL " + + "AND kit.scan_date <= (UNIX_TIMESTAMP(NOW())-(eve.hours*60*60))*1000 " + + "AND kit.receive_date IS NULL AND kit.deactivated_date IS NULL AND realm.is_active = 1 AND queue.EVENT_TYPE IS NULL"; + @Override public int create(EventDto eventDto) { - return 0; + throw new NotImplementedException("Not implemented, use insertEvent method instead"); } @Override public int delete(int id) { - return 0; + throw new NotImplementedException("Not implemented"); } @Override public Optional get(long id) { - return Optional.empty(); + throw new NotImplementedException("Not implemented"); } - public Optional hasTriggeredEventByEventTypeAndDdpParticipantId(@NotNull String eventType, @NonNull String ddpParticipantId) { + public boolean isEventTriggeredForParticipant(@NotNull String eventType, @NonNull String ddpParticipantId) { SimpleResult results = inTransaction((conn) -> { SimpleResult dbVals = new SimpleResult(); - try (PreparedStatement stmt = conn.prepareStatement(GET_TRIGGERED_EVENT_QUEUE_BY_EVENT_TYPE_AND_DDP_PARTICIPANT_ID, - ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY)) { + try (PreparedStatement stmt = conn.prepareStatement(GET_EVENT_QUEUE_BY_EVENT_TYPE_AND_DDP_PARTICIPANT_ID + .concat(SQL_BY_TRIGGER_TRUE_CONDITION), ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY)) { stmt.setString(1, eventType); stmt.setString(2, ddpParticipantId); try (ResultSet rs = stmt.executeQuery()) { @@ -50,6 +87,8 @@ public Optional hasTriggeredEventByEventTypeAndDdpParticipantId(@NotNul int count = rs.getRow(); if (count > 0) { dbVals.resultValue = true; + } else { + dbVals.resultValue = false; } } } catch (SQLException ex) { @@ -61,6 +100,163 @@ public Optional hasTriggeredEventByEventTypeAndDdpParticipantId(@NotNul if (results.resultException != null) { logger.error("Couldn't get triggered event for participant " + ddpParticipantId, results.resultException); } - return Optional.ofNullable((Boolean) results.resultValue); + return (boolean) results.resultValue; + } + + public Optional getEventForKit(@NotNull String eventType, @NonNull int dsmKitRequestId) { + SimpleResult results = inTransaction((conn) -> { + SimpleResult dbVals = new SimpleResult(); + try (PreparedStatement stmt = conn.prepareStatement(GET_EVENT_BY_EVENT_TYPE_AND_KIT_REQUEST_ID, + ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY)) { + stmt.setString(1, eventType); + stmt.setInt(2, dsmKitRequestId); + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + dbVals.resultValue = new EventDto.Builder(rs.getInt(DBConstants.DDP_INSTANCE_ID)) + .withEventId(rs.getInt(DBConstants.EVENT_ID)) + .withEventDateCreated(rs.getLong(DBConstants.EVENT_DATE_CREATED)) + .withEventType(rs.getString(DBConstants.EVENT_TYPE)) + .withDsmKitRequestId(rs.getInt(DBConstants.DSM_KIT_REQUEST_ID)) + .withDdpParticipantId(rs.getString(DBConstants.DDP_PARTICIPANT_ID)) + .withEventTriggered(rs.getBoolean(DBConstants.EVENT_TRIGGERED)).build(); + } + if (rs.next()) { + // multiple events found, this should not happen. Putting a log here to track this down + logger.error("Multiple events found for kit with dsmKitRequestId %d and event type %s" + .formatted(dsmKitRequestId, eventType)); + } + } + } catch (SQLException ex) { + dbVals.resultException = ex; + } + return dbVals; + }); + + if (results.resultException != null) { + logger.error("Couldn't get event for kit with dsmKitRequestId " + dsmKitRequestId, results.resultException); + } + return Optional.ofNullable((EventDto) results.resultValue); + } + + public Optional getEventForParticipant(@NotNull String eventType, @NonNull String ddpParticipantId) { + SimpleResult results = inTransaction((conn) -> { + SimpleResult dbVals = new SimpleResult(); + try (PreparedStatement stmt = conn.prepareStatement(GET_EVENT_QUEUE_BY_EVENT_TYPE_AND_DDP_PARTICIPANT_ID, + ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY)) { + stmt.setString(1, eventType); + stmt.setString(2, ddpParticipantId); + try (ResultSet rs = stmt.executeQuery()) { + if (rs.next()) { + dbVals.resultValue = new EventDto.Builder(rs.getInt(DBConstants.DDP_INSTANCE_ID)) + .withEventId(rs.getInt(DBConstants.EVENT_ID)) + .withEventDateCreated(rs.getLong(DBConstants.EVENT_DATE_CREATED)) + .withEventType(rs.getString(DBConstants.EVENT_TYPE)) + .withDsmKitRequestId(rs.getInt(DBConstants.DSM_KIT_REQUEST_ID)) + .withDdpParticipantId(rs.getString(DBConstants.DDP_PARTICIPANT_ID)) + .withEventTriggered(rs.getBoolean(DBConstants.EVENT_TRIGGERED)).build(); + } + if (rs.next()) { + // multiple events found, this should not happen. Putting a log here to track this down + logger.error("Multiple events found for participant with ddpParticipantId %s and event type %s" + .formatted(ddpParticipantId, eventType)); + } + } + } catch (SQLException ex) { + dbVals.resultException = ex; + } + return dbVals; + }); + + if (results.resultException != null) { + logger.error("Couldn't get event for kit with ddpParticipantId " + ddpParticipantId, results.resultException); + } + return Optional.ofNullable((EventDto) results.resultValue); + } + + /** + * Inserts an event into the EVENT_QUEUE table + * */ + public void insertEvent(@NonNull String type, @NonNull int ddpInstanceID, String ddpParticipantId, + String dsmKitRequestId, boolean trigger) { + if (StringUtils.isBlank(ddpParticipantId) && StringUtils.isBlank(dsmKitRequestId)) { + throw new DsmInternalError(("Both ddpParticipantId and dsmKitRequestId cannot be blank, unable to insert event for type %s and " + + " instance %d").formatted(type, ddpInstanceID)); + } + SimpleResult result = inTransaction((conn) -> { + SimpleResult dbVals = new SimpleResult(); + try (PreparedStatement stmt = conn.prepareStatement(SQL_INSERT_EVENT)) { + stmt.setLong(1, System.currentTimeMillis()); + stmt.setString(2, type); + stmt.setInt(3, ddpInstanceID); + if (StringUtils.isNotBlank(ddpParticipantId)) { + stmt.setString(4, ddpParticipantId); + } else { + stmt.setNull(4, java.sql.Types.VARCHAR); + } + if (StringUtils.isNotBlank(dsmKitRequestId)) { + stmt.setString(5, dsmKitRequestId); + } else { + stmt.setNull(5, java.sql.Types.VARCHAR); + } + stmt.setString(5, dsmKitRequestId); + stmt.setBoolean(6, trigger); + int r = stmt.executeUpdate(); + if (r != 1) { + if (ddpParticipantId != null) { + dbVals.resultException = new DsmInternalError("Error could not add event for participant " + ddpParticipantId); + } else { + dbVals.resultException = new DsmInternalError("Error could not add event for kit request " + dsmKitRequestId); + } + return dbVals; + } + } catch (SQLException e) { + dbVals.resultException = e; + } + return dbVals; + }); + if (result.resultException != null) { + if (ddpParticipantId != null) { + logger.error("Error adding event for participant " + ddpParticipantId, result.resultException); + } else { + logger.error("Error adding event for kit request " + dsmKitRequestId, result.resultException); + } + } + } + + /** + * Creates KitDDPNotification for all the kits that are sent to participants but not returned to Broad + * (i.e. kits that are not received yet). + * @return Collection of KitDDPNotification objects + * */ + public Collection getKitsNotReceived() { + ArrayList kitDDPNotifications = new ArrayList<>(); + SimpleResult results = inTransaction((conn) -> { + SimpleResult dbVals = new SimpleResult(); + try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_KIT_FOR_REMINDER_EMAILS)) { + stmt.setString(1, DBConstants.KIT_PARTICIPANT_NOTIFICATIONS_ACTIVATED); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + if (rs.getBoolean(DBConstants.HAS_ROLE)) { + String participantId = rs.getString(DBConstants.DDP_PARTICIPANT_ID); + String realm = rs.getString(DBConstants.INSTANCE_NAME); + kitDDPNotifications.add(new KitDDPNotification(participantId, rs.getString(DBConstants.DSM_KIT_REQUEST_ID), + rs.getInt(DBConstants.DDP_INSTANCE_ID), realm, rs.getString(DBConstants.BASE_URL), + rs.getString(DBConstants.EVENT_NAME), rs.getString(DBConstants.EVENT_TYPE), System.currentTimeMillis(), + rs.getBoolean(DBConstants.NEEDS_AUTH0_TOKEN), rs.getString(DBConstants.UPLOAD_REASON), + rs.getString(DBConstants.DDP_KIT_REQUEST_ID))); + } + } + } + } catch (SQLException ex) { + dbVals.resultException = ex; + } + return dbVals; + }); + + if (results.resultException != null) { + logger.error("Error getting list of kit requests which aren't received yet (for reminder emails) ", results.resultException); + } + logger.info("Found " + kitDDPNotifications.size() + " kit requests for which the ddp needs to trigger reminder emails."); + return kitDDPNotifications; } } diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/settings/EventTypeDao.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/settings/EventTypeDao.java index a562226103..3562af6679 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/settings/EventTypeDao.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dao/settings/EventTypeDao.java @@ -58,7 +58,7 @@ public List getEventTypeByInstanceName(@NonNull String instanceNam try (ResultSet rs = stmt.executeQuery()) { while (rs.next()) { eventTypeList.add( - new EventTypeDto.Builder(rs.getString(DBConstants.DDP_INSTANCE_ID)).withEventName(rs.getString(EVENT_NAME)) + new EventTypeDto.Builder(rs.getInt(DBConstants.DDP_INSTANCE_ID)).withEventName(rs.getString(EVENT_NAME)) .withEventType(rs.getString(EVENT_TYPE)).withInstanceName(rs.getString(DBConstants.INSTANCE_NAME)) .withBaseUrl(rs.getString(DBConstants.BASE_URL)) .withAuth0Token(rs.getBoolean(DBConstants.NEEDS_AUTH0_TOKEN)).build()); @@ -88,7 +88,7 @@ public Optional getEventTypeByEventNameAndInstanceId(@NotNull Stri rs.beforeFirst(); if (count == 1) { if (rs.next()) { //if row is 0 the ddp/kit type combination does not trigger a participant event - dbVals.resultValue = new EventTypeDto.Builder(rs.getString(DBConstants.DDP_INSTANCE_ID)).withEventName( + dbVals.resultValue = new EventTypeDto.Builder(rs.getInt(DBConstants.DDP_INSTANCE_ID)).withEventName( rs.getString(EVENT_NAME)).withEventType(rs.getString(EVENT_TYPE)) .withInstanceName(rs.getString(DBConstants.INSTANCE_NAME)) .withBaseUrl(rs.getString(DBConstants.BASE_URL)) diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dto/kit/nonPepperKit/NonPepperKitStatusDto.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dto/kit/nonPepperKit/NonPepperKitStatusDto.java index 15cfc13af5..23cb7ff6dc 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dto/kit/nonPepperKit/NonPepperKitStatusDto.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dto/kit/nonPepperKit/NonPepperKitStatusDto.java @@ -112,6 +112,7 @@ public Builder withLabelByEmail(String labelByEmail) { this.labelByEmail = labelByEmail; return this; } + public Builder withMfBarcode(String mfBarcode) { this.mfBarcode = mfBarcode; return this; diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dto/queue/EventDto.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dto/queue/EventDto.java index d9042b453c..e76e336838 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dto/queue/EventDto.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dto/queue/EventDto.java @@ -1,12 +1,17 @@ package org.broadinstitute.dsm.db.dto.queue; +import lombok.Getter; + +@Getter public class EventDto { private int eventId; private long eventDateCreated; private String eventType; private int ddpInstanceId; - private int dsmKitRequestId; + + //the dsmKitRequestId will be null for participant events + private Integer dsmKitRequestId; private String ddpParticipantId; private Boolean eventTriggered; diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dto/queue/SkippedParticipantEventDto.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dto/queue/SkippedParticipantEventDto.java new file mode 100644 index 0000000000..821c46869e --- /dev/null +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dto/queue/SkippedParticipantEventDto.java @@ -0,0 +1,22 @@ +package org.broadinstitute.dsm.db.dto.queue; + +import lombok.Data; + +@Data +public class SkippedParticipantEventDto { + /** + * The event_type in this table is actually the event_name from the event_type table + */ + private final String participantId; + private final String eventType; + private final String user; + private final long date; + private String shortId; + + public SkippedParticipantEventDto(String participantId, String eventType, String user, long date) { + this.participantId = participantId; + this.eventType = eventType; + this.user = user; + this.date = date; + } +} diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dto/settings/EventTypeDto.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dto/settings/EventTypeDto.java index 7fc039a4e0..02695a1aad 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dto/settings/EventTypeDto.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/db/dto/settings/EventTypeDto.java @@ -6,7 +6,7 @@ public class EventTypeDto { private int eventTypeId; - private String ddpInstanceId; + private int ddpInstanceId; private String instanceName; private String baseUrl; private Boolean auth0Token; @@ -32,7 +32,7 @@ private EventTypeDto(EventTypeDto.Builder builder) { public static class Builder { private int eventTypeId; - private String ddpInstanceId; + private int ddpInstanceId; private String instanceName; private String baseUrl; private Boolean auth0Token; @@ -42,7 +42,7 @@ public static class Builder { private String eventType; private int hours; - public Builder(String ddpInstanceId) { + public Builder(int ddpInstanceId) { this.ddpInstanceId = ddpInstanceId; } diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/jobs/DDPEventJob.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/jobs/DDPEventJob.java index 22d144ee58..f2c1296c1f 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/jobs/DDPEventJob.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/jobs/DDPEventJob.java @@ -1,7 +1,7 @@ package org.broadinstitute.dsm.jobs; import org.broadinstitute.dsm.DSMServer; -import org.broadinstitute.dsm.util.EventUtil; +import org.broadinstitute.dsm.service.EventService; import org.broadinstitute.dsm.util.NotificationUtil; import org.quartz.Job; import org.quartz.JobDataMap; @@ -18,8 +18,8 @@ public void execute(JobExecutionContext context) throws JobExecutionException { try { JobDataMap dataMap = context.getJobDetail().getJobDataMap(); //fetch parameters from JobDataMap - EventUtil eventUtil = (EventUtil) dataMap.get(DSMServer.EVENT_UTIL); - eventUtil.triggerReminder(); + EventService eventService = (EventService) dataMap.get(DSMServer.EVENT_UTIL); + eventService.triggerReminder(); NotificationUtil notificationUtil = (NotificationUtil) dataMap.get(DSMServer.NOTIFICATION_UTIL); notificationUtil.removeObsoleteReminders(); diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/jobs/TestBostonUPSTrackingJob.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/jobs/TestBostonUPSTrackingJob.java deleted file mode 100644 index ff465e0302..0000000000 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/jobs/TestBostonUPSTrackingJob.java +++ /dev/null @@ -1,610 +0,0 @@ -package org.broadinstitute.dsm.jobs; - -import static org.broadinstitute.dsm.db.dao.ddp.kitrequest.KitRequestDao.BY_KIT_LABEL; -import static org.broadinstitute.dsm.db.dao.ddp.kitrequest.KitRequestDao.SQL_GET_KIT_REQUEST; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.time.Instant; -import java.util.Arrays; -import java.util.Base64; -import java.util.Date; -import java.util.List; - -import com.google.cloud.functions.BackgroundFunction; -import com.google.cloud.functions.Context; -import com.google.gson.Gson; -import com.typesafe.config.Config; -import org.apache.commons.dbcp2.PoolableConnection; -import org.apache.commons.dbcp2.PoolingDataSource; -import org.apache.commons.lang3.tuple.Pair; -import org.broadinstitute.dsm.careevolve.Authentication; -import org.broadinstitute.dsm.careevolve.Covid19OrderRegistrar; -import org.broadinstitute.dsm.careevolve.Provider; -import org.broadinstitute.dsm.cf.CFUtil; -import org.broadinstitute.dsm.db.InstanceSettings; -import org.broadinstitute.dsm.db.dto.ddp.kitrequest.KitRequestDto; -import org.broadinstitute.dsm.model.KitDDPNotification; -import org.broadinstitute.dsm.model.ups.UPSActivity; -import org.broadinstitute.dsm.model.ups.UPSDeliveryDate; -import org.broadinstitute.dsm.model.ups.UPSError; -import org.broadinstitute.dsm.model.ups.UPSKit; -import org.broadinstitute.dsm.model.ups.UPSPackage; -import org.broadinstitute.dsm.model.ups.UPSShipment; -import org.broadinstitute.dsm.model.ups.UPSStatus; -import org.broadinstitute.dsm.model.ups.UPSTrackingResponse; -import org.broadinstitute.dsm.shipping.UPSTracker; -import org.broadinstitute.dsm.statics.ApplicationConfigConstants; -import org.broadinstitute.dsm.statics.DBConstants; -import org.broadinstitute.dsm.util.EventUtil; -import org.broadinstitute.dsm.util.KitUtil; -import org.broadinstitute.dsm.security.Auth0Util; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import spark.utils.StringUtils; - -public class TestBostonUPSTrackingJob implements BackgroundFunction { - - public static final String SKIP_CE_ORDERS_FOR_SCHEDULED_KITS_AFTER = "testboston.skipCEOrdersForScheduledKitsAfter"; - private static Auth0Util auth0Util; - private final Logger logger = LoggerFactory.getLogger(TestBostonUPSTrackingJob.class); - private final int maxConnection = 1; - private final String skipCeOrderDateFormat = "YYYY-MM-dd"; - String delivered = "DELIVERED"; - String received = "RECEIVED"; - String endpoint; - String username; - String password; - String accessKey; - Date ignoreScheduledOrdersAfter; - UPSTracker upsTracker = null; - private String studyManagerSchema = System.getenv("STUDY_MANAGER_SCHEMA") + "."; - private String selectByExternalOrderNumber = "and request.external_order_number = ?"; - private Covid19OrderRegistrar orderRegistrar; - private Authentication careEvolveAuth = null; - - @Override - public void accept(PubsubMessage message, Context context) throws Exception { - if (message.data == null) { - logger.error("No pubsub message provided"); - return; - } - Config cfg = CFUtil.loadConfig(); - String dbUrl = cfg.getString("dsmDBUrl"); - endpoint = cfg.getString("ups.url"); - username = cfg.getString("ups.username"); - password = cfg.getString("ups.password"); - accessKey = cfg.getString("ups.accesskey"); - if (cfg.hasPath(SKIP_CE_ORDERS_FOR_SCHEDULED_KITS_AFTER)) { - String skipAfter = cfg.getString(SKIP_CE_ORDERS_FOR_SCHEDULED_KITS_AFTER); - try { - ignoreScheduledOrdersAfter = new SimpleDateFormat(skipCeOrderDateFormat).parse(skipAfter); - logger.info("Will skip all CE orders after " + skipAfter); - } catch (ParseException e) { - logger.error( - "Could not parse cutoff time for testboston longitudinal orders. Expected format is " + skipCeOrderDateFormat, - e); - } - } else { - logger.info("No cutoff date for CE orders of longitudinal kits. Will continue to place CE orders"); - } - upsTracker = new UPSTracker(endpoint, username, password, accessKey); - logger.info("Starting the UPS lookup job"); - auth0Util = new Auth0Util(cfg.getString(ApplicationConfigConstants.AUTH0_ACCOUNT), - cfg.getStringList(ApplicationConfigConstants.AUTH0_CONNECTIONS), cfg.getString(ApplicationConfigConstants.AUTH0_CLIENT_KEY), - cfg.getString(ApplicationConfigConstants.AUTH0_SECRET), cfg.getString(ApplicationConfigConstants.AUTH0_MGT_KEY), - cfg.getString(ApplicationConfigConstants.AUTH0_MGT_SECRET), cfg.getString(ApplicationConfigConstants.AUTH0_MGT_API_URL), - cfg.getString(ApplicationConfigConstants.AUTH0_AUDIENCE)); - String data = new String(Base64.getDecoder().decode(message.data)); - UPSKit[] kitsToLookFor = new Gson().fromJson(data, UPSKit[].class); - PoolingDataSource dataSource = - CFUtil.createDataSource(maxConnection, cfg.getString(ApplicationConfigConstants.CF_DSM_DB_URL)); - Arrays.stream(kitsToLookFor).forEach(kit -> { - logger.info("Checking possible actions for kit " + kit.getDsmKitRequestId()); - if (StringUtils.isNotBlank(kit.getUpsPackage().getUpsShipmentId())) { - getUPSUpdate(dataSource, kit, cfg); - } else { - insertShipmentAndPackageForNewKit(dataSource, kit, cfg); // for a new kit we first need to insert the UPSShipment - } - } - - ); - - - } - - private void insertShipmentAndPackageForNewKit(PoolingDataSource dataSource, UPSKit kit, Config cfg) { - String insertedShipmentId = null; - String[] insertedPackageIds = new String[2]; - String shippingKitPackageId = null; - String returnKitPackageId = null; - boolean gbfShippedTriggerDSSDelivered = false; - logger.info("Inserting new kit information for kit " + kit.getDsmKitRequestId()); - final String SQL_INSERT_SHIPMENT = - "INSERT INTO " + studyManagerSchema + "ups_shipment" + " ( dsm_kit_request_id )" + " VALUES " + " (?)"; - final String SQL_INSERT_UPSPackage = - "INSERT INTO " + studyManagerSchema + "ups_package" + "( ups_shipment_id ," + " tracking_number )" + " VALUES " - + " ( ? ,?)," + " ( ? ,?) "; - - Connection conn = null; - try { - conn = dataSource.getConnection(); - try (PreparedStatement stmt = conn.prepareStatement(SQL_INSERT_SHIPMENT, Statement.RETURN_GENERATED_KEYS)) { - stmt.setString(1, kit.getDsmKitRequestId()); - int result = stmt.executeUpdate(); - if (result == 1) { - try (ResultSet rs = stmt.getGeneratedKeys()) { - - if (rs.next()) { - insertedShipmentId = rs.getString(1); - logger.info("Added new ups shipment with id " + insertedShipmentId + " for " + kit.getDsmKitRequestId()); - } - } catch (Exception e) { - logger.error("Error getting id of new shipment ", e); - logger.error(e.getMessage()); - return; - } - } else { - logger.error("Error adding new ups shipment for kit w/ id " + kit.getDsmKitRequestId() + " it was updating " + result - + " rows"); - return; - } - - } catch (Exception ex) { - logger.error("Error preparing statement", ex); - logger.error(ex.getMessage()); - return; - } - - if (insertedShipmentId != null) { - logger.info("Inserting new package information for kit " + kit.getDsmKitRequestId()); - try (PreparedStatement stmt = conn.prepareStatement(SQL_INSERT_UPSPackage, Statement.RETURN_GENERATED_KEYS)) { - stmt.setString(1, insertedShipmentId); - stmt.setString(2, kit.getTrackingToId()); //first row is the shipping one - stmt.setString(3, insertedShipmentId); - stmt.setString(4, kit.getTrackingReturnId()); //second row is the return one - int result = stmt.executeUpdate(); - if (result == 2) { - try (ResultSet rs = stmt.getGeneratedKeys()) { - int i = 0; - while (rs.next()) { - insertedPackageIds[i] = rs.getString(1); - i++; - } - if (i != 2) { - throw new RuntimeException("Didn't insert right amount of packages. Num of Packages = " + i); - } - shippingKitPackageId = insertedPackageIds[0]; - returnKitPackageId = insertedPackageIds[1]; - logger.info( - "Added new outbound ups package with id " + shippingKitPackageId + " for " + kit.getDsmKitRequestId() - + " and added new inbound ups package with id " + returnKitPackageId + " for " - + kit.getDsmKitRequestId()); - } catch (Exception e) { - logger.error("Error getting id of new inserted packages for kit " + kit.getDsmKitRequestId(), e); - return; - } - } else { - logger.error( - "Error adding new ups packages for kit w/ id " + kit.getDsmKitRequestId() + " it was updating " + result - + " rows"); - return; - } - - - } catch (Exception ex) { - logger.error("Error preparing statement", ex); - logger.error(ex.getMessage()); - return; - } - - } - gbfShippedTriggerDSSDelivered = - InstanceSettings.getInstanceSettings(Integer.parseInt(kit.getDdpInstanceId()), conn).isGbfShippedTriggerDSSDelivered(); - conn.commit(); - } catch (SQLException ex) { - logger.error("Trouble creating a connection to the database " + ex); - logger.error(ex.getMessage()); - } finally { - if (conn != null) { - try { - conn.close(); - } catch (Throwable ex) { - logger.error("Could not close JDBC Connection ", ex); - } - } - } - UPSPackage upsPackageShipping = new UPSPackage(kit.getTrackingToId(), null, insertedShipmentId, shippingKitPackageId, null, null); - UPSPackage upsPackageReturn = new UPSPackage(kit.getTrackingReturnId(), null, insertedShipmentId, returnKitPackageId, null, null); - - UPSKit kitShipping = - new UPSKit(upsPackageShipping, kit.getKitLabel(), kit.getCeOrder(), kit.getDsmKitRequestId(), kit.getExternalOrderNumber(), - kit.getTrackingToId(), kit.getTrackingReturnId(), kit.getDdpInstanceId(), kit.getHruid(), - gbfShippedTriggerDSSDelivered); - UPSKit kitReturn = - new UPSKit(upsPackageReturn, kit.getKitLabel(), kit.getCeOrder(), kit.getDsmKitRequestId(), kit.getExternalOrderNumber(), - kit.getTrackingToId(), kit.getTrackingReturnId(), kit.getDdpInstanceId(), kit.getHruid(), - gbfShippedTriggerDSSDelivered); - getUPSUpdate(dataSource, kitShipping, cfg); - getUPSUpdate(dataSource, kitReturn, cfg); - } - - - public void getUPSUpdate(PoolingDataSource dataSource, UPSKit kit, Config cfg) { - logger.info("Checking UPS status for kit with external order number " + kit.getExternalOrderNumber()); - updateKitStatus(dataSource, kit, kit.isReturn(), kit.getDdpInstanceId(), cfg); - } - - public UPSTrackingResponse lookupTrackingInfo(String trackingId) throws Exception { - if (upsTracker != null) { - return upsTracker.lookupTrackingInfo(trackingId); - } else { - throw new RuntimeException("UPSTracker should not be null!"); - } - } - - public void updateKitStatus(PoolingDataSource dataSource, UPSKit kit, boolean isReturn, String ddpInstanceId, - Config cfg) { - if (kit.getUpsPackage() != null) { - String trackingId = kit.getUpsPackage().getTrackingNumber(); - UPSActivity lastActivity = kit.getUpsPackage().getActivity() == null ? null : kit.getUpsPackage().getActivity()[0]; - if (lastActivity != null && lastActivity.getStatus().isDelivery()) { - this.logger.info("Tracking id " + trackingId + " is already delivered, not going to check UPS anymore"); - updateDeliveryInformation(dataSource, kit.getUpsPackage(), kit, cfg); - return; - } - logger.info("Checking UPS status for " + trackingId + " for kit w/ external order number " + kit.getExternalOrderNumber()); - try { - UPSTrackingResponse response = lookupTrackingInfo(trackingId); - logger.info("UPS response for " + trackingId + " is " + response); //todo remove after tests - if (response != null && response.getErrors() == null) { - updateStatus(dataSource, trackingId, lastActivity, response, isReturn, kit, ddpInstanceId, cfg); - } else { - logError(trackingId, response.getErrors()); - } - } catch (Exception e) { - logger.error("Problem getting UPS update for kit " + kit.getUpsPackage().getTrackingNumber()); - e.printStackTrace(); - } - } else { - logger.error("Kit's UPSPackage was null for dsmKitRequestId: " + kit.getDsmKitRequestId()); - } - } - - private void logError(String trackingId, UPSError[] errors) { - String errorString = ""; - for (UPSError error : errors) { - errorString += "Got Error: " + error.getCode() + " " + error.getMessage() + " For Tracking Number " + trackingId; - } - logger.error(errorString); - } - - - private void updateStatus(PoolingDataSource dataSource, String trackingId, UPSActivity lastActivity, - UPSTrackingResponse response, boolean isReturn, UPSKit kit, String ddpInstanceId, Config cfg) { - if (response.getTrackResponse() != null) { - UPSShipment[] shipment = response.getTrackResponse().getShipment(); - if (shipment != null && shipment.length > 0) { - UPSPackage[] responseUpsPackages = shipment[0].getUpsPackageArray(); - if (responseUpsPackages != null && responseUpsPackages.length > 0) { - UPSPackage responseUpsPackage = responseUpsPackages[0]; - UPSActivity[] activities = responseUpsPackage.getActivity(); - if (activities != null) { - UPSActivity earliestPackageMovementEvent = responseUpsPackage.getEarliestPackageMovementEvent(); - Instant earliestPackageMovement = null; - if (earliestPackageMovementEvent != null) { - earliestPackageMovement = earliestPackageMovementEvent.getInstant(); - } - UPSActivity recentActivity = activities[0]; - UPSStatus status = activities[0].getStatus(); - String statusType = null; - if (status != null) { - statusType = status.getType(); - } - if (lastActivity == null || (!lastActivity.equals(recentActivity))) { - updateTrackingInfo(dataSource, activities, statusType, lastActivity, trackingId, isReturn, kit, - earliestPackageMovement, ddpInstanceId, cfg); - } - if (responseUpsPackage.getDeliveryDate() != null) { - updateDeliveryInformation(dataSource, responseUpsPackage, kit, cfg); - } - } - } - - } - } - } - - private void updateDeliveryInformation(PoolingDataSource dataSource, UPSPackage responseUpsPackage, UPSKit upsKit, - Config cfg) { - String sqlUpdatePackageDelivery = - "UPDATE " + studyManagerSchema + "ups_package " + "SET " + "delivery_date = ?, " + "delivery_time_start = ?, " - + "delivery_time_end = ?, " + "delivery_time_type = ? " + "WHERE ups_package_id = ? "; - UPSDeliveryDate[] deliveryDates = responseUpsPackage.getDeliveryDate(); - UPSDeliveryDate currentDelivery = null; - String deliveryDate = null; - if (deliveryDates != null && deliveryDates.length > 0) { - currentDelivery = deliveryDates[0]; - deliveryDate = currentDelivery.getDate(); - } - String deliveryStartTime = null; - String deliveryEndTime = null; - String deliveryType = null; - if (responseUpsPackage.getDeliveryTime() != null) { - deliveryStartTime = responseUpsPackage.getDeliveryTime().getStartTime(); - deliveryEndTime = responseUpsPackage.getDeliveryTime().getEndTime(); - deliveryType = responseUpsPackage.getDeliveryTime().getType(); - } - Connection conn = null; - try { - conn = dataSource.getConnection(); - try (PreparedStatement stmt = conn.prepareStatement(sqlUpdatePackageDelivery)) { - stmt.setString(1, deliveryDate); - stmt.setString(2, deliveryStartTime); - stmt.setString(3, deliveryEndTime); - stmt.setString(4, deliveryType); - stmt.setString(5, upsKit.getUpsPackage().getUpsPackageId()); - int r = stmt.executeUpdate(); - - logger.info("Updated " + r + " rows adding delivery for tracking number " + responseUpsPackage.getTrackingNumber() - + " for ups_package_id " + responseUpsPackage.getUpsPackageId()); - if (r != 1) { - logger.error(r + " rows updated in UPSPackege while updating delivery for " + upsKit.getUpsPackage().getUpsPackageId()); - } - conn.commit(); - } catch (Exception ex) { - logger.error("Error preparing statement", ex); - logger.error(ex.getMessage()); - } - conn.commit(); - } catch (SQLException e) { - logger.error("Trouble creating a connection to the DB"); - logger.error(e.getMessage()); - } finally { - if (conn != null) { - try { - conn.close(); - } catch (Throwable ex) { - logger.error("Could not close JDBC Connection ", ex); - logger.error(ex.getMessage()); - } - } - } - - } - - - private void updateTrackingInfo(PoolingDataSource dataSource, UPSActivity[] activities, String statusType, - UPSActivity lastActivity, String trackingId, boolean isReturn, UPSKit kit, - Instant earliestInTransitTime, String ddpInstanceId, Config cfg) { - final String INSERT_NEW_ACTIVITIES = - "INSERT INTO " + studyManagerSchema + "ups_activity ( ups_package_id , ups_location , " - + " ups_status_type , ups_status_description , ups_status_code , " - + " ups_activity_date_time) " + "VALUES " + "( ?, ?, ?, ?, ?, ?)"; - final String SQL_SELECT_KIT_FOR_NOTIFICATION_EXTERNAL_SHIPPER = - "select eve.*, request.ddp_participant_id, request.ddp_label, request.dsm_kit_request_id, " - + "request.ddp_kit_request_id, request.upload_reason, " - + " realm.ddp_instance_id, realm.instance_name, realm.base_url, realm.auth0_token, " - + "realm.notification_recipients, realm.migrated_ddp, kit.receive_date, kit.scan_date" - + " FROM " + studyManagerSchema + "ddp_kit_request request, " + studyManagerSchema + "ddp_kit kit, " - + studyManagerSchema + "event_type eve, " + studyManagerSchema - + "ddp_instance realm where request.dsm_kit_request_id = kit.dsm_kit_request_id " - + "and request.ddp_instance_id = realm.ddp_instance_id" - + " and not exists (select 1 FROM " + studyManagerSchema + "EVENT_QUEUE q" - + " where q.DDP_INSTANCE_ID = realm.ddp_instance_id and " - + " q.EVENT_TYPE = eve.event_name and " - + " q.DSM_KIT_REQUEST_ID = request.dsm_kit_request_id " - + " and q.event_triggered = true )" - + " and (eve.ddp_instance_id = request.ddp_instance_id and eve.kit_type_id = request.kit_type_id) " - + " and eve.event_type = ? " - + " and realm.ddp_instance_id = ? and kit.dsm_kit_request_id = ?"; - logger.info("Inserting new activities for kit with package id " + kit.getUpsPackage().getUpsPackageId()); - Connection conn = null; - try { - conn = dataSource.getConnection(); - for (int i = activities.length - 1; i >= 0; i--) { - UPSActivity currentInsertingActivity = activities[i]; - if (lastActivity != null) { - if (lastActivity.getInstant() != null && (currentInsertingActivity.getInstant().equals(lastActivity.getInstant()) - || currentInsertingActivity.getInstant().isBefore(lastActivity.getInstant()))) { - continue; - } - } - String activityDateTime = currentInsertingActivity.getSQLDateTimeString(); - - - try (PreparedStatement stmt = conn.prepareStatement(INSERT_NEW_ACTIVITIES)) { - stmt.setString(1, kit.getUpsPackage().getUpsPackageId()); - stmt.setString(2, currentInsertingActivity.getLocation().getString()); - stmt.setString(3, currentInsertingActivity.getStatus().getType()); - stmt.setString(4, currentInsertingActivity.getStatus().getDescription()); - stmt.setString(5, currentInsertingActivity.getStatus().getCode()); - stmt.setString(6, activityDateTime); - int r = stmt.executeUpdate(); - - logger.info("Updated " + r + " rows for a new activity"); - logger.info("Inserted new activity " + currentInsertingActivity.getStatus().getDescription() + " for package id " - + kit.getUpsPackage().getUpsPackageId()); - if (r != 1) { - logger.error(r + " is too big for 1 new activity"); - } - } catch (Exception ex) { - throw new RuntimeException( - "Error preparing statement for inserting a new activity for package id " + kit.getUpsPackage() - .getUpsPackageId(), ex); - } - } - String oldType = null; - if (lastActivity != null && lastActivity.getStatus() != null) { - oldType = lastActivity.getStatus().getType(); - } - if (!isReturn) { - if (shouldTriggerEventForKitOnItsWayToParticipant(statusType, oldType, kit.isGbfShippedTriggerDSSDelivered())) { - KitDDPNotification kitDDPNotification = KitDDPNotification.getKitDDPNotification(conn, - SQL_SELECT_KIT_FOR_NOTIFICATION_EXTERNAL_SHIPPER + selectByExternalOrderNumber, - new String[] {delivered, ddpInstanceId, kit.getDsmKitRequestId(), kit.getExternalOrderNumber()}, 1); - if (kitDDPNotification != null) { - logger.info( - "Triggering DDP for kit going to participant with external order number: " + kit.getExternalOrderNumber()); - EventUtil.triggerDDP(conn, kitDDPNotification, auth0Util); - } else { - logger.error("delivered kitDDPNotification was null for " + kit.getExternalOrderNumber()); - } - } - - } else { // this is a return - if (earliestInTransitTime != null && !kit.getCeOrder()) { - // if we have the first date of an inbound event, create an order in CE - // using the earliest date of inbound event - - boolean shouldPlaceCEOrder = true; - if (StringUtils.isNotBlank(kit.getKitLabel())) { - // if we are after the cutoff date and this is a longitudinal order, do not place the order - if (ignoreScheduledOrdersAfter != null) { - if (ignoreScheduledOrdersAfter.toInstant().isAfter(Instant.now())) { - shouldPlaceCEOrder = doesKitHaveUploadReason(conn, kit.getKitLabel()); - } - } - - if (shouldPlaceCEOrder) { - if (orderRegistrar == null || careEvolveAuth == null) { - Pair careEvolveOrderingTools = createCEOrderRegistrar(cfg); - orderRegistrar = careEvolveOrderingTools.getLeft(); - careEvolveAuth = careEvolveOrderingTools.getRight(); - - } - orderRegistrar.orderTest(careEvolveAuth, kit.getHruid(), kit.getMainKitLabel(), kit.getExternalOrderNumber(), - earliestInTransitTime, conn, cfg); - logger.info("Placed CE order for kit with external order number " + kit.getExternalOrderNumber()); - logger.info( - "Placed CE order for kit with label " + kit.getMainKitLabel() + " for time " + earliestInTransitTime); - kit.changeCEOrdered(conn, true); - } - } - } else { - logger.info("No return events for " + kit.getMainKitLabel() + ". Will not place order yet."); - } - if (shouldTriggerEventForReturnKitDelivery(statusType, oldType)) { - KitUtil.setKitReceived(conn, kit.getMainKitLabel()); - logger.info("RECEIVED: " + trackingId); - KitDDPNotification kitDDPNotification = KitDDPNotification.getKitDDPNotification(conn, - SQL_SELECT_KIT_FOR_NOTIFICATION_EXTERNAL_SHIPPER + selectByExternalOrderNumber, - new String[] {received, ddpInstanceId, kit.getDsmKitRequestId(), kit.getExternalOrderNumber()}, 1); - if (kitDDPNotification != null) { - logger.info("Triggering DDP for received kit with external order number: " + kit.getExternalOrderNumber()); - EventUtil.triggerDDP(conn, kitDDPNotification, auth0Util); - - } else { - logger.error("received kitDDPNotification was null for " + kit.getExternalOrderNumber()); - } - } - } - conn.commit(); - logger.info("Updated status of tracking number " + trackingId + " to " + statusType + " from " + oldType - + " for kit w/ external order number " + kit.getExternalOrderNumber()); - - - } catch (SQLException ex) { - logger.error("Trouble connecting to DB " + ex); - logger.error(ex.getMessage()); - } finally { - if (conn != null) { - try { - conn.close(); - } catch (Throwable ex) { - logger.error("Could not close JDBC Connection ", ex); - } - } - } - - - } - - /** - * Queries the database to see whether there is an upload reason - * for the given kit label - */ - private boolean doesKitHaveUploadReason(Connection conn, String kitLabel) throws SQLException { - boolean hasUploadReason = false; - try (PreparedStatement stmt = conn.prepareStatement(SQL_GET_KIT_REQUEST + BY_KIT_LABEL)) { - stmt.setString(1, kitLabel); - try (ResultSet rs = stmt.executeQuery()) { - while (rs.next()) { - KitRequestDto dto = new KitRequestDto(rs.getInt(DBConstants.DSM_KIT_REQUEST_ID), rs.getInt(DBConstants.DDP_INSTANCE_ID), - rs.getString(DBConstants.DDP_KIT_REQUEST_ID), rs.getInt(DBConstants.KIT_TYPE_ID), - rs.getString(DBConstants.COLLABORATOR_PARTICIPANT_ID), - rs.getString(DBConstants.BSP_COLLABORATOR_SAMPLE_ID), rs.getString(DBConstants.DDP_PARTICIPANT_ID), - rs.getString(DBConstants.DSM_LABEL), rs.getString(DBConstants.CREATED_BY), rs.getLong(DBConstants.CREATED_DATE), - rs.getString(DBConstants.EXTERNAL_ORDER_NUMBER), rs.getLong(DBConstants.EXTERNAL_ORDER_DATE), - rs.getString(DBConstants.EXTERNAL_ORDER_STATUS), rs.getString(DBConstants.EXTERNAL_RESPONSE), - rs.getString(DBConstants.UPLOAD_REASON), rs.getTimestamp(DBConstants.ORDER_TRANSMITTED_AT)); - - if (!hasUploadReason && dto.hasUploadReason()) { - hasUploadReason = true; - } - } - } - } - return hasUploadReason; - } - - /** - * Determines whether or not a trigger should be sent to - * study-server to respond to kit being sent to participant - */ - private boolean shouldTriggerEventForKitOnItsWayToParticipant(String currentStatus, String previousStatus, - boolean gbfShippedTriggerDSSDelivered) { - if (gbfShippedTriggerDSSDelivered) { - return false; - } - List triggerStates = Arrays.asList(UPSStatus.DELIVERED_TYPE, UPSStatus.IN_TRANSIT_TYPE); - return triggerStates.contains(currentStatus) && !triggerStates.contains(previousStatus); - } - - /** - * Determines whether or not a trigger should be sent to - * study-server to respond to kit being delivered back at broad - */ - private boolean shouldTriggerEventForReturnKitDelivery(String currentStatus, String previousStatus) { - List triggerStates = Arrays.asList(UPSStatus.DELIVERED_TYPE); - return triggerStates.contains(currentStatus) && !triggerStates.contains(previousStatus); - } - - - private Pair createCEOrderRegistrar(Config cfg) { - Covid19OrderRegistrar orderRegistrar; - String careEvolveSubscriberKey = cfg.getString(ApplicationConfigConstants.CARE_EVOLVE_SUBSCRIBER_KEY); - String careEvolveServiceKey = cfg.getString(ApplicationConfigConstants.CARE_EVOLVE_SERVICE_KEY); - Authentication careEvolveAuth = new Authentication(careEvolveSubscriberKey, careEvolveServiceKey); - String careEvolveAccount = cfg.getString(ApplicationConfigConstants.CARE_EVOLVE_ACCOUNT); - String careEvolveOrderEndpoint = cfg.getString(ApplicationConfigConstants.CARE_EVOLVE_ORDER_ENDPOINT); - Integer careEvolveMaxRetries; - Integer careEvolveRetyWaitSeconds; - if (cfg.hasPath(ApplicationConfigConstants.CARE_EVOLVE_MAX_RETRIES)) { - careEvolveMaxRetries = cfg.getInt(ApplicationConfigConstants.CARE_EVOLVE_MAX_RETRIES); - } else { - careEvolveMaxRetries = 5; - } - if (cfg.hasPath(ApplicationConfigConstants.CARE_EVOLVE_RETRY_WAIT_SECONDS)) { - careEvolveRetyWaitSeconds = cfg.getInt(ApplicationConfigConstants.CARE_EVOLVE_RETRY_WAIT_SECONDS); - } else { - careEvolveRetyWaitSeconds = 10; - } - logger.info("Will retry CareEvolve at most {} times after {} seconds", careEvolveMaxRetries, careEvolveRetyWaitSeconds); - Provider provider; - provider = new Provider(cfg.getString(ApplicationConfigConstants.CARE_EVOLVE_PROVIDER_FIRSTNAME), - cfg.getString(ApplicationConfigConstants.CARE_EVOLVE_PROVIDER_LAST_NAME), - cfg.getString(ApplicationConfigConstants.CARE_EVOLVE_PROVIDER_NPI)); - orderRegistrar = new Covid19OrderRegistrar(careEvolveOrderEndpoint, careEvolveAccount, provider, careEvolveMaxRetries, - careEvolveRetyWaitSeconds); - Pair result = Pair.of(orderRegistrar, careEvolveAuth); - return result; - } - - -} diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/KitDDPNotification.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/KitDDPNotification.java index 038a1636d6..4111fa0173 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/KitDDPNotification.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/KitDDPNotification.java @@ -8,6 +8,8 @@ import lombok.Data; import lombok.NonNull; +import org.apache.commons.lang3.StringUtils; +import org.broadinstitute.ddp.notficationevent.KitReasonType; import org.broadinstitute.dsm.statics.DBConstants; import org.broadinstitute.lddp.db.SimpleResult; import org.slf4j.Logger; @@ -22,17 +24,17 @@ public class KitDDPNotification { private static final Logger logger = LoggerFactory.getLogger(KitDDPNotification.class); private final String participantId; private final String dsmKitRequestId; - private final String ddpInstanceId; + private final int ddpInstanceId; private final String instanceName; private final String baseUrl; private final String eventName; private final String eventType; private final long date; private final boolean hasAuth0Token; - private final String uploadReason; + private final KitReasonType uploadReason; private final String ddpKitRequestId; - public KitDDPNotification(String participantId, String dsmKitRequestId, String ddpInstanceId, String instanceName, String baseUrl, + public KitDDPNotification(String participantId, String dsmKitRequestId, int ddpInstanceId, String instanceName, String baseUrl, String eventName, String eventType, long date, boolean hasAuth0Token, String uploadReason, String ddpKitRequestId) { this.participantId = participantId; @@ -44,7 +46,11 @@ public KitDDPNotification(String participantId, String dsmKitRequestId, String d this.eventType = eventType; this.date = date; this.hasAuth0Token = hasAuth0Token; - this.uploadReason = uploadReason; + if (StringUtils.isBlank(uploadReason)) { + this.uploadReason = KitReasonType.NORMAL; + } else { + this.uploadReason = KitReasonType.valueOf(uploadReason); + } this.ddpKitRequestId = ddpKitRequestId; } @@ -60,7 +66,7 @@ public static KitDDPNotification getKitDDPNotification(@NonNull String query, @N if (count == expectedCount && rs.next()) { //if row is 0 the ddp/kit type combination does not trigger a participant event dbVals.resultValue = new KitDDPNotification(rs.getString(DBConstants.DDP_PARTICIPANT_ID), - rs.getString(DBConstants.DSM_KIT_REQUEST_ID), rs.getString(DBConstants.DDP_INSTANCE_ID), + rs.getString(DBConstants.DSM_KIT_REQUEST_ID), rs.getInt(DBConstants.DDP_INSTANCE_ID), rs.getString(DBConstants.INSTANCE_NAME), rs.getString(DBConstants.BASE_URL), rs.getString(DBConstants.EVENT_NAME), rs.getString(DBConstants.EVENT_TYPE), rs.getLong(DBConstants.DSM_RECEIVE_DATE), rs.getBoolean(DBConstants.NEEDS_AUTH0_TOKEN), @@ -95,7 +101,7 @@ public static KitDDPNotification getKitDDPNotification(Connection conn, @NonNull rs.beforeFirst(); if (count == expectedCount && rs.next()) { //if row is 0 the ddp/kit type combination does not trigger a participant event result = new KitDDPNotification(rs.getString(DBConstants.DDP_PARTICIPANT_ID), - rs.getString(DBConstants.DSM_KIT_REQUEST_ID), rs.getString(DBConstants.DDP_INSTANCE_ID), + rs.getString(DBConstants.DSM_KIT_REQUEST_ID), rs.getInt(DBConstants.DDP_INSTANCE_ID), rs.getString(DBConstants.INSTANCE_NAME), rs.getString(DBConstants.BASE_URL), rs.getString(DBConstants.EVENT_NAME), rs.getString(DBConstants.EVENT_TYPE), rs.getLong(DBConstants.DSM_RECEIVE_DATE), rs.getBoolean(DBConstants.NEEDS_AUTH0_TOKEN), diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/TestResultEvent.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/TestResultEvent.java deleted file mode 100644 index 47a54a5cf7..0000000000 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/TestResultEvent.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.broadinstitute.dsm.model; - -import lombok.NonNull; -import org.broadinstitute.dsm.model.birch.DSMTestResult; -import org.broadinstitute.dsm.util.KitEvent; - -public class TestResultEvent extends KitEvent { - DSMTestResult eventData; - - public TestResultEvent(String eventInfo, @NonNull String eventType, @NonNull Long eventDate, String kitUploadType, - String ddpKitRequestId, DSMTestResult result) { - super(eventInfo, eventType, eventDate, kitUploadType, ddpKitRequestId); - this.eventData = result; - } -} diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/gp/BSPKit.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/gp/BSPKit.java index 9964594bbe..ec431ff780 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/gp/BSPKit.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/gp/BSPKit.java @@ -1,6 +1,5 @@ package org.broadinstitute.dsm.model.gp; -import java.sql.Connection; import java.util.Optional; import lombok.NonNull; @@ -9,9 +8,7 @@ import org.broadinstitute.dsm.db.dto.kit.BSPKitDto; import org.broadinstitute.dsm.model.KitDDPNotification; import org.broadinstitute.dsm.model.gp.bsp.BSPKitStatus; -import org.broadinstitute.dsm.statics.ApplicationConfigConstants; -import org.broadinstitute.dsm.util.DSMConfig; -import org.broadinstitute.dsm.util.EventUtil; +import org.broadinstitute.dsm.service.EventService; import org.broadinstitute.dsm.util.NotificationUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -19,6 +16,13 @@ public class BSPKit extends GPReceivedKit { private static Logger logger = LoggerFactory.getLogger(BSPKit.class); + public static final String SQL_SELECT_KIT_INFO_FOR_NOTIFICATION_EMAIL = "select eve.event_name, eve.event_type," + + " request.ddp_participant_id, request.dsm_kit_request_id, request.ddp_kit_request_id, request.upload_reason, " + + " realm.ddp_instance_id, realm.instance_name, realm.base_url, realm.auth0_token, realm.notification_recipients, " + + " 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 = ?"; public Optional getKitStatus(@NonNull BSPKitDto bspKitQueryResult, NotificationUtil notificationUtil) { if (StringUtils.isNotBlank(bspKitQueryResult.getParticipantExitId())) { @@ -42,14 +46,13 @@ public Optional canReceiveKit(@NonNull String kitLabel) { } } - public void triggerDDP(Connection conn, @NonNull BSPKitDto bspKitInfo, boolean firstTimeReceived, String kitLabel) { + public void triggerDDP(@NonNull BSPKitDto bspKitInfo, boolean firstTimeReceived, String kitLabel) { try { if (bspKitInfo.isHasParticipantNotifications() && firstTimeReceived) { - KitDDPNotification kitDDPNotification = KitDDPNotification.getKitDDPNotification( - DSMConfig.getSqlFromConfig(ApplicationConfigConstants.GET_RECEIVED_KIT_INFORMATION_FOR_NOTIFICATION_EMAIL), + KitDDPNotification kitDDPNotification = KitDDPNotification.getKitDDPNotification(SQL_SELECT_KIT_INFO_FOR_NOTIFICATION_EMAIL, kitLabel, 1); if (kitDDPNotification != null) { - EventUtil.triggerDDP(conn, kitDDPNotification); + EventService.sendKitEventToDss(kitDDPNotification); } } } catch (Exception e) { diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/gp/GPReceivedKit.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/gp/GPReceivedKit.java index 5fe128d07f..e851596973 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/gp/GPReceivedKit.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/gp/GPReceivedKit.java @@ -82,18 +82,18 @@ public static Optional receiveKit(String kitLabel, BSPKitDto bspKitQuer } - private static void updateKitAndExport(String kitLabel, BSPKitDao bspKitDao, BSPKitDto maybeBspKitQueryResult, boolean triggerDDP, + private static void updateKitAndExport(String kitLabel, BSPKitDao bspKitDao, BSPKitDto bspKitQueryResult, boolean triggerDDP, String receiver) { long receivedDate = System.currentTimeMillis(); - bspKitDao.setKitReceivedAndTriggerDDP(kitLabel, triggerDDP, maybeBspKitQueryResult, receiver); + + DDPInstanceDto ddpInstanceDto = + new DDPInstanceDao().getDDPInstanceByInstanceName(bspKitQueryResult.getInstanceName()).orElseThrow(); + bspKitDao.setKitReceivedAndTriggerDDP(kitLabel, triggerDDP, bspKitQueryResult, receiver); KitRequestShipping kitRequestShipping = new KitRequestShipping(); kitRequestShipping.setReceiveDate(receivedDate); kitRequestShipping.setKitLabel(kitLabel); - DDPInstanceDto ddpInstanceDto = - new DDPInstanceDao().getDDPInstanceByInstanceName(maybeBspKitQueryResult.getInstanceName()).orElseThrow(); - if (StringUtils.isNotBlank(ddpInstanceDto.getEsParticipantIndex())) { try { UpsertPainlessFacade.of(DBConstants.DDP_KIT_REQUEST_ALIAS, kitRequestShipping, ddpInstanceDto, ESObjectConstants.KIT_LABEL, diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/kit/KitFinalSentBaseUseCase.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/kit/KitFinalSentBaseUseCase.java index 62c1f58735..58f287f97d 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/kit/KitFinalSentBaseUseCase.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/kit/KitFinalSentBaseUseCase.java @@ -2,54 +2,58 @@ import java.util.Optional; -import org.broadinstitute.ddp.db.TransactionWrapper; import org.broadinstitute.dsm.db.KitRequestShipping; import org.broadinstitute.dsm.db.dao.kit.KitDao; import org.broadinstitute.dsm.model.KitDDPNotification; import org.broadinstitute.dsm.model.elastic.export.painless.PutToNestedScriptBuilder; import org.broadinstitute.dsm.model.elastic.export.painless.UpsertPainlessFacade; import org.broadinstitute.dsm.route.kit.KitPayload; -import org.broadinstitute.dsm.statics.ApplicationConfigConstants; +import org.broadinstitute.dsm.service.EventService; import org.broadinstitute.dsm.statics.DBConstants; -import org.broadinstitute.dsm.util.DSMConfig; -import org.broadinstitute.dsm.util.EventUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public abstract class KitFinalSentBaseUseCase extends BaseKitUseCase { private static final Logger logger = LoggerFactory.getLogger(KitFinalSentBaseUseCase.class); + private static final String GET_SENT_KIT_INFORMATION_FOR_NOTIFICATION_EMAIL = + "select eve.event_name, eve.event_type, " + + "request.ddp_participant_id, request.dsm_kit_request_id, " + + "request.ddp_kit_request_id, request.upload_reason, realm.ddp_instance_id, " + + "realm.instance_name, realm.base_url, realm.auth0_token, realm.notification_recipients, " + + "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 = \"SENT\" and request.ddp_label = ?"; - public KitFinalSentBaseUseCase(KitPayload kitPayload, KitDao kitDao) { + + + protected KitFinalSentBaseUseCase(KitPayload kitPayload, KitDao kitDao) { super(kitPayload, kitDao); } - protected void trigerEventsIfSuccessfulKitUpdate(Optional result, String kit, + protected void trigerEventsIfSuccessfulKitUpdate(Optional result, String ddpLabel, KitRequestShipping kitRequestShipping) { if (isKitUpdateSuccessful(result, kitRequestShipping.getBspCollaboratorParticipantId())) { - triggerEvents(kit, kitRequestShipping); + triggerEvents(ddpLabel, kitRequestShipping); } } - protected void triggerEvents(String kit, KitRequestShipping kitRequestShipping) { + protected void triggerEvents(String ddpLabel, KitRequestShipping kitRequestShipping) { logger.info("Updated kitRequests w/ ddp_label " + kitRequestShipping.getDdpLabel()); - KitDDPNotification kitDDPNotification = KitDDPNotification.getKitDDPNotification( - DSMConfig.getSqlFromConfig(ApplicationConfigConstants.GET_SENT_KIT_INFORMATION_FOR_NOTIFICATION_EMAIL), kit, - 1); + KitDDPNotification kitDDPNotification = KitDDPNotification.getKitDDPNotification(GET_SENT_KIT_INFORMATION_FOR_NOTIFICATION_EMAIL, + ddpLabel, 1); if (kitDDPNotification != null) { - TransactionWrapper.inTransaction(conn -> { - // TODO: this should not be in a DB transaction since it makes a call to an external service -DC - EventUtil.triggerDDP(conn, kitDDPNotification); - return null; - }); + EventService.sendKitEventToDss(kitDDPNotification); } if (kitPayload.getDdpInstanceDto().isESUpdatePossible()) { try { UpsertPainlessFacade.of(DBConstants.DDP_KIT_REQUEST_ALIAS, kitRequestShipping, kitPayload.getDdpInstanceDto(), "ddpLabel", "ddpLabel", - kit, new PutToNestedScriptBuilder()).export(); + ddpLabel, new PutToNestedScriptBuilder()).export(); } catch (Exception e) { - logger.error(String.format("Error updating ddp label for kit with label: %s", kit)); + logger.error(String.format("Error updating ddp label for kit with ddpLabel: %s", ddpLabel)); e.printStackTrace(); } } diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/patch/BasePatch.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/patch/BasePatch.java index ced42b8ccc..7f4ea8b744 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/patch/BasePatch.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/patch/BasePatch.java @@ -1,7 +1,5 @@ package org.broadinstitute.dsm.model.patch; -import static org.broadinstitute.ddp.db.TransactionWrapper.inTransaction; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -29,10 +27,10 @@ import org.broadinstitute.dsm.model.elastic.export.ExportFacadePayload; import org.broadinstitute.dsm.model.elastic.export.generate.GeneratorPayload; import org.broadinstitute.dsm.model.participant.data.FamilyMemberConstants; +import org.broadinstitute.dsm.service.EventService; import org.broadinstitute.dsm.statics.DBConstants; import org.broadinstitute.dsm.statics.ESObjectConstants; import org.broadinstitute.dsm.util.ElasticSearchUtil; -import org.broadinstitute.dsm.util.EventUtil; import org.broadinstitute.dsm.util.ParticipantUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -45,6 +43,8 @@ public abstract class BasePatch { protected static final String STATUS = "status"; protected static final Gson GSON = new GsonBuilder().serializeNulls().create(); static final Logger logger = LoggerFactory.getLogger(BasePatch.class); + + private EventDao eventDao = new EventDao(); protected static Map NULL_KEY; protected Patch patch; protected Profile profile; @@ -210,18 +210,15 @@ protected void writeESWorkflow(@NonNull Patch patch, @NonNull NameValue nameValu } protected void triggerParticipantEvent(DDPInstance ddpInstance, Patch patch, Value action) { - final EventDao eventDao = new EventDao(); final EventTypeDao eventTypeDao = new EventTypeDao(); Optional eventType = eventTypeDao.getEventTypeByEventNameAndInstanceId(action.getName(), ddpInstance.getDdpInstanceId()); eventType.ifPresent(eventTypeDto -> { boolean participantHasTriggeredEventByEventType = - eventDao.hasTriggeredEventByEventTypeAndDdpParticipantId(action.getName(), patch.getParentId()).orElse(false); + eventDao.isEventTriggeredForParticipant(action.getName(), patch.getParentId()); if (!participantHasTriggeredEventByEventType) { - inTransaction((conn) -> { - EventUtil.triggerDDP(conn, eventType, patch.getParentId()); - return null; - }); + String type = eventTypeDto.getEventName(); + EventService.sendParticipantEventToDss(type, ddpInstance, patch.getParentId()); } else { logger.info("Participant " + patch.getParentId() + " was already triggered for event type " + action.getName()); } diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/stool/upload/StoolUploadService.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/stool/upload/StoolUploadService.java index 15f6965d6e..7050c8ec37 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/stool/upload/StoolUploadService.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/model/stool/upload/StoolUploadService.java @@ -2,15 +2,13 @@ import java.util.List; -import org.broadinstitute.ddp.db.TransactionWrapper; import org.broadinstitute.dsm.db.dao.stoolupload.StoolUploadDao; import org.broadinstitute.dsm.db.dao.stoolupload.StoolUploadDto; import org.broadinstitute.dsm.files.parser.AbstractRecordsParser; import org.broadinstitute.dsm.files.parser.stool.TSVStoolUploadRecordsParser; import org.broadinstitute.dsm.model.KitDDPNotification; -import org.broadinstitute.dsm.statics.ApplicationConfigConstants; -import org.broadinstitute.dsm.util.DSMConfig; -import org.broadinstitute.dsm.util.EventUtil; +import org.broadinstitute.dsm.model.gp.BSPKit; +import org.broadinstitute.dsm.service.EventService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,14 +32,10 @@ private void updateKitAndThenSendNotification(StoolUploadDto stoolUploadDto) { boolean updated = stoolUploadDao.updateKit(stoolUploadDto); if (updated) { KitDDPNotification kitDDPNotification = KitDDPNotification.getKitDDPNotification( - DSMConfig.getSqlFromConfig(ApplicationConfigConstants.GET_RECEIVED_KIT_INFORMATION_FOR_NOTIFICATION_EMAIL), - stoolUploadDto.getMfBarcode(), 1); + BSPKit.SQL_SELECT_KIT_INFO_FOR_NOTIFICATION_EMAIL, stoolUploadDto.getMfBarcode(), 1); if (kitDDPNotification != null) { logger.info("Triggering DDP to send emails"); - TransactionWrapper.inTransaction(conn -> { - EventUtil.triggerDDP(conn, kitDDPNotification); - return null; - }); + EventService.sendKitEventToDss(kitDDPNotification); } else { logger.warn(String.format("No notification was found for barcode %s", stoolUploadDto.getMfBarcode())); } diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/pubsub/MercuryOrderStatusListener.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/pubsub/MercuryOrderStatusListener.java index 70f29fadce..3d9f8be540 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/pubsub/MercuryOrderStatusListener.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/pubsub/MercuryOrderStatusListener.java @@ -14,13 +14,12 @@ import lombok.extern.slf4j.Slf4j; import org.broadinstitute.dsm.db.dao.mercury.MercuryOrderDao; import org.broadinstitute.dsm.exception.DSMPubSubException; -import org.broadinstitute.dsm.exception.DsmInternalError; import org.broadinstitute.dsm.model.mercury.BaseMercuryStatusMessage; @Slf4j public class MercuryOrderStatusListener { - private MercuryOrderStatusListener(){ + private MercuryOrderStatusListener() { throw new IllegalStateException("Utility class"); } diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/route/ClinicalKitsRoute.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/route/ClinicalKitsRoute.java index fb82e49d27..ea32ea8466 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/route/ClinicalKitsRoute.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/route/ClinicalKitsRoute.java @@ -23,7 +23,7 @@ public class ClinicalKitsRoute implements Route { private static final Logger logger = LoggerFactory.getLogger(ClinicalKitsRoute.class); - + private final ClinicalKitDao clinicalKitDao = new ClinicalKitDao(); private NotificationUtil notificationUtil; public ClinicalKitsRoute(@NonNull NotificationUtil notificationUtil) { @@ -72,7 +72,7 @@ private ClinicalKitDto getClinicalKit(String kitLabel, Optional optio clinicalKit.setSampleCollection(ClinicalKitDao.PECGS); DDPInstance ddpInstance = DDPInstance.getDDPInstance(kitInfo.getRealm()); clinicalKit.setNecessaryParticipantDataToClinicalKit(ddpParticipantId, ddpInstance); - ClinicalKitDao.ifTissueAccessionedTriggerDDP(ddpParticipantId, ddpInstance); + clinicalKitDao.triggerRequiredSamplesReceivedEvent(ddpParticipantId, ddpInstance); return clinicalKit; } } diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/route/ParticipantEventRoute.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/route/SkippedParticipantEventRoute.java similarity index 81% rename from pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/route/ParticipantEventRoute.java rename to pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/route/SkippedParticipantEventRoute.java index 84a4502b2e..f48eea9eb5 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/route/ParticipantEventRoute.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/route/SkippedParticipantEventRoute.java @@ -4,7 +4,7 @@ import com.google.gson.JsonParser; import org.apache.commons.lang3.StringUtils; import org.broadinstitute.dsm.db.DDPInstance; -import org.broadinstitute.dsm.db.ParticipantEvent; +import org.broadinstitute.dsm.db.dao.SkippedParticipantEventDao; import org.broadinstitute.dsm.security.RequestHandler; import org.broadinstitute.dsm.statics.RequestParameter; import org.broadinstitute.dsm.statics.UserErrorMessages; @@ -15,9 +15,10 @@ import spark.Request; import spark.Response; -public class ParticipantEventRoute extends RequestHandler { +public class SkippedParticipantEventRoute extends RequestHandler { - private static final Logger logger = LoggerFactory.getLogger(ParticipantEventRoute.class); + private static final Logger logger = LoggerFactory.getLogger(SkippedParticipantEventRoute.class); + SkippedParticipantEventDao skippedParticipantEventDao = new SkippedParticipantEventDao(); @Override public Object processRequest(Request request, Response response, String userId) throws Exception { @@ -25,7 +26,7 @@ public Object processRequest(Request request, Response response, String userId) String realm = request.params(RequestParameter.REALM); if (StringUtils.isNotBlank(realm)) { if (UserUtil.checkUserAccess(realm, userId, "participant_event", null)) { - return ParticipantEvent.getSkippedParticipantEvents(realm); + return skippedParticipantEventDao.getSkippedParticipantEvents(realm); } else { response.status(500); return new Result(500, UserErrorMessages.NO_RIGHTS); @@ -43,7 +44,7 @@ public Object processRequest(Request request, Response response, String userId) String userIdRequest = jsonObject.getAsJsonObject().get("user").getAsString(); String eventType = jsonObject.getAsJsonObject().get("eventType").getAsString(); - ParticipantEvent.skipParticipantEvent(ddpParticipantId, currentTime, userIdRequest, instance, eventType); + skippedParticipantEventDao.skipParticipantEvent(ddpParticipantId, currentTime, userIdRequest, instance, eventType); return new Result(200); } else { response.status(500); diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/service/EventService.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/service/EventService.java new file mode 100644 index 0000000000..6b20577678 --- /dev/null +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/service/EventService.java @@ -0,0 +1,203 @@ +package org.broadinstitute.dsm.service; + +import java.util.Collection; +import java.util.concurrent.Callable; + +import com.google.common.annotations.VisibleForTesting; +import com.sun.istack.NotNull; +import io.github.resilience4j.core.IntervalFunction; +import io.github.resilience4j.retry.Retry; +import io.github.resilience4j.retry.RetryConfig; +import lombok.NonNull; +import org.broadinstitute.ddp.notficationevent.DsmNotificationPayload; +import org.broadinstitute.ddp.notficationevent.KitReasonType; +import org.broadinstitute.dsm.db.DDPInstance; +import org.broadinstitute.dsm.db.dao.SkippedParticipantEventDao; +import org.broadinstitute.dsm.db.dao.queue.EventDao; +import org.broadinstitute.dsm.model.KitDDPNotification; +import org.broadinstitute.dsm.statics.RoutePath; +import org.broadinstitute.dsm.util.DDPRequestUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EventService { + private static final Logger logger = LoggerFactory.getLogger(EventService.class); + protected static final int MAX_TRIES = 5; + private static final EventDao eventDao = new EventDao(); + private static final SkippedParticipantEventDao skippedParticipantEventDao = new SkippedParticipantEventDao(); + + /** + *

+ * Called from Kit Classes, this method adds the kit event to the EVENT_QUEUE table and triggers the Dss for the event. + * If the event is skipped for this participant, the event will not be triggered, just added into the EVENT_QUEUE table. + *

+ * The event that is sent to DSS has the ddpKitRequestId as the eventInfo, however, the event that is added to the + * EVENT_QUEUE table will have the dsmKitRequestId as the eventInfo. + *

+ * @param kitDDPNotification - the kit event to be triggered + * */ + public static void sendKitEventToDss(@NonNull KitDDPNotification kitDDPNotification) { + boolean dssSuccessfullyTriggered = false; + if (isParticipantEventSkipped(kitDDPNotification)) { + logger.info("Participant event was skipped per data in participant_event table. DDP will not get triggered"); + } else { + dssSuccessfullyTriggered = triggerDssByKitEvent(kitDDPNotification); + } + addKitEvent(kitDDPNotification.getEventName(), kitDDPNotification.getDdpInstanceId(), + kitDDPNotification.getDsmKitRequestId(), dssSuccessfullyTriggered); + } + + /** + * Returns true if this event is skipped for this participant, false otherwise + * */ + private static boolean isParticipantEventSkipped(KitDDPNotification kitDDPNotification) { + return skippedParticipantEventDao.isParticipantEventSkipped(kitDDPNotification.getParticipantId(), + kitDDPNotification.getEventName(), kitDDPNotification.getDdpInstanceId()); + } + + /** + * Called in ClinicalKitDao and BasePatch classes, this method adds the participant event to the EVENT_QUEUE table + * and triggers the Dss for the event. + * The Only participant_event currently in DSM is "REQUIRED_SAMPLES_RECEIVED" for PE-CGS studies + * */ + public static void sendParticipantEventToDss(String eventName, DDPInstance ddpInstance, @NotNull String ddpParticipantId) { + int ddpInstanceId = ddpInstance.getDdpInstanceIdAsInt(); + if (!skippedParticipantEventDao.isParticipantEventSkipped(ddpParticipantId, eventName, ddpInstanceId)) { + boolean dssSuccessfullyTriggered = triggerDssWithEvent(eventName, ddpInstance, System.currentTimeMillis() / 1000, + ddpParticipantId, ddpParticipantId, KitReasonType.NORMAL); + addParticipantEvent(eventName, ddpInstanceId, ddpParticipantId, dssSuccessfullyTriggered); + } else { + logger.info("Participant event was skipped for event %s for participant %s ".formatted(eventName, ddpParticipantId) + .concat("based on participant_event table. Dss will not get triggered")); + //add this event to the EVENT_QUEUE table, but without triggering dss and flag EVENT_TRIGGERED = false + addParticipantEvent(eventName, ddpInstanceId, ddpParticipantId, false); + } + } + + /** + * Sends a POST request to DSS to trigger the event for a kit, using the information in the KitDDPNotification object. + * */ + @VisibleForTesting + protected static boolean triggerDssByKitEvent(KitDDPNotification kitDDPNotification) { + DDPInstance ddpInstance = DDPInstance.getDDPInstanceById(kitDDPNotification.getDdpInstanceId()); + return triggerDssWithEvent(kitDDPNotification.getEventName(), ddpInstance, + kitDDPNotification.getDate() / 1000, kitDDPNotification.getParticipantId(), + kitDDPNotification.getDdpKitRequestId(), kitDDPNotification.getUploadReason()); + } + + /** + * Tries to send a POST request to DSS to trigger the event for a kit or a participant, + * It will try MAX_TRIES times before giving up and adding the event to the EVENT_QUEUE table. + * @param eventType - the type of event to be triggered, e.g. "SALIVA_RECEIVED" + * @param eventInfo - the information to be sent in the event, for kit events it is the "ddp_kit_request_id", + * and for participant events it is the ddp_participant_id + * @return true if the request was successful, false otherwise + * */ + @VisibleForTesting + protected static boolean triggerDssWithEvent(@NonNull String eventType, DDPInstance ddpInstance, long eventDate, + @NotNull String ddpParticipantId, @NotNull String eventInfo, KitReasonType reason) { + final long initialInterval = 500; // base delay in milliseconds + final double multiplier = 2.0; // exponential backoff multiplier + + IntervalFunction intervalFn = IntervalFunction.ofExponentialBackoff(initialInterval, multiplier); + RetryConfig retryConfig = RetryConfig.custom() + .maxAttempts(MAX_TRIES) + .intervalFunction(intervalFn) + .build(); + Retry retry = Retry.of("triggerDssWithEvent", retryConfig); + retry.getEventPublisher() + .onRetry(event -> logger.warn("{}", event)); + Callable triggerDssWithEventCallable = Retry.decorateCallable(retry, () -> { + boolean success = false; + try { + success = sendDDPEventRequest(eventType, ddpInstance, eventDate, ddpParticipantId, eventInfo, reason); + } catch (Exception e) { + logTriggerFailure(ddpInstance, eventType, ddpParticipantId, eventInfo, e); + } + if (success) { + return true; + } else { + throw new Exception("Failed to trigger event"); + } + }); + + try { + return triggerDssWithEventCallable.call(); + } catch (Exception e) { + logTriggerExhausted(ddpInstance, eventType, ddpParticipantId, eventInfo); + return false; + } + } + + /** + * Sends the POST request to DSS to trigger the event for a kit or a participant. + * @return true if the request was successful, false otherwise + * */ + @VisibleForTesting + protected static boolean sendDDPEventRequest(String eventType, DDPInstance ddpInstance, long eventDate, String ddpParticipantId, + String eventInfo, KitReasonType reason) throws Exception { + DsmNotificationPayload event = new DsmNotificationPayload(eventType, eventDate, reason, eventInfo); + String sendRequest = ddpInstance.getBaseUrl() + RoutePath.DDP_PARTICIPANT_EVENT_PATH + "/" + ddpParticipantId; + int responseCode = DDPRequestUtil.postRequest(sendRequest, event, ddpInstance.getName(), ddpInstance.isHasAuth0Token()); + if (responseCode == 200) { + return true; + } + logger.error("Bad Response: Failed to trigger {} to notify participant {} about {} for dsm_kit_request_id {}, response code {}", + ddpInstance.getName(), ddpParticipantId, eventType, eventInfo, responseCode); + return false; + } + + /** + * logs the failure of the trigger event to DSS + * */ + @VisibleForTesting + protected static void logTriggerFailure(DDPInstance ddpInstance, String eventType, String ddpParticipantId, String eventInfo, + Exception e) { + logger.warn("Failed to trigger {} to notify participant {} about {} for dsm_kit_request_id {}", + ddpInstance.getName(), ddpParticipantId, eventType, eventInfo); + logger.error("Error: ", e); + } + + /** + * logs the exhaustion of the tries to trigger the event to DSS + * */ + @VisibleForTesting + protected static void logTriggerExhausted(DDPInstance ddpInstance, String eventType, String ddpParticipantId, String eventInfo) { + logger.error("DSM was unable to send the trigger to DSS for study {}, participant {}, event type {} and event info {}," + + " exhausted all tries. Event will be added to the EVENT_QUEUE table with trigger false", ddpInstance.getName(), + ddpParticipantId, eventType, eventInfo); + } + + /** + * Adds a kit event to the EVENT_QUEUE table + * */ + private static void addKitEvent(@NonNull String name, @NonNull int ddpInstanceID, @NonNull String requestId, boolean trigger) { + eventDao.insertEvent(name, ddpInstanceID, null, requestId, trigger); + + } + + /** + * Adds a Participant event to the EVENT_QUEUE table + * */ + private static void addParticipantEvent(@NonNull String name, @NonNull int instanceID, @NonNull String ddpParticipantId, + boolean trigger) { + eventDao.insertEvent(name, instanceID, ddpParticipantId, null, trigger); + } + + /** + * Triggers the reminder emails for kits that were sent out but have not been received yet. + * The events tell DSS the list of kits that need reminders, and then DSS will send the reminder emails. + * It's called from the DDPEventJob class + * */ + public static void triggerReminder() { + logger.info("Triggering reminder emails now"); + Collection kitDDPNotifications = eventDao.getKitsNotReceived(); + for (KitDDPNotification kitInfo : kitDDPNotifications) { + if (KitDDPNotification.REMINDER.equals(kitInfo.getEventType())) { + sendKitEventToDss(kitInfo); + } else { + logger.error("Event type {} is not a reminder event", kitInfo.getEventType()); + } + } + } +} diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/statics/ApplicationConfigConstants.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/statics/ApplicationConfigConstants.java index aa5aae348e..9b12eba3bf 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/statics/ApplicationConfigConstants.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/statics/ApplicationConfigConstants.java @@ -83,8 +83,6 @@ public class ApplicationConfigConstants { public static final String EMAIL_NOTIFICATIONS_SEND_GRID_TEMPLATE_ID = "sendGridTemplate"; //db queries - public static final String GET_RECEIVED_KIT_INFORMATION_FOR_NOTIFICATION_EMAIL = "portal.selectReceivedKitForNotification"; - public static final String GET_SENT_KIT_INFORMATION_FOR_NOTIFICATION_EMAIL = "portal.selectSentKitForNotification"; public static final String GET_ALLOWED_REALMS_FOR_USER_ROLE_STARTS_LIKE = "portal.selectAllowedRealmsStartsLike"; public static final String GET_ROLES_LIKE = "portal.getRoles"; public static final String UPDATE_KIT_REQUEST = "portal.updateKitRequest"; diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/statics/DBConstants.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/statics/DBConstants.java index cb11276014..58c17ac678 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/statics/DBConstants.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/statics/DBConstants.java @@ -374,6 +374,9 @@ private DBConstants() { //eventType public static final String EVENT_NAME = "event_name"; public static final String EVENT_TYPE = "event_type"; + public static final String EVENT_DATE_CREATED = "EVENT_DATE_CREATED"; + public static final String EVENT_TRIGGERED = "EVENT_TRIGGERED"; + public static final String EVENT_ID = "EVENT_ID"; public static final String EVENT_DESCRIPTION = "event_description"; public static final String EVENT = "event"; diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/util/DDPRequestUtil.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/util/DDPRequestUtil.java index ed3a8605da..120cab1fd6 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/util/DDPRequestUtil.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/util/DDPRequestUtil.java @@ -94,7 +94,7 @@ public static T getResponseObjectWithCustomHeader(Class responseClass, St // make a post request public static Integer postRequest(String sendRequest, Object objectToPost, String name, boolean auth0Token) - throws IOException, RuntimeException { + throws IOException { logger.info("Requesting data from " + name + " w/ " + sendRequest); org.apache.http.client.fluent.Request request = SecurityUtil.createPostRequestWithHeader(sendRequest, name, auth0Token, objectToPost); diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/util/EventUtil.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/util/EventUtil.java deleted file mode 100644 index 5bd11e6a6e..0000000000 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/util/EventUtil.java +++ /dev/null @@ -1,276 +0,0 @@ -package org.broadinstitute.dsm.util; - -import static org.broadinstitute.ddp.db.TransactionWrapper.inTransaction; - -import javax.annotation.Nonnull; -import java.io.IOException; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Optional; - -import com.sun.istack.NotNull; -import lombok.NonNull; -import org.broadinstitute.ddp.db.TransactionWrapper; -import org.broadinstitute.dsm.db.ParticipantEvent; -import org.broadinstitute.dsm.db.dto.settings.EventTypeDto; -import org.broadinstitute.dsm.model.KitDDPNotification; -import org.broadinstitute.dsm.model.TestResultEvent; -import org.broadinstitute.dsm.model.birch.DSMTestResult; -import org.broadinstitute.dsm.model.birch.TestBostonResult; -import org.broadinstitute.dsm.statics.DBConstants; -import org.broadinstitute.dsm.statics.RoutePath; -import org.broadinstitute.lddp.db.SimpleResult; -import org.broadinstitute.dsm.security.Auth0Util; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class EventUtil { - - public static final String SQL_SELECT_KIT_FOR_REMINDER_EMAILS = - "SELECT eve.event_name, eve.event_type, request.ddp_participant_id, request.dsm_kit_request_id, realm.instance_name, " - + "realm.base_url, " - + "realm.ddp_instance_id, realm.auth0_token, realm.notification_recipients, kit.receive_date, kit.scan_date, " - + "request.upload_reason, request.ddp_kit_request_id, " - + "(SELECT count(role.name) FROM ddp_instance realm2, ddp_instance_role inRol, instance_role role " - + "WHERE realm2.ddp_instance_id = inRol.ddp_instance_id AND inRol.instance_role_id = role.instance_role_id " - + "AND role.name = ? AND realm2.ddp_instance_id = realm.ddp_instance_id) AS 'has_role' " - + "FROM ddp_kit_request request LEFT JOIN ddp_kit kit ON (kit.dsm_kit_request_id = request.dsm_kit_request_id) " - + "LEFT JOIN ddp_instance realm ON (request.ddp_instance_id = realm.ddp_instance_id) " - + "LEFT JOIN ddp_participant_exit ex ON (ex.ddp_participant_id = request.ddp_participant_id " - + "AND ex.ddp_instance_id = request.ddp_instance_id) " - + "LEFT JOIN event_type eve ON (eve.ddp_instance_id = request.ddp_instance_id " - + "AND eve.kit_type_id = request.kit_type_id " - + "AND eve.event_type = 'REMINDER') " - + "LEFT JOIN EVENT_QUEUE queue ON (queue.DSM_KIT_REQUEST_ID = request.dsm_kit_request_id " - + "AND queue.EVENT_TYPE = eve.event_name) " - + "WHERE ex.ddp_participant_exit_id IS NULL AND kit.scan_date IS NOT NULL " - + "AND kit.scan_date <= (UNIX_TIMESTAMP(NOW())-(eve.hours*60*60))*1000 " - + "AND kit.receive_date IS NULL AND kit.deactivated_date IS NULL AND realm.is_active = 1 AND queue.EVENT_TYPE IS NULL"; - private static final Logger logger = LoggerFactory.getLogger(EventUtil.class); - private static final String SQL_INSERT_EVENT = - "INSERT INTO EVENT_QUEUE SET EVENT_DATE_CREATED = ?, EVENT_TYPE = ?, DDP_INSTANCE_ID = ?, " - + "DSM_KIT_REQUEST_ID = ?, EVENT_TRIGGERED = ?"; - private static final String SQL_INSERT_PT_EVENT = - "INSERT INTO EVENT_QUEUE SET EVENT_DATE_CREATED = ?, EVENT_TYPE = ?, DDP_INSTANCE_ID = ?, " - + "DDP_PARTICIPANT_ID = ?, EVENT_TRIGGERED = ?"; - - public static void triggerDDP(Connection conn, @NonNull KitDDPNotification kitDDPNotification) { - Collection events = - ParticipantEvent.getParticipantEvent(conn, kitDDPNotification.getParticipantId(), kitDDPNotification.getDdpInstanceId()); - if (!events.contains(kitDDPNotification.getEventName())) { - EventUtil.triggerDDP(conn, kitDDPNotification.getEventName(), kitDDPNotification); - } else { - logger.info("Participant direct event was added in the participant_event table. DDP will not get triggered"); - //to add these events also to the event table, but without triggering the ddp and flag EVENT_TRIGGERED = false - addEvent(conn, kitDDPNotification.getEventName(), kitDDPNotification.getDdpInstanceId(), - kitDDPNotification.getDsmKitRequestId(), false); - } - } - - public static void triggerDDP(Connection conn, @NonNull Optional eventTypes, @NotNull String ddpParticipantId) { - Collection events = ParticipantEvent.getParticipantEvent(conn, ddpParticipantId, eventTypes.get().getDdpInstanceId()); - if (!events.contains(eventTypes.get().getEventName())) { - EventUtil.triggerDDP(conn, eventTypes.get().getEventName(), eventTypes, ddpParticipantId); - } else { - logger.info("Participant direct event was added in the participant_event table. DDP will not get triggered"); - //to add these events also to the event table, but without triggering the ddp and flag EVENT_TRIGGERED = false - addEvent(conn, eventTypes.get().getEventName(), eventTypes.get().getDdpInstanceId(), ddpParticipantId, false); - } - } - - private static void triggerDDP(Connection conn, @NonNull String eventType, @NonNull KitDDPNotification kitInfo) { - try { - KitEvent event = new KitEvent(kitInfo.getParticipantId(), eventType, kitInfo.getDate() / 1000, kitInfo.getUploadReason(), - kitInfo.getDdpKitRequestId()); - String sendRequest = kitInfo.getBaseUrl() + RoutePath.DDP_PARTICIPANT_EVENT_PATH + "/" + kitInfo.getParticipantId(); - DDPRequestUtil.postRequest(sendRequest, event, kitInfo.getInstanceName(), kitInfo.isHasAuth0Token()); - addEvent(conn, eventType, kitInfo.getDdpInstanceId(), kitInfo.getDsmKitRequestId()); - } catch (IOException e) { - logger.error( - "Failed to trigger " + kitInfo.getInstanceName() + " to notify participant " + kitInfo.getParticipantId() + " about " - + eventType + " for dsm_kit_request_id " + kitInfo.getDsmKitRequestId()); - e.printStackTrace(); - //to add these events also to the event table, but without triggering the ddp and flag EVENT_TRIGGERED = false - addEvent(conn, eventType, kitInfo.getDdpInstanceId(), kitInfo.getDsmKitRequestId(), false); - } catch (RuntimeException e) { - logger.error( - "Failed to trigger " + kitInfo.getInstanceName() + " to notify participant " + kitInfo.getParticipantId() + " about " - + eventType + " for dsm_kit_request_id " + kitInfo.getDsmKitRequestId()); - e.printStackTrace(); - //to add these events also to the event table, but without triggering the ddp and flag EVENT_TRIGGERED = false - addEvent(conn, eventType, kitInfo.getDdpInstanceId(), kitInfo.getDsmKitRequestId(), false); - } - } - - private static void triggerDDP(Connection conn, @NonNull String eventType, @NonNull Optional eventTypes, - @NotNull String ddpParticipantId) { - try { - KitEvent event = new KitEvent(ddpParticipantId, eventType, 0, null, ddpParticipantId); - String sendRequest = eventTypes.get().getBaseUrl() + RoutePath.DDP_PARTICIPANT_EVENT_PATH + "/" + ddpParticipantId; - DDPRequestUtil.postRequest(sendRequest, event, eventTypes.get().getInstanceName(), eventTypes.get().getAuth0Token()); - addPTEvent(conn, eventType, eventTypes.get().getDdpInstanceId(), ddpParticipantId, true); - } catch (IOException e) { - logger.error( - "Failed to trigger " + eventTypes.get().getInstanceName() + " to notify participant " + ddpParticipantId + " about " - + eventType); - e.printStackTrace(); - //to add these events also to the event table, but without triggering the ddp and flag EVENT_TRIGGERED = false - addPTEvent(conn, eventType, eventTypes.get().getDdpInstanceId(), ddpParticipantId, false); - } catch (RuntimeException e) { - logger.error( - "Failed to trigger " + eventTypes.get().getInstanceName() + " to notify participant " + ddpParticipantId + " about " - + eventType); - e.printStackTrace(); - //to add these events also to the event table, but without triggering the ddp and flag EVENT_TRIGGERED = false - addPTEvent(conn, eventType, eventTypes.get().getDdpInstanceId(), ddpParticipantId, false); - } - } - - private static void triggerDDP(Connection conn, @NonNull String eventType, @NonNull KitDDPNotification kitInfo, Auth0Util auth0Util) { - try { - KitEvent event = new KitEvent(kitInfo.getParticipantId(), eventType, kitInfo.getDate() / 1000, kitInfo.getUploadReason(), - kitInfo.getDdpKitRequestId()); - String sendRequest = kitInfo.getBaseUrl() + RoutePath.DDP_PARTICIPANT_EVENT_PATH + "/" + kitInfo.getParticipantId(); - DDPRequestUtil.postRequest(sendRequest, event, kitInfo.getInstanceName(), kitInfo.isHasAuth0Token(), auth0Util); - addEvent(conn, eventType, kitInfo.getDdpInstanceId(), kitInfo.getDsmKitRequestId()); - } catch (IOException e) { - logger.error( - "Failed to trigger " + kitInfo.getInstanceName() + " to notify participant " + kitInfo.getParticipantId() + " about " - + eventType + " for dsm_kit_request_id " + kitInfo.getDsmKitRequestId()); - e.printStackTrace(); - //to add these events also to the event table, but without triggering the ddp and flag EVENT_TRIGGERED = false - addEvent(conn, eventType, kitInfo.getDdpInstanceId(), kitInfo.getDsmKitRequestId(), false); - } catch (RuntimeException e) { - logger.error( - "Failed to trigger " + kitInfo.getInstanceName() + " to notify participant " + kitInfo.getParticipantId() + " about " - + eventType + " for dsm_kit_request_id " + kitInfo.getDsmKitRequestId()); - e.printStackTrace(); - //to add these events also to the event table, but without triggering the ddp and flag EVENT_TRIGGERED = false - addEvent(conn, eventType, kitInfo.getDdpInstanceId(), kitInfo.getDsmKitRequestId(), false); - } - } - - public static void triggerDDP(Connection conn, @NonNull KitDDPNotification kitDDPNotification, Auth0Util auth0Util) { - Collection events = - ParticipantEvent.getParticipantEvent(conn, kitDDPNotification.getParticipantId(), kitDDPNotification.getDdpInstanceId()); - if (!events.contains(kitDDPNotification.getEventName())) { - EventUtil.triggerDDP(conn, kitDDPNotification.getEventName(), kitDDPNotification, auth0Util); - } else { - logger.info("Participant direct event was added in the participant_event table. DDP will not get triggered"); - //to add these events also to the event table, but without triggering the ddp and flag EVENT_TRIGGERED = false - addEvent(conn, kitDDPNotification.getEventName(), kitDDPNotification.getDdpInstanceId(), - kitDDPNotification.getDsmKitRequestId(), false); - } - } - - public static void triggerDDPWithTestResult(Connection conn, @NonNull KitDDPNotification kitDDPNotification, - @Nonnull TestBostonResult result) { - Collection events = - ParticipantEvent.getParticipantEvent(kitDDPNotification.getParticipantId(), kitDDPNotification.getDdpInstanceId()); - if (!events.contains(kitDDPNotification.getEventName())) { - EventUtil.triggerDDPWithTestResult(conn, kitDDPNotification.getEventName(), kitDDPNotification, result); - } else { - logger.info("Participant direct event was added in the participant_event table. DDP will not get triggered"); - //to add these events also to the event table, but without triggering the ddp and flag EVENT_TRIGGERED = false - addEvent(conn, kitDDPNotification.getEventName(), kitDDPNotification.getDdpInstanceId(), - kitDDPNotification.getDsmKitRequestId(), false); - } - } - - private static void triggerDDPWithTestResult(Connection conn, @NonNull String eventType, @NonNull KitDDPNotification kitInfo, - @Nonnull TestBostonResult result) { - try { - DSMTestResult dsmTestResult = new DSMTestResult(result.getResult(), result.getTimeCompleted(), result.isCorrected()); - TestResultEvent event = - new TestResultEvent(kitInfo.getParticipantId(), eventType, kitInfo.getDate() / 1000, kitInfo.getUploadReason(), - kitInfo.getDdpKitRequestId(), dsmTestResult); - String sendRequest = kitInfo.getBaseUrl() + RoutePath.DDP_PARTICIPANT_EVENT_PATH + "/" + kitInfo.getParticipantId(); - DDPRequestUtil.postRequest(sendRequest, event, kitInfo.getInstanceName(), kitInfo.isHasAuth0Token()); - addEvent(conn, eventType, kitInfo.getDdpInstanceId(), kitInfo.getDsmKitRequestId()); - } catch (IOException e) { - logger.error("Failed to trigger DDP to notify participant about " + eventType); - //to add these events also to the event table, but without triggering the ddp and flag EVENT_TRIGGERED = false - addEvent(conn, eventType, kitInfo.getDdpInstanceId(), kitInfo.getDsmKitRequestId(), false); - } - } - - private static void addEvent(Connection conn, @NonNull String type, @NonNull String instanceID, @NonNull String requestId) { - addEvent(conn, type, instanceID, requestId, true); - } - - public static void addEvent(Connection conn, @NonNull String type, @NonNull String instanceID, @NonNull String requestId, - boolean trigger) { - addEvent(conn, type, instanceID, requestId, trigger, SQL_INSERT_EVENT); - } - - public static void addEvent(Connection conn, @NonNull String type, @NonNull String instanceID, @NonNull String requestId, - boolean trigger, String query) { - try (PreparedStatement stmt = conn.prepareStatement(query)) { - stmt.setLong(1, System.currentTimeMillis()); - stmt.setString(2, type); - stmt.setString(3, instanceID); - stmt.setString(4, requestId); - stmt.setBoolean(5, trigger); - int result = stmt.executeUpdate(); - if (result != 1) { - throw new RuntimeException("Error could not add event for kit request " + requestId); - } - } catch (SQLException e) { - logger.error("Error inserting event ", e); - } - } - - public static void addPTEvent(Connection conn, @NonNull String type, @NonNull String instanceID, @NonNull String requestId, - boolean trigger) { - addEvent(conn, type, instanceID, requestId, trigger, SQL_INSERT_PT_EVENT); - } - - public void triggerReminder() { - logger.info("Triggering reminder emails now"); - Collection kitDDPNotifications = getKitsNotReceived(); - for (KitDDPNotification kitInfo : kitDDPNotifications) { - if (KitDDPNotification.REMINDER.equals(kitInfo.getEventType())) { - TransactionWrapper.inTransaction(conn -> { - triggerDDP(conn, kitInfo); - return null; - }); - } - } - } - - public Collection getKitsNotReceived() { - ArrayList kitDDPNotifications = new ArrayList<>(); - SimpleResult results = inTransaction((conn) -> { - SimpleResult dbVals = new SimpleResult(); - try (PreparedStatement stmt = conn.prepareStatement(SQL_SELECT_KIT_FOR_REMINDER_EMAILS)) { - stmt.setString(1, DBConstants.KIT_PARTICIPANT_NOTIFICATIONS_ACTIVATED); - try (ResultSet rs = stmt.executeQuery()) { - while (rs.next()) { - if (rs.getBoolean(DBConstants.HAS_ROLE)) { - String participantId = rs.getString(DBConstants.DDP_PARTICIPANT_ID); - String realm = rs.getString(DBConstants.INSTANCE_NAME); - kitDDPNotifications.add(new KitDDPNotification(participantId, rs.getString(DBConstants.DSM_KIT_REQUEST_ID), - rs.getString(DBConstants.DDP_INSTANCE_ID), realm, rs.getString(DBConstants.BASE_URL), - rs.getString(DBConstants.EVENT_NAME), rs.getString(DBConstants.EVENT_TYPE), System.currentTimeMillis(), - rs.getBoolean(DBConstants.NEEDS_AUTH0_TOKEN), rs.getString(DBConstants.UPLOAD_REASON), - rs.getString(DBConstants.DDP_KIT_REQUEST_ID))); - } - } - } - } catch (SQLException ex) { - dbVals.resultException = ex; - } - return dbVals; - }); - - if (results.resultException != null) { - logger.error("Error getting list of kit requests which aren't received yet (for reminder emails) ", results.resultException); - } - logger.info("Found " + kitDDPNotifications.size() + " kit requests for which the ddp needs to trigger reminder emails."); - return kitDDPNotifications; - } -} diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/util/KitEvent.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/util/KitEvent.java deleted file mode 100644 index 4bcffe4982..0000000000 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/util/KitEvent.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.broadinstitute.dsm.util; - -import org.apache.commons.lang3.StringUtils; -import org.broadinstitute.lddp.handlers.util.Event; - -public class KitEvent extends Event { - private String normal = "NORMAL"; - private String kitReasonType; - private String kitRequestId; - - public KitEvent(String eventInfo, String eventType, long eventDate, String kitReasonType, String kitRequestId) { - super(eventInfo, eventType, eventDate); - if (StringUtils.isBlank(kitReasonType)) { - kitReasonType = normal; - } - this.kitReasonType = kitReasonType; - this.kitRequestId = kitRequestId; - } -} diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/util/externalshipper/GBFRequestUtil.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/util/externalshipper/GBFRequestUtil.java index 181addc036..f16da5e6f8 100644 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/util/externalshipper/GBFRequestUtil.java +++ b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/dsm/util/externalshipper/GBFRequestUtil.java @@ -2,22 +2,6 @@ import static org.broadinstitute.ddp.db.TransactionWrapper.inTransaction; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.stream.XMLInputFactory; -import javax.xml.stream.XMLStreamReader; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; -import javax.xml.xpath.XPath; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathFactory; import java.io.ByteArrayInputStream; import java.io.StringReader; import java.io.StringWriter; @@ -34,6 +18,22 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; import com.google.api.client.http.HttpStatusCodes; import com.google.gson.Gson; @@ -62,11 +62,11 @@ import org.broadinstitute.dsm.model.gbf.ShippingConfirmations; import org.broadinstitute.dsm.model.gbf.ShippingInfo; import org.broadinstitute.dsm.model.gbf.Status; +import org.broadinstitute.dsm.service.EventService; import org.broadinstitute.dsm.statics.DBConstants; import org.broadinstitute.dsm.util.DBUtil; import org.broadinstitute.dsm.util.EasyPostUtil; import org.broadinstitute.dsm.util.ElasticSearchUtil; -import org.broadinstitute.dsm.util.EventUtil; import org.broadinstitute.dsm.util.SecurityUtil; import org.broadinstitute.dsm.util.SystemUtil; import org.broadinstitute.lddp.db.SimpleResult; @@ -113,6 +113,7 @@ public class GBFRequestUtil implements ExternalShipper { private static int additionalAttempts = 1; private static int sleepInMs = 500; private static Executor blindTrustEverythingExecutor; + // public final String CANCEL_ORDER_ENDPOINT = "cancelorder"; // private final String ORDERED = "ORDERED"; private final String notFound = "NOT FOUND"; //INDICATES: we have no record of the order number @@ -495,12 +496,12 @@ public void orderStatus(Connection conn, KitRequest kit, int instanceId, boolean if (kitDeliveredNotification != null) { logger.info("Triggering DDP for kit 'DELIVERED' with external order number: " + kit.getExternalOrderNumber()); - EventUtil.triggerDDP(conn, kitDeliveredNotification); + EventService.sendKitEventToDss(kitDeliveredNotification); } else { logger.error("delivered kitDDPNotification was null for " + kit.getExternalOrderNumber()); } } - EventUtil.triggerDDP(conn, kitDDPNotification); + EventService.sendKitEventToDss(kitDDPNotification); } else { logger.error("kitDDPNotification was null for " + kit.getExternalOrderNumber()); } diff --git a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/lddp/handlers/util/Event.java b/pepper-apis/dsm-core/src/main/java/org/broadinstitute/lddp/handlers/util/Event.java deleted file mode 100755 index 90c904a772..0000000000 --- a/pepper-apis/dsm-core/src/main/java/org/broadinstitute/lddp/handlers/util/Event.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.broadinstitute.lddp.handlers.util; - -import lombok.Data; -import lombok.NonNull; - -@Data -public class Event { - - private String eventInfo; - private String eventType; - private long eventDate; - - public Event() { - } - - public Event(String eventInfo, @NonNull String eventType, @NonNull Long eventDate) { - this.eventInfo = eventInfo; - this.eventType = eventType; - this.eventDate = eventDate; - } -} diff --git a/pepper-apis/dsm-core/src/main/resources/application.conf b/pepper-apis/dsm-core/src/main/resources/application.conf index 6e099dfc15..8a64082520 100644 --- a/pepper-apis/dsm-core/src/main/resources/application.conf +++ b/pepper-apis/dsm-core/src/main/resources/application.conf @@ -516,64 +516,6 @@ portal { where dsm_kit_request_id = ? """ - selectReceivedKitForNotification:""" - select - eve.event_name, - eve.event_type, - request.ddp_participant_id, - request.dsm_kit_request_id, - request.ddp_kit_request_id, - request.upload_reason, - realm.ddp_instance_id, - realm.instance_name, - realm.base_url, - realm.auth0_token, - realm.notification_recipients, - 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 = ? - """ - - selectSentKitForNotification:""" - select - eve.event_name, - eve.event_type, - request.ddp_participant_id, - request.dsm_kit_request_id, - request.ddp_kit_request_id, - request.upload_reason, - realm.ddp_instance_id, - realm.instance_name, - realm.base_url, - realm.auth0_token, - realm.notification_recipients, - 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 = "SENT" - and request.ddp_label = ? - """ - labelSettingsQuery:""" select setting.label_setting_id, diff --git a/pepper-apis/dsm-core/src/main/resources/liquibase/PEPPER-1397_instance_role_insert.xml b/pepper-apis/dsm-core/src/main/resources/liquibase/PEPPER-1397_instance_role_insert.xml new file mode 100644 index 0000000000..5e6b46a2ce --- /dev/null +++ b/pepper-apis/dsm-core/src/main/resources/liquibase/PEPPER-1397_instance_role_insert.xml @@ -0,0 +1,19 @@ + + + + + + + SELECT COUNT(*) FROM instance_role WHERE name='kit_participant_notifications_activated'; + + + + + + + + diff --git a/pepper-apis/dsm-core/src/main/resources/master-changelog.xml b/pepper-apis/dsm-core/src/main/resources/master-changelog.xml index 7449d0be89..5fba2abf4c 100644 --- a/pepper-apis/dsm-core/src/main/resources/master-changelog.xml +++ b/pepper-apis/dsm-core/src/main/resources/master-changelog.xml @@ -148,4 +148,5 @@ + diff --git a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/RouteTestSample.java b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/RouteTestSample.java index 6aa091eee9..05a9a87fb7 100644 --- a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/RouteTestSample.java +++ b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/RouteTestSample.java @@ -415,8 +415,8 @@ public Address easyPost(String instanceId, String instanceName, DDPParticipant p EasyPostUtil easyPostUtil = EasyPostUtil.fromInstanceName(instanceName); Address toAddress = easyPostUtil.createAddress(participant, "617-714-8952"); Address returnAddress = - easyPostUtil.createAddressWithoutValidation("Broad Institute", "320 Charles St - Lab 181", "Attn. Broad Genomics", "Cambridge", "02141", - "MA", "US", "617-714-8952"); + easyPostUtil.createAddressWithoutValidation("Broad Institute", "320 Charles St - Lab 181", "Attn. Broad Genomics", + "Cambridge", "02141", "MA", "US", "617-714-8952"); Parcel parcel = easyPostUtil.createParcel("3.2", "6.9", "1.3", "5.2"); CustomsInfo customs = null; if (!"US".equals(participant.getCountry())) { @@ -659,7 +659,7 @@ public void triggerBloodReminders() { DBTestUtil.setKitToSent("FAKE_KIT_" + EVENT_UTIL_TEST + "2", "FAKE_DSM_LABEL_UID" + EVENT_UTIL_TEST + "2", System.currentTimeMillis() - (17 * DBTestUtil.WEEK)); - eventUtil.triggerReminder(); + eventService.triggerReminder(); //check kit which is just 2 weeks old is not in event table ArrayList strings = new ArrayList<>(); @@ -680,7 +680,7 @@ public void triggerBloodReminders() { //check kit which is now 18 weeks old is in event table DBTestUtil.setKitToSent("FAKE_KIT_" + EVENT_UTIL_TEST + "2", "FAKE_DSM_LABEL_UID" + EVENT_UTIL_TEST + "2", System.currentTimeMillis() - (18 * DBTestUtil.WEEK)); - eventUtil.triggerReminder(); + eventService.triggerReminder(); Assert.assertNotNull( DBTestUtil.getQueryDetail("select * from EVENT_QUEUE WHERE DSM_KIT_REQUEST_ID = ? AND EVENT_TYPE='BLOOD_SENT_4WK'", kitId, "EVENT_ID")); @@ -695,7 +695,7 @@ public void skipDDPEventBloodReminder() { + "values (\'BLOOD_SENT_2WK\', \'" + FAKE_DDP_PARTICIPANT_ID + "_tt3" + "\', \'" + INSTANCE_ID + "\', \'" + System.currentTimeMillis() + "\', \'1\')"); - eventUtil.triggerReminder(); + eventService.triggerReminder(); //check if event_triggered = 1, which would mean it was sent Assert.assertNull(DBTestUtil.getQueryDetail("select * from EVENT_QUEUE queue, ddp_kit_request request " @@ -1566,7 +1566,7 @@ public void triggerReminder() throws Exception { String kitId = triggerBloodSentEmail(suffix); DBTestUtil.setKitToSent("FAKE_MF_" + kitId, FAKE_DSM_LABEL_UID + suffix, System.currentTimeMillis() - (3 * DBTestUtil.WEEK)); - eventUtil.triggerReminder(); + eventService.triggerReminder(); //check kit which is just 3 weeks old is in event table List strings = new ArrayList<>(); strings.add(FAKE_LATEST_KIT + suffix); @@ -1577,7 +1577,7 @@ public void triggerReminder() throws Exception { "select count(dsm_kit_request_id) from EVENT_QUEUE WHERE DSM_KIT_REQUEST_ID = ? AND EVENT_TRIGGERED = 1", kitId, "count(dsm_kit_request_id)")); - eventUtil.triggerReminder(); + eventService.triggerReminder(); //check kit which is just 3 weeks old is in event table strings = new ArrayList<>(); strings.add(FAKE_LATEST_KIT + suffix); diff --git a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/TestHelper.java b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/TestHelper.java index d273a140cc..e002b05660 100644 --- a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/TestHelper.java +++ b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/TestHelper.java @@ -15,13 +15,13 @@ import org.apache.http.client.fluent.Request; import org.broadinstitute.ddp.db.TransactionWrapper; import org.broadinstitute.dsm.db.MedicalRecord; +import org.broadinstitute.dsm.service.EventService; import org.broadinstitute.dsm.statics.ApplicationConfigConstants; import org.broadinstitute.dsm.util.DBTestUtil; import org.broadinstitute.dsm.util.DDPKitRequest; import org.broadinstitute.dsm.util.DDPRequestUtil; import org.broadinstitute.dsm.util.DSMConfig; import org.broadinstitute.dsm.util.ElasticSearchUtil; -import org.broadinstitute.dsm.util.EventUtil; import org.broadinstitute.dsm.util.KitUtil; import org.broadinstitute.dsm.util.NotificationUtil; import org.broadinstitute.dsm.util.TestUtil; @@ -94,8 +94,8 @@ public class TestHelper { public static DDPRequestUtil ddpRequestUtil; public static NotificationUtil notificationUtil; public static UserUtil userUtil; - public static EventUtil eventUtil; protected static String DDP_BASE_URL; + public static EventService eventService; protected static String DSM_BASE_URL; protected static RestHighLevelClient esClient; @@ -321,7 +321,7 @@ public static void setupUtils() throws Exception { notificationUtil = new NotificationUtil(cfg); userUtil = new UserUtil(); - eventUtil = new EventUtil(); + eventService = new EventService(); } public static void setupEsClient() { diff --git a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/db/dao/mercury/ClinicalOrderDaoTest.java b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/db/dao/mercury/ClinicalOrderDaoTest.java index 159f6e18d1..365a0c1604 100644 --- a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/db/dao/mercury/ClinicalOrderDaoTest.java +++ b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/db/dao/mercury/ClinicalOrderDaoTest.java @@ -22,7 +22,7 @@ import org.broadinstitute.dsm.db.dto.ddp.participant.ParticipantDto; import org.broadinstitute.dsm.db.dto.mercury.ClinicalOrderDto; import org.broadinstitute.dsm.db.dto.mercury.MercuryOrderDto; -import org.broadinstitute.dsm.kits.TestKitUtil; +import org.broadinstitute.dsm.kits.KitTestUtil; import org.broadinstitute.dsm.util.MedicalRecordUtil; import org.broadinstitute.dsm.util.MercuryOrderTestUtil; import org.broadinstitute.dsm.util.SampleIdTestUtil; @@ -64,7 +64,7 @@ public class ClinicalOrderDaoTest extends DbTxnBaseTest { private static int oncHistoryDetailId = -1; - public static TestKitUtil testKitUtil; + public static KitTestUtil kitTestUtil; private static int ddpInstanceId = -1; @@ -81,13 +81,13 @@ public static void setup() { studyInstanceName = "ClinOrdTest" + nameAppend; String studyGroup = "ClinOrdTest" + nameAppend; - testKitUtil = new TestKitUtil(studyInstanceName, studyInstanceName, "CinOrdTest", studyGroup, - "SALIVA", null, null); - testKitUtil.setupInstanceAndSettings(); - userId = testKitUtil.adminUtil.createTestUser(generateUserEmail(), Arrays.asList(KIT_SHIPPING, PT_LIST_VIEW)); + kitTestUtil = new KitTestUtil(studyInstanceName, studyInstanceName, "CinOrdTest", studyGroup, + "SALIVA", "SALIVA", null, false); + kitTestUtil.setupInstanceAndSettings(); + userId = kitTestUtil.getAdminUtil().createTestUser(generateUserEmail(), Arrays.asList(KIT_SHIPPING, PT_LIST_VIEW)); ParticipantDto participantDto = - new ParticipantDto.Builder(testKitUtil.ddpInstanceId, System.currentTimeMillis()) + new ParticipantDto.Builder(kitTestUtil.getDdpInstanceId(), System.currentTimeMillis()) .withDdpParticipantId(ddpParticipantId) .withLastVersion(0L) .withLastVersionDate("") @@ -118,7 +118,7 @@ public static void setup() { }); oncHistoryDetailId = OncHistoryDetail.createOncHistoryDetail(medicalRecordId, "tester"); log.info("Created onc history detail {}", oncHistoryDetailId); - ddpInstanceId = testKitUtil.adminUtil.getDdpInstanceId(); + ddpInstanceId = kitTestUtil.getDdpInstanceId(); } @Test @@ -153,7 +153,7 @@ public void testGetClinicalOrdersForTissuesWhenATissueHasOrders() { String order1Barcode = "testtestBarcode"; MercuryOrderDto orderDto = mercuryOrderTestUtil.createMercuryOrder(ddpParticipantId, order1Barcode, - testKitUtil.kitTypeId, ddpInstanceId, tissueId); + kitTestUtil.getKitTypeId(), ddpInstanceId, tissueId); Map> ordersByTissue = clinicalOrderDao.getClinicalOrdersForTissueIds(tissueIds); @@ -176,16 +176,16 @@ public void testGetClinicalOrdersForTissuesWhenSomeTissuesHaveOrdersAndSomeDoNot String order1Barcode = "TestBarcode1"; - ddpInstanceId = testKitUtil.adminUtil.getDdpInstanceId(); + ddpInstanceId = kitTestUtil.getAdminUtil().getDdpInstanceId(); MercuryOrderDto orderDto = mercuryOrderTestUtil.createMercuryOrder(ddpParticipantId, order1Barcode, - testKitUtil.kitTypeId, ddpInstanceId, tissueWithOrder); + kitTestUtil.getKitTypeId(), ddpInstanceId, tissueWithOrder); log.info("Created order {} for tissue {} and sample {}", orderDto.getMercurySequencingId(), tissueWithOrder, sampleWithOrder); String order2Barcode = "TestBarcode2"; MercuryOrderDto order2Dto = mercuryOrderTestUtil.createMercuryOrder(ddpParticipantId, order2Barcode, - testKitUtil.kitTypeId, ddpInstanceId, tissueWithOrder); + kitTestUtil.getKitTypeId(), ddpInstanceId, tissueWithOrder); log.info("Created order {} for tissue {} and sample {}", order2Dto.getMercurySequencingId(), tissueWithOrder, sampleWithOrder); @@ -233,6 +233,6 @@ public static void deleteTestingData() { log.info("Deleted institution {}", institutionDto.getInstitutionId()); participantDao.delete(participantId); log.info("Deleted participant {}", participantId); - testKitUtil.deleteGeneratedData(); + kitTestUtil.deleteGeneratedData(); } } diff --git a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/juniperkits/JuniperKitCreationStatusTest.java b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/juniperkits/JuniperKitCreationStatusTest.java index 39d431301e..53147af4e2 100644 --- a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/juniperkits/JuniperKitCreationStatusTest.java +++ b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/juniperkits/JuniperKitCreationStatusTest.java @@ -23,6 +23,7 @@ import org.broadinstitute.dsm.db.dao.kit.KitCurrentStatus; import org.broadinstitute.dsm.db.dto.kit.nonPepperKit.NonPepperKitStatusDto; import org.broadinstitute.dsm.exception.DsmInternalError; +import org.broadinstitute.dsm.kits.KitTestUtil; import org.broadinstitute.dsm.model.kit.ScanResult; import org.broadinstitute.dsm.model.nonpepperkit.JuniperKitRequest; import org.broadinstitute.dsm.model.nonpepperkit.KitResponse; @@ -30,6 +31,7 @@ import org.broadinstitute.dsm.model.nonpepperkit.NonPepperStatusKitService; import org.broadinstitute.dsm.statics.DBConstants; import org.broadinstitute.dsm.util.EasyPostUtil; +import org.broadinstitute.dsm.util.NotificationUtil; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; @@ -70,21 +72,22 @@ public class JuniperKitCreationStatusTest extends DbTxnBaseTest { Tracker mockShipmentTracker = mock(Tracker.class); NonPepperKitCreationService nonPepperKitCreationService = new NonPepperKitCreationService(); NonPepperStatusKitService nonPepperStatusKitService = new NonPepperStatusKitService(); + private static KitTestUtil juniperKitUtil; @BeforeClass public static void setupJuniperBefore() { - JuniperTestSetupUtil juniperTestSetupUtil = - new JuniperTestSetupUtil(instanceName, instanceGuid, "Juniper-Test", "JuniperTestProject", "Juniper-Group"); - juniperTestSetupUtil.setupJuniperInstanceAndSettings(); + juniperKitUtil = + new KitTestUtil(instanceName, instanceGuid, "JuniperTestProject", "Juniper-Group", "SALIVA", "SALIVA", null, true); + juniperKitUtil.setupInstanceAndSettings(); ddpInstance = DDPInstance.getDDPInstanceWithRoleByStudyGuid(instanceGuid, DBConstants.JUNIPER_STUDY_INSTANCE_ROLE); } @AfterClass public static void deleteJuniperInstance() { - JuniperTestSetupUtil.deleteKitsArray(createdKitIds); - JuniperTestSetupUtil.deleteJuniperInstanceAndSettings(); + juniperKitUtil.deleteKitsArray(createdKitIds); + juniperKitUtil.deleteGeneratedData(); } @Before @@ -100,16 +103,18 @@ public void testCurrentStatusField() { createNonPepperTestKit(juniperTestKit); KitResponse kitResponse = nonPepperStatusKitService.getKitsBasedOnJuniperKitId(juniperTestKit.getJuniperKitId()); verifyStatusKitResponse(kitResponse, juniperTestKit, rand, KitCurrentStatus.KIT_WITHOUT_LABEL.getValue()); - JuniperTestSetupUtil.changeKitToQueue(juniperTestKit, mockEasyPostUtil); + juniperKitUtil.changeKitToQueue(juniperTestKit.getJuniperParticipantID(), mockEasyPostUtil); kitResponse = nonPepperStatusKitService.getKitsBasedOnJuniperKitId(juniperTestKit.getJuniperKitId()); verifyStatusKitResponse(kitResponse, juniperTestKit, rand, KitCurrentStatus.QUEUE.getValue()); juniperTestKit.setDdpLabel(kitResponse.getKits().get(0).getDsmShippingLabel()); - List scanResultList = JuniperTestSetupUtil.changeKitToSent(juniperTestKit); + List scanResultList = juniperKitUtil.changeKitToSent(juniperTestKit.getDdpLabel(), + "SOME_RANDOM_KIT_LABEL"); Assert.assertFalse( scanResultList.stream().filter(scanError -> scanError.hasError()).findAny().isPresent()); kitResponse = nonPepperStatusKitService.getKitsBasedOnJuniperKitId(juniperTestKit.getJuniperKitId()); verifyStatusKitResponse(kitResponse, juniperTestKit, rand, KitCurrentStatus.SENT.getValue()); - JuniperTestSetupUtil.changeKitToReceived(); + NotificationUtil notificationUtil = mock(NotificationUtil.class); + juniperKitUtil.changeKitToReceived(notificationUtil, "SOME_RANDOM_KIT_LABEL"); kitResponse = nonPepperStatusKitService.getKitsBasedOnJuniperKitId(juniperTestKit.getJuniperKitId()); verifyStatusKitResponse(kitResponse, juniperTestKit, rand, KitCurrentStatus.RECEIVED.getValue()); diff --git a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/juniperkits/JuniperTestSetupUtil.java b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/juniperkits/JuniperTestSetupUtil.java deleted file mode 100644 index 8e9f98adee..0000000000 --- a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/juniperkits/JuniperTestSetupUtil.java +++ /dev/null @@ -1,339 +0,0 @@ -package org.broadinstitute.dsm.juniperkits; - -import static org.broadinstitute.ddp.db.TransactionWrapper.inTransaction; -import static org.broadinstitute.dsm.service.admin.UserAdminService.USER_ADMIN_ROLE; -import static org.broadinstitute.dsm.statics.DBConstants.KIT_SHIPPING; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; - -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; -import org.broadinstitute.dsm.db.KitRequestCreateLabel; -import org.broadinstitute.dsm.db.KitRequestShipping; -import org.broadinstitute.dsm.db.dao.ddp.instance.DDPInstanceDao; -import org.broadinstitute.dsm.db.dao.kit.KitDao; -import org.broadinstitute.dsm.db.dto.ddp.instance.DDPInstanceDto; -import org.broadinstitute.dsm.db.dto.kit.BSPKitDto; -import org.broadinstitute.dsm.exception.DsmInternalError; -import org.broadinstitute.dsm.model.gp.BSPKit; -import org.broadinstitute.dsm.model.gp.bsp.BSPKitStatus; -import org.broadinstitute.dsm.model.kit.KitFinalScanUseCase; -import org.broadinstitute.dsm.model.kit.ScanResult; -import org.broadinstitute.dsm.model.nonpepperkit.JuniperKitRequest; -import org.broadinstitute.dsm.route.kit.KitPayload; -import org.broadinstitute.dsm.route.kit.SentAndFinalScanPayload; -import org.broadinstitute.dsm.service.admin.UserAdminTestUtil; -import org.broadinstitute.dsm.util.EasyPostUtil; -import org.broadinstitute.dsm.util.KitUtil; -import org.broadinstitute.dsm.util.NotificationUtil; -import org.broadinstitute.lddp.db.SimpleResult; - -/** - *

- * This class has methods to set up a Juniper study in DSM database. - * It creates the instance, group, instance_role, kit_type, carrier, - * kit_dimensions, kit_return and ddp_kit_request_settings for the - * newly created study. - * It also contains methods to delete what was set up after tests are complete - *

- *

- * The usage is by first creating an instance of this class by declaring the desired instance name and study guid, - * display name and collaborator prefix. - * Then call setupJuniperInstanceAndSettings() for initiating all the config in database. - *When done, call deleteJuniperInstanceAndSettings() to delete everything - *

- */ -@Slf4j -public class JuniperTestSetupUtil { - private static final String SELECT_INSTANCE_ROLE = "SELECT instance_role_id FROM instance_role WHERE name = 'juniper_study';"; - private static final String INSERT_DDP_INSTANCE_ROLE = "INSERT INTO ddp_instance_role (ddp_instance_id, instance_role_id) " - + " VALUES (?, ?) ON DUPLICATE KEY UPDATE instance_role_id = ?;"; - private static final String SELECT_KIT_TYPE_ID = "SELECT kit_type_id FROM kit_type WHERE kit_type_name = ?"; - private static final String INSERT_KIT_DIMENSION = "INSERT INTO kit_dimension (kit_width, kit_height, kit_length, kit_weight) " - + " VALUES ('6.9', '1.3', '5.2', '3.2') ON DUPLICATE KEY UPDATE kit_width = '6.9';"; - private static final String INSERT_KIT_RETURN = "INSERT INTO kit_return_information (return_address_name, return_address_phone) " - + " VALUES ('Broad Institute', '1111112222') ON DUPLICATE KEY UPDATE return_address_name = 'Broad Institute';"; - private static final String INSERT_CARRIER = "INSERT INTO carrier_service (carrier, service) " - + " VALUES ('FedEx', 'FEDEX_2_DAY') ON DUPLICATE KEY UPDATE carrier = 'FedEx';"; - private static final String INSERT_DDP_KIT_REQUEST_SETTINGS = - "INSERT INTO ddp_kit_request_settings (ddp_instance_id, kit_type_id, kit_return_id, carrier_service_to_id, kit_dimension_id) " - + " VALUES (?, ?, ?, ?, ?) ;"; - private static final String SELECT_DSM_KIT_REQUEST_ID = "SELECT dsm_kit_request_id from ddp_kit_request where ddp_kit_request_id = ?"; - private static final UserAdminTestUtil adminUtil = new UserAdminTestUtil(); - public static String ddpGroupId; - public static String ddpInstanceId; - public static String ddpInstanceGroupId; - public static String instanceRoleId; - public static String ddpInstanceRoleId; - private static String kitTypeId; - private static String kitDimensionId; - private static String kitReturnId; - private static String carrierId; - private static String ddpKitRequestSettingsId; - private static String instanceName; - private static String groupName; - private static String studyGuid; - private static String displayName; - private static String collaboratorPrefix; - private static String userWithKitShippingAccess; - - private static NotificationUtil notificationUtil; - - public JuniperTestSetupUtil(String instanceName, String studyGuid, String displayName, String collaboratorPrefix, String groupName) { - this.instanceName = instanceName; - this.studyGuid = studyGuid; - this.displayName = displayName; - this.collaboratorPrefix = collaboratorPrefix; - this.groupName = groupName; - } - - public void setupJuniperInstanceAndSettings() { - //everything should get inserted in one transaction - SimpleResult results = inTransaction((conn) -> { - SimpleResult simpleResult = new SimpleResult(); - try { - adminUtil.createRealmAndStudyGroup(instanceName, studyGuid, collaboratorPrefix, groupName, null); - ddpInstanceId = String.valueOf(adminUtil.getDdpInstanceId()); - ddpGroupId = String.valueOf(adminUtil.getStudyGroupId()); - instanceRoleId = getInstanceRole(conn); - ddpInstanceRoleId = createDdpInstanceRole(conn); - kitTypeId = getKitTypeId(conn); - kitDimensionId = createKitDimension(conn); - kitReturnId = createKitReturnInformation(conn); - carrierId = createCarrierInformation(conn); - ddpKitRequestSettingsId = createKitRequestSettingsInformation(conn); - adminUtil.setStudyAdminAndRoles(generateUserEmail(), USER_ADMIN_ROLE, - Arrays.asList(KIT_SHIPPING)); - - userWithKitShippingAccess = Integer.toString(adminUtil.createTestUser(generateUserEmail(), - Collections.singletonList(KIT_SHIPPING))); - } catch (SQLException e) { - simpleResult.resultException = e; - } - return simpleResult; - }); - if (results.resultException != null) { - log.error("Error creating juniper data ", results.resultException); - deleteJuniperInstanceAndSettings(); - } - } - - public static void deleteJuniperInstanceAndSettings() { - SimpleResult results = inTransaction((conn) -> { - SimpleResult dbVals = new SimpleResult(); - try { - delete(conn, "kit_dimension", "kit_dimension_id", kitDimensionId); - delete(conn, "kit_return_information", "kit_return_id", kitReturnId); - delete(conn, "carrier_service", "carrier_service_id", carrierId); - delete(conn, "ddp_kit_request_settings", "ddp_kit_request_settings_id", ddpKitRequestSettingsId); - delete(conn, "ddp_instance_role", "ddp_instance_role_id", ddpInstanceRoleId); - delete(conn, "ddp_instance_group", "instance_group_id", ddpInstanceGroupId); - delete(conn, "ddp_instance", "ddp_instance_id", ddpInstanceId); - delete(conn, "ddp_group", "group_id", ddpGroupId); - adminUtil.deleteGeneratedData(); - } catch (Exception e) { - dbVals.resultException = e; - } - return dbVals; - }); - - } - - private static void delete(Connection conn, String tableName, String primaryColumn, String id) { - try (PreparedStatement stmt = conn.prepareStatement("DELETE from " + tableName + " WHERE " + primaryColumn + " = ? ;")) { - stmt.setString(1, id); - try { - stmt.executeUpdate(); - } catch (SQLException e) { - throw new RuntimeException("Error deleting from " + tableName, e); - } - } catch (SQLException ex) { - throw new RuntimeException("Error deleting ", ex); - } - } - - public static void deleteJuniperKit(String ddpKitRequestId) { - SimpleResult results = inTransaction((conn) -> { - String dsmKitRequestId; - try (PreparedStatement stmt = conn.prepareStatement(SELECT_DSM_KIT_REQUEST_ID)) { - stmt.setString(1, ddpKitRequestId); - try (ResultSet rs = stmt.executeQuery()) { - if (rs.next()) { - dsmKitRequestId = rs.getString("dsm_kit_request_id"); - } else { - log.warn("Kit Not Found " + ddpKitRequestId); - return null; - } - } catch (SQLException e) { - throw new RuntimeException("Error selecting dsm_kit_request_id", e); - } - } catch (SQLException ex) { - throw new RuntimeException("Error deleting ", ex); - } - try { - delete(conn, "ddp_kit", "dsm_kit_request_id", dsmKitRequestId); - delete(conn, "ddp_kit_request", "dsm_kit_request_id", dsmKitRequestId); - } catch (Exception ex) { - throw new RuntimeException("Error deleting kits", ex); - } - return null; - }); - } - - public static void deleteKitsArray(List kitIds) { - for (String kitId : kitIds) { - try { - deleteJuniperKit(kitId); - } catch (Exception e) { - log.error("unable to delete kitId {}", kitId, e); - } finally { - continue; - } - } - - } - - private static String getPrimaryKey(ResultSet rs, String table) throws SQLException { - if (rs.next()) { - return rs.getString(1); - } else { - throw new DsmInternalError(String.format("Unable to set up data in %s for juniper, going to role back transaction", table)); - } - } - - public static void changeKitToQueue(JuniperKitRequest juniperKitRequest, EasyPostUtil mockEasyPostUtil) { - KitRequestShipping[] kitRequests = - KitRequestShipping.getKitRequestsByRealm(instanceName, "uploaded", "SALIVA").toArray(new KitRequestShipping[1]); - Optional kitWeWantToChange = Arrays.stream(kitRequests) - .filter(kitRequestShipping -> kitRequestShipping.getParticipantId().equals(juniperKitRequest.getJuniperParticipantID())) - .findFirst(); - if (kitWeWantToChange.isPresent()) { - KitRequestCreateLabel.updateKitLabelRequested(new KitRequestShipping[] {kitWeWantToChange.get()}, userWithKitShippingAccess, - new DDPInstanceDao().getDDPInstanceByInstanceName(instanceName).orElseThrow()); - List kitsLabelTriggered = KitUtil.getListOfKitsLabelTriggered(); - if (!kitsLabelTriggered.isEmpty()) { - KitUtil.createLabel(kitsLabelTriggered, mockEasyPostUtil); - } - } - - } - - public static List changeKitToSent(JuniperKitRequest juniperTestKit) { - List scanPayloads = new ArrayList<>(); - DDPInstanceDto ddpInstanceDto = new DDPInstanceDao().getDDPInstanceByInstanceName(instanceName).orElseThrow(); - SentAndFinalScanPayload sentAndFinalScanPayload = new SentAndFinalScanPayload(juniperTestKit.getDdpLabel(), - "SOME_RANDOM_KIT_LABEL"); - scanPayloads.add(sentAndFinalScanPayload); - List scanResultList = new ArrayList<>(); - KitPayload kitPayload = new KitPayload(scanPayloads, Integer.parseInt(userWithKitShippingAccess), ddpInstanceDto); - KitFinalScanUseCase kitFinalScanUseCase = new KitFinalScanUseCase(kitPayload, new KitDao()); - scanResultList.addAll(kitFinalScanUseCase.get()); - return scanResultList; - } - - private static String generateUserEmail() { - return "JuniperTest-" + System.currentTimeMillis() + "@broad.dev"; - } - - public static void changeKitToReceived() { - BSPKit bspKit = new BSPKit(); - String kitLabel = "SOME_RANDOM_KIT_LABEL"; - Optional optionalBSPKitDto = bspKit.canReceiveKit(kitLabel); - //kit does not exist in ddp_kit table - if (!optionalBSPKitDto.isEmpty()) { - //check if kit is from a pt which is withdrawn - Optional result = bspKit.getKitStatus(optionalBSPKitDto.get(), notificationUtil); - if (result.isEmpty()) { - //kit found in ddp_kit table - bspKit.receiveKit(kitLabel, optionalBSPKitDto.get(), notificationUtil, "BSP").orElseThrow(); - } - } - } - - private String createKitRequestSettingsInformation(Connection conn) throws SQLException { - if (StringUtils.isNotBlank(ddpKitRequestSettingsId)) { - return ddpKitRequestSettingsId; - } - PreparedStatement stmt = conn.prepareStatement(INSERT_DDP_KIT_REQUEST_SETTINGS, Statement.RETURN_GENERATED_KEYS); - stmt.setString(1, ddpInstanceId); - stmt.setString(2, kitTypeId); - stmt.setString(3, kitReturnId); - stmt.setString(4, carrierId); - stmt.setString(5, kitDimensionId); - stmt.executeUpdate(); - ResultSet rs = stmt.getGeneratedKeys(); - return getPrimaryKey(rs, "ddp_kit_request_settings"); - } - - private String createCarrierInformation(Connection conn) throws SQLException { - if (StringUtils.isNotBlank(carrierId)) { - return carrierId; - } - PreparedStatement stmt = conn.prepareStatement(INSERT_CARRIER, Statement.RETURN_GENERATED_KEYS); - stmt.executeUpdate(); - ResultSet rs = stmt.getGeneratedKeys(); - return getPrimaryKey(rs, "carrier_service"); - } - - private String createKitReturnInformation(Connection conn) throws SQLException { - if (StringUtils.isNotBlank(kitReturnId)) { - return kitReturnId; - } - PreparedStatement stmt = conn.prepareStatement(INSERT_KIT_RETURN, Statement.RETURN_GENERATED_KEYS); - stmt.executeUpdate(); - ResultSet rs = stmt.getGeneratedKeys(); - return getPrimaryKey(rs, "kit_return_information"); - } - - private String createKitDimension(Connection conn) throws SQLException { - if (StringUtils.isNotBlank(kitDimensionId)) { - return kitDimensionId; - } - PreparedStatement stmt = conn.prepareStatement(INSERT_KIT_DIMENSION, Statement.RETURN_GENERATED_KEYS); - stmt.executeUpdate(); - ResultSet rs = stmt.getGeneratedKeys(); - return getPrimaryKey(rs, "kit_dimension"); - } - - private String getKitTypeId(Connection conn) throws SQLException { - if (StringUtils.isNotBlank(kitTypeId)) { - return kitTypeId; - } - PreparedStatement stmt = conn.prepareStatement(SELECT_KIT_TYPE_ID); - stmt.setString(1, "SALIVA"); - ResultSet rs = stmt.executeQuery(); - return getPrimaryKey(rs, "kit_type"); - } - - private String getInstanceRole(Connection conn) throws SQLException { - if (StringUtils.isNotBlank(instanceRoleId)) { - return instanceRoleId; - } - PreparedStatement stmt = conn.prepareStatement(SELECT_INSTANCE_ROLE); - ResultSet rs = stmt.executeQuery(); - return getPrimaryKey(rs, "instance_role"); - } - - private String createDdpInstanceRole(Connection conn) throws SQLException { - if (StringUtils.isNotBlank(ddpInstanceRoleId)) { - return ddpInstanceRoleId; - } - PreparedStatement stmt = conn.prepareStatement(INSERT_DDP_INSTANCE_ROLE, Statement.RETURN_GENERATED_KEYS); - stmt.setString(1, ddpInstanceId); - stmt.setString(2, instanceRoleId); - stmt.setString(3, instanceRoleId); - stmt.executeUpdate(); - ResultSet rs = stmt.getGeneratedKeys(); - return getPrimaryKey(rs, "ddp_instance_role"); - } - -} diff --git a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/kits/KitDisplayNameTest.java b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/kits/KitDisplayNameTest.java index 2fed3605fe..d777f63486 100644 --- a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/kits/KitDisplayNameTest.java +++ b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/kits/KitDisplayNameTest.java @@ -3,40 +3,55 @@ import java.util.List; import org.broadinstitute.dsm.DbTxnBaseTest; -import org.broadinstitute.dsm.db.DDPInstance; import org.broadinstitute.dsm.db.KitRequestShipping; -import org.broadinstitute.dsm.model.nonpepperkit.JuniperKitRequest; -import org.broadinstitute.dsm.model.nonpepperkit.NonPepperKitCreationService; -import org.broadinstitute.dsm.statics.DBConstants; +import org.broadinstitute.dsm.db.dao.ddp.instance.DDPInstanceDao; +import org.broadinstitute.dsm.db.dao.ddp.participant.ParticipantDao; +import org.broadinstitute.dsm.db.dao.kit.KitDao; +import org.broadinstitute.dsm.db.dto.ddp.instance.DDPInstanceDto; +import org.broadinstitute.dsm.db.dto.ddp.participant.ParticipantDto; +import org.broadinstitute.dsm.util.KitShippingTestUtil; +import org.broadinstitute.dsm.util.TestParticipantUtil; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; public class KitDisplayNameTest extends DbTxnBaseTest { - private static TestKitUtil testKitUtil = new TestKitUtil("kit_test_instance", "kit_test_instance_guid", + private static final String instanceName = "kit_test_instance"; + private static KitTestUtil kitTestUtil = new KitTestUtil(instanceName, instanceName, "some_prefix", "kit_test_group", KitRequestShippingTest.BLOOD_RNA_KIT_TYPE_NAME, - KitRequestShippingTest.BLOOD_RNA_KIT_TYPE_DISPLAY_NAME, null); + KitRequestShippingTest.BLOOD_RNA_KIT_TYPE_DISPLAY_NAME, null, false); + + private static KitShippingTestUtil kitShippingTestUtil; + private static DDPInstanceDto ddpInstanceDto; + private static DDPInstanceDao ddpInstanceDao = new DDPInstanceDao(); + private static String ddpParticipantId; + private static ParticipantDto participantDto; + private static ParticipantDao participantDao = new ParticipantDao(); + private static final String TEST_USER = "kitDisplayNameTestUser"; @BeforeClass public static void setupBefore() { - testKitUtil.setupInstanceAndSettings(); + kitTestUtil.setupInstanceAndSettings(); + kitShippingTestUtil = new KitShippingTestUtil(TEST_USER, "kitDisplayNameTest"); + ddpInstanceDto = ddpInstanceDao.getDDPInstanceByInstanceId(kitTestUtil.getDdpInstanceId()).orElseThrow(); + ddpParticipantId = TestParticipantUtil.genDDPParticipantId("kitDisplayNameTest"); + participantDto = TestParticipantUtil.createParticipant(ddpParticipantId, ddpInstanceDto.getDdpInstanceId()); } @AfterClass public static void cleanUpAfterClass() { - testKitUtil.deleteKitsArray(); - testKitUtil.deleteGeneratedData(); + kitShippingTestUtil.tearDown(); + participantDao.delete(participantDto.getParticipantId().get()); + kitTestUtil.deleteGeneratedData(); } @Test public void testKitWithDisplayName() { - NonPepperKitCreationService nonPepperKitCreationService = new NonPepperKitCreationService(); - DDPInstance ddpInstance = DDPInstance.getDDPInstanceWithRole("kit_test_instance", - DBConstants.JUNIPER_STUDY_INSTANCE_ROLE); - JuniperKitRequest juniperTestKit = testKitUtil.generateKitRequestJson(); - testKitUtil.createNonPepperTestKit(juniperTestKit, nonPepperKitCreationService, ddpInstance); - List kits = KitRequestShipping.getKitRequestsByRealm("kit_test_instance", "overview", + int kitRequestId = kitShippingTestUtil.createTestKitShippingWithKitType(participantDto, ddpInstanceDto, + KitRequestShippingTest.BLOOD_RNA_KIT_TYPE_NAME, kitTestUtil.getKitTypeId(), false); + KitRequestShipping kitRequestShipping = KitDao.getKitRequest(kitRequestId).orElseThrow(); + List kits = KitRequestShipping.getKitRequestsByRealm(instanceName, KitRequestShipping.OVERVIEW, KitRequestShippingTest.BLOOD_RNA_KIT_TYPE_NAME); Assert.assertEquals(1, kits.size()); Assert.assertEquals(KitRequestShippingTest.BLOOD_RNA_KIT_TYPE_NAME, kits.get(0).getKitTypeName()); diff --git a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/kits/KitRequestShippingTest.java b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/kits/KitRequestShippingTest.java index 2c6c17e41c..cc1f381f42 100644 --- a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/kits/KitRequestShippingTest.java +++ b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/kits/KitRequestShippingTest.java @@ -40,16 +40,16 @@ public class KitRequestShippingTest extends DbAndElasticBaseTest { private static ParticipantDto notLegacyParticipant; private static int participantCounter = 0; private static Pair legacyParticipantPair; - private static TestKitUtil testKitUtil; + private static KitTestUtil kitTestUtil; private static List participants = new ArrayList<>(); private static List createdKits = new ArrayList<>(); @BeforeClass public static void doFirst() { esIndex = ElasticTestUtil.createIndex(instanceName, "elastic/lmsMappings.json", null); - testKitUtil = new TestKitUtil(instanceName, instanceName, collaboratorIdPrefix, instanceName, "SALIVA", null, esIndex); - testKitUtil.setupInstanceAndSettings(); - ddpInstanceDao.setMigratedDdp(testKitUtil.ddpInstanceId, true); + kitTestUtil = new KitTestUtil(instanceName, instanceName, collaboratorIdPrefix, instanceName, "SALIVA", null, esIndex, false); + kitTestUtil.setupInstanceAndSettings(); + ddpInstanceDao.setMigratedDdp(kitTestUtil.ddpInstanceId, true); ddpInstanceDto = ddpInstanceDao.getDDPInstanceByInstanceName(instanceName).orElseThrow(); Assert.assertTrue(ddpInstanceDto.getMigratedDdp()); ddpInstance = DDPInstance.from(ddpInstanceDto); @@ -72,8 +72,8 @@ public static void doFirst() { public static void tearDown() { participants.forEach(participantDto -> TestParticipantUtil.deleteParticipant(participantDto.getRequiredParticipantId())); - createdKits.forEach(dsmKitRequestId -> testKitUtil.deleteKitRequestShipping((Integer.parseInt(dsmKitRequestId)))); - testKitUtil.deleteGeneratedData(); + createdKits.forEach(dsmKitRequestId -> kitTestUtil.deleteKitRequestShipping((Integer.parseInt(dsmKitRequestId)))); + kitTestUtil.deleteGeneratedData(); ddpInstanceDao.delete(ddpInstanceDto.getDdpInstanceId()); ElasticTestUtil.deleteIndex(esIndex); } @@ -134,7 +134,7 @@ public void testLegacyKitUpload() { String nextCollaboratorParticipantId = KitRequestShipping.getCollaboratorParticipantId(ddpInstance, legacyParticipant.getRequiredDdpParticipantId(), shortId, "0"); String nextCollaboratorSampleId = KitRequestShipping.generateBspSampleID(conn, nextCollaboratorParticipantId, "SALIVA", - testKitUtil.kitTypeId); + kitTestUtil.kitTypeId); Assert.assertEquals(collaboratorParticipantId, nextCollaboratorParticipantId); Assert.assertEquals(collaboratorSampleId, nextCollaboratorSampleId); @@ -145,15 +145,15 @@ public void testLegacyKitUpload() { .withBspCollaboratorSampleId(legacyCollaboratorSampleId) .withKitTypeName("SALIVA") .withDdpKitRequestId("0001_Kit") - .withKitTypeId(String.valueOf(testKitUtil.kitTypeId)).build(); + .withKitTypeId(String.valueOf(kitTestUtil.kitTypeId)).build(); - String dsmKitRequestId = testKitUtil.createKitRequestShipping(kitRequestShipping, ddpInstance, "100"); + String dsmKitRequestId = kitTestUtil.createKitRequestShipping(kitRequestShipping, ddpInstance, "100"); createdKits.add(dsmKitRequestId); nextCollaboratorParticipantId = KitRequestShipping.getCollaboratorParticipantId(ddpInstance, legacyParticipant.getRequiredDdpParticipantId(), shortId, "0"); nextCollaboratorSampleId = KitRequestShipping.generateBspSampleID(conn, nextCollaboratorParticipantId, "SALIVA", - testKitUtil.kitTypeId); + kitTestUtil.kitTypeId); Assert.assertEquals(legacyCollaboratorParticipantId, nextCollaboratorParticipantId); Assert.assertEquals(expectedNextCollaboratorSampleId, nextCollaboratorSampleId); @@ -171,7 +171,7 @@ public void testPepperParticipantKitUpload() { String nextCollaboratorParticipantId = KitRequestShipping.getCollaboratorParticipantId(ddpInstance, notLegacyParticipantGuid, notLegacyParticipantShortId, "0"); String nextCollaboratorSampleId = KitRequestShipping.generateBspSampleID(conn, nextCollaboratorParticipantId, "SALIVA", - testKitUtil.kitTypeId); + kitTestUtil.kitTypeId); Assert.assertEquals(collaboratorParticipantId, nextCollaboratorParticipantId); Assert.assertEquals(collaboratorSampleId, nextCollaboratorSampleId); @@ -182,14 +182,14 @@ public void testPepperParticipantKitUpload() { .withBspCollaboratorSampleId(collaboratorSampleId) .withKitTypeName("SALIVA") .withDdpKitRequestId(notLegacyParticipantShortId + "_Kit") - .withKitTypeId(String.valueOf(testKitUtil.kitTypeId)).build(); + .withKitTypeId(String.valueOf(kitTestUtil.kitTypeId)).build(); - String dsmKitRequestId = testKitUtil.createKitRequestShipping(kitRequestShipping, ddpInstance, "100"); + String dsmKitRequestId = kitTestUtil.createKitRequestShipping(kitRequestShipping, ddpInstance, "100"); createdKits.add(dsmKitRequestId); nextCollaboratorParticipantId = KitRequestShipping.getCollaboratorParticipantId(ddpInstance, notLegacyParticipantGuid, notLegacyParticipantShortId, "0"); nextCollaboratorSampleId = KitRequestShipping.generateBspSampleID(conn, nextCollaboratorParticipantId, "SALIVA", - testKitUtil.kitTypeId); + kitTestUtil.kitTypeId); String expectedNextCollaboratorSampleId = "PROJ_" + notLegacyParticipantShortId + "_SALIVA_2"; Assert.assertEquals(collaboratorParticipantId, nextCollaboratorParticipantId); Assert.assertEquals(expectedNextCollaboratorSampleId, nextCollaboratorSampleId); diff --git a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/kits/TestKitUtil.java b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/kits/KitTestUtil.java similarity index 50% rename from pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/kits/TestKitUtil.java rename to pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/kits/KitTestUtil.java index f5af88813b..8a76b0a808 100644 --- a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/kits/TestKitUtil.java +++ b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/kits/KitTestUtil.java @@ -3,9 +3,7 @@ import static org.broadinstitute.ddp.db.TransactionWrapper.inTransaction; import static org.broadinstitute.dsm.service.admin.UserAdminService.USER_ADMIN_ROLE; import static org.broadinstitute.dsm.statics.DBConstants.KIT_SHIPPING; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import java.sql.Connection; import java.sql.PreparedStatement; @@ -17,96 +15,98 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Optional; -import com.easypost.exception.EasyPostException; import com.easypost.model.Address; import com.easypost.model.Parcel; import com.easypost.model.PostageLabel; import com.easypost.model.Shipment; import com.easypost.model.Tracker; -import com.google.gson.Gson; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.broadinstitute.dsm.db.DDPInstance; +import org.broadinstitute.dsm.db.KitRequestCreateLabel; import org.broadinstitute.dsm.db.KitRequestShipping; +import org.broadinstitute.dsm.db.dao.ddp.instance.DDPInstanceDao; import org.broadinstitute.dsm.db.dao.kit.KitDao; -import org.broadinstitute.dsm.db.dto.kit.nonPepperKit.NonPepperKitStatusDto; +import org.broadinstitute.dsm.db.dto.ddp.instance.DDPInstanceDto; +import org.broadinstitute.dsm.db.dto.kit.BSPKitDto; import org.broadinstitute.dsm.exception.DsmInternalError; -import org.broadinstitute.dsm.model.nonpepperkit.JuniperKitRequest; -import org.broadinstitute.dsm.model.nonpepperkit.KitResponse; -import org.broadinstitute.dsm.model.nonpepperkit.NonPepperKitCreationService; +import org.broadinstitute.dsm.model.gp.BSPKit; +import org.broadinstitute.dsm.model.gp.bsp.BSPKitStatus; +import org.broadinstitute.dsm.model.kit.KitFinalScanUseCase; +import org.broadinstitute.dsm.model.kit.ScanResult; +import org.broadinstitute.dsm.route.kit.KitPayload; +import org.broadinstitute.dsm.route.kit.SentAndFinalScanPayload; import org.broadinstitute.dsm.service.admin.UserAdminTestUtil; import org.broadinstitute.dsm.util.EasyPostUtil; +import org.broadinstitute.dsm.util.KitUtil; +import org.broadinstitute.dsm.util.NotificationUtil; import org.broadinstitute.lddp.db.SimpleResult; -import org.junit.Assert; import org.mockito.Mock; -/** - *

- * This class has methods to set up a study that uses kits in DSM database. - * It creates the instance, group, instance_role, kit_type, carrier, - * kit_dimensions, kit_return and ddp_kit_request_settings for the - * newly created study. - * It also contains methods to delete what was set up after tests are complete - *

- * The usage is by first creating an instance of this class by declaring the desired instance name and study guid, - * display name and collaborator prefix. - * Then call setupStudyWithKitsInstanceAndSettings() for initiating all the config in database. - *

- * When done, call deleteJuniperInstanceAndSettings() to delete everything - */ - @Slf4j -public class TestKitUtil { +@Getter +public class KitTestUtil { - private static final String SELECT_INSTANCE_ROLE = "SELECT instance_role_id FROM instance_role WHERE name = 'juniper_study';"; - private static final String INSERT_DDP_INSTANCE_ROLE = "INSERT INTO ddp_instance_role (ddp_instance_id, instance_role_id) " + protected static final String SELECT_INSTANCE_ROLE = "SELECT instance_role_id FROM instance_role WHERE name = ?;"; + protected static final String INSERT_DDP_INSTANCE_ROLE = "INSERT INTO ddp_instance_role (ddp_instance_id, instance_role_id) " + " VALUES (?, ?) ON DUPLICATE KEY UPDATE instance_role_id = ?;"; - - private static final String INSERT_KIT_TYPE_ID = "INSERT into kit_type (kit_type_name , display_name) VALUES (?, ?)"; - private static final String SELECT_KIT_TYPE_ID = "SELECT kit_type_id FROM kit_type WHERE kit_type_name = ? "; - private static final String SELECT_BY_DISPLAY_NAME = " and display_name = ? "; - private static final String INSERT_KIT_DIMENSION = "INSERT INTO kit_dimension (kit_width, kit_height, kit_length, kit_weight) " + protected static final String SELECT_KIT_TYPE_ID = "SELECT kit_type_id FROM kit_type WHERE kit_type_name = ?"; + protected static final String INSERT_KIT_DIMENSION = "INSERT INTO kit_dimension (kit_width, kit_height, kit_length, kit_weight) " + " VALUES ('6.9', '1.3', '5.2', '3.2') ON DUPLICATE KEY UPDATE kit_width = '6.9';"; - private static final String INSERT_KIT_RETURN = "INSERT INTO kit_return_information (return_address_name, return_address_phone) " + protected static final String INSERT_KIT_RETURN = "INSERT INTO kit_return_information (return_address_name, return_address_phone) " + " VALUES ('Broad Institute', '1111112222') ON DUPLICATE KEY UPDATE return_address_name = 'Broad Institute';"; - private static final String INSERT_CARRIER = "INSERT INTO carrier_service (carrier, service) " + protected static final String INSERT_CARRIER = "INSERT INTO carrier_service (carrier, service) " + " VALUES ('FedEx', 'FEDEX_2_DAY') ON DUPLICATE KEY UPDATE carrier = 'FedEx';"; - private static final String INSERT_DDP_KIT_REQUEST_SETTINGS = + protected static final String INSERT_DDP_KIT_REQUEST_SETTINGS = "INSERT INTO ddp_kit_request_settings (ddp_instance_id, kit_type_id, kit_return_id, carrier_service_to_id, kit_dimension_id) " + " VALUES (?, ?, ?, ?, ?) ;"; + private static final String SELECT_DSM_KIT_REQUEST_ID = + "SELECT dsm_kit_request_id from ddp_kit_request where ddp_kit_request_id like ? "; + + private static final String INSERT_KIT_TYPE_ID = "INSERT into kit_type (kit_type_name , display_name) VALUES (?, ?)"; + private static final String SELECT_BY_DISPLAY_NAME = " and display_name = ? "; private static final String INSERT_SUB_KITS_SETTINGS = "INSERT INTO sub_kits_settings (ddp_kit_request_settings_id, kit_type_id, kit_count, hide_on_sample_pages, external_name) " + " VALUES (?, ?, 1, ?, '') ;"; - private static final String SELECT_DSM_KIT_REQUEST_ID = "SELECT dsm_kit_request_id from ddp_kit_request " - + " where ddp_kit_request_id like ? "; - public final UserAdminTestUtil adminUtil = new UserAdminTestUtil(); + + private static final String INSERT_EVENT_TYPE = + "INSERT INTO event_type (ddp_instance_id, event_name, event_description, kit_type_id, event_type) " + + " VALUES (?, ?, ?, ?, ?) ;"; + + protected UserAdminTestUtil adminUtil = new UserAdminTestUtil(); + protected Integer ddpInstanceId; + protected Integer ddpGroupId; + protected Integer ddpInstanceGroupId; + protected Integer kitTypeId; + protected Integer kitDimensionId; + protected Integer kitReturnId; + protected Integer carrierId; + protected Integer ddpKitRequestSettingsId; + protected String instanceName; + protected String groupName; + protected String studyGuid; + protected String userWithKitShippingAccess; + protected NotificationUtil notificationUtil; private String kitTypeDisplayName; - public Integer ddpGroupId; - public Integer ddpInstanceId; - public Integer instanceRoleId; - public Integer ddpInstanceRoleId; + public List ddpInstanceRoleIdList = new ArrayList<>(); List createdKitIds = new ArrayList<>(); - public Integer kitTypeId; - private Integer kitDimensionId; - private Integer kitReturnId; - private Integer carrierId; - private Integer ddpKitRequestSettingsId; - private String instanceName; - private String groupName; + private boolean isJuniperStudy = false; private String kitTypeName; - private String studyGuid; private String collaboratorPrefix; private String esIndex; - private String userWithKitShippingAccess; + private Integer instanceRoleId; + private Integer ddpInstanceRoleId; + @Getter @Mock EasyPostUtil mockEasyPostUtil = mock(EasyPostUtil.class); @Mock Address mockEasyPostAddress = mock(Address.class); - @Mock static Shipment mockEasyPostShipment = mock(Shipment.class); + @Mock static Shipment mockEasyPostShipment = mock(Shipment.class); @Mock Parcel mockEasyPostParcel = mock(Parcel.class); @Mock @@ -116,26 +116,57 @@ public class TestKitUtil { private KitDao kitDao = new KitDao(); - public TestKitUtil(String instanceName, String studyGuid, String collaboratorPrefix, String groupName, - String kitTypeName, String kitTypeDisplayName, String esIndex) { + /** + * Constructor for KitTestUtil, after creating an instance of this class, call {@link #setupInstanceAndSettings} + * If creating a Juniper study, set the isJuniperStudy to true and the esIndex will be set null. + * If deleting the data, call {@link #deleteGeneratedData} + * + * @param instanceName name of the instance + * @param studyGuid study-guid for study + * @param collaboratorPrefix prefix for collaborator id for kits + * @param groupName name of the study group + * @param kitTypeName name of the kit type, for example "SALIVA" + * @param kitTypeDisplayName display name of the kit type, for example "Saliva" + * @param esIndex ES index for the study + * @param isJuniperStudy boolean to indicate if the study is a Juniper study and will have features specific to Juniper studies + * */ + public KitTestUtil(String instanceName, String studyGuid, String collaboratorPrefix, String groupName, + String kitTypeName, String kitTypeDisplayName, String esIndex, boolean isJuniperStudy) { this.instanceName = instanceName; this.studyGuid = studyGuid; - this.collaboratorPrefix = collaboratorPrefix; this.groupName = groupName; + this.collaboratorPrefix = collaboratorPrefix; this.kitTypeName = kitTypeName; this.kitTypeDisplayName = kitTypeDisplayName; - this.esIndex = esIndex; + + this.isJuniperStudy = isJuniperStudy; + if (!this.isJuniperStudy) { + this.esIndex = esIndex; + } else { + this.esIndex = null; + log.info("Juniper study, not setting ES index"); + } } + /** + * Will delete all the data that was created for the instance and settings + * Call this after deleting the created participants and kits and all the participant data that belongs to the study + * */ public void deleteGeneratedData() { SimpleResult results = inTransaction((conn) -> { SimpleResult dbVals = new SimpleResult(); try { + delete(conn, "event_type", "ddp_instance_id", ddpInstanceId); + delete(conn, "EVENT_QUEUE", "ddp_instance_id", ddpInstanceId); delete(conn, "kit_return_information", "kit_return_id", kitReturnId); delete(conn, "ddp_kit_request_settings", "ddp_kit_request_settings_id", ddpKitRequestSettingsId); delete(conn, "carrier_service", "carrier_service_id", carrierId); delete(conn, "kit_dimension", "kit_dimension_id", kitDimensionId); - delete(conn, "ddp_instance_role", "ddp_instance_role_id", ddpInstanceRoleId); + ddpInstanceRoleIdList.forEach(ddpInstanceRoleId -> { + if (ddpInstanceRoleId != null) { + delete(conn, "ddp_instance_role", "ddp_instance_role_id", ddpInstanceRoleId); + } + }); adminUtil.deleteGeneratedData(); } catch (Exception e) { dbVals.resultException = e; @@ -148,86 +179,10 @@ public void deleteGeneratedData() { } - public void deleteSubKitSettings(Integer[] subKitSettingIds) { - SimpleResult results = inTransaction((conn) -> { - SimpleResult dbVals = new SimpleResult(); - for (int subkitSettingId : subKitSettingIds) { - try { - delete(conn, "sub_kits_settings", "sub_kits_settings_id", subkitSettingId); - } catch (Exception e) { - throw e; - } - - } - return dbVals; - }); - } - - private void delete(Connection conn, String tableName, String primaryColumn, int id) { - try (PreparedStatement stmt = conn.prepareStatement("DELETE from " + tableName + " WHERE " + primaryColumn + " = ? ;")) { - stmt.setInt(1, id); - try { - stmt.executeUpdate(); - } catch (SQLException e) { - throw new RuntimeException("Error deleting from " + tableName, e); - } - } catch (SQLException ex) { - throw new RuntimeException("Error deleting ", ex); - } - } - - private void delete(Connection conn, String tableName, String primaryColumn, List ids) { - for (int id: ids) { - delete(conn, tableName, primaryColumn, id); - } - } - - public void deleteKitByDdpKitRequestId(String ddpKitRequestId) { - List dsmKitRequestIds = new ArrayList<>(); - inTransaction((conn) -> { - try (PreparedStatement stmt = conn.prepareStatement(SELECT_DSM_KIT_REQUEST_ID)) { - stmt.setString(1, ddpKitRequestId); - try (ResultSet rs = stmt.executeQuery()) { - while (rs.next()) { - dsmKitRequestIds.add(rs.getInt("dsm_kit_request_id")); - } - if (dsmKitRequestIds.isEmpty()) { - throw new DsmInternalError( - String.format("Could not find kit %s to delete", ddpKitRequestId)); - } - } catch (SQLException e) { - throw new RuntimeException("Error selecting dsm_kit_request_id", e); - } - } catch (SQLException ex) { - throw new RuntimeException("Error deleting kit request " + ddpKitRequestId, ex); - } - return null; - }); - dsmKitRequestIds.forEach(this::deleteKitRequestShipping); - } - - public void deleteKitsArray() { - for (String kitId : createdKitIds) { - try { - deleteKitByDdpKitRequestId(kitId); - } catch (Exception e) { - throw new DsmInternalError("Could not delete kit " + kitId, e); - } - } - } - - private Integer getPrimaryKey(ResultSet rs, String table) throws SQLException { - if (rs.next()) { - return rs.getInt(1); - } else { - throw new DsmInternalError(String.format("Unable to get primary key for %s", table)); - } - } - - private String generateUserEmail() { - return "Test-" + System.currentTimeMillis() + "@broad.dev"; - } - + /** + * Will set up the instance and settings for the study + * Call this for creating the study and the study group + * */ public void setupInstanceAndSettings() { //everything should get inserted in one transaction SimpleResult results = inTransaction((conn) -> { @@ -236,8 +191,12 @@ public void setupInstanceAndSettings() { adminUtil.createRealmAndStudyGroup(instanceName, studyGuid, collaboratorPrefix, groupName, esIndex); ddpInstanceId = adminUtil.getDdpInstanceId(); ddpGroupId = adminUtil.getStudyGroupId(); - instanceRoleId = getInstanceRole(conn); - ddpInstanceRoleId = createDdpInstanceRole(conn); + instanceRoleId = getKitRequestInstanceRole(conn); + ddpInstanceRoleIdList.add(createDdpInstanceRole(conn, instanceRoleId)); + if (!isJuniperStudy) { + Integer ptInstanceRoleId = getPtNotifInstanceRole(conn); + ddpInstanceRoleIdList.add(createDdpInstanceRole(conn, ptInstanceRoleId)); + } kitTypeId = getKitTypeId(conn, kitTypeName, kitTypeDisplayName, true); kitDimensionId = createKitDimension(conn); kitReturnId = createKitReturnInformation(conn); @@ -259,49 +218,31 @@ public void setupInstanceAndSettings() { } } - private Integer createKitRequestSettingsInformation(Connection conn) throws SQLException { - if (ddpKitRequestSettingsId != null) { - return ddpKitRequestSettingsId; - } - PreparedStatement stmt = conn.prepareStatement(INSERT_DDP_KIT_REQUEST_SETTINGS, Statement.RETURN_GENERATED_KEYS); - stmt.setInt(1, ddpInstanceId); - stmt.setInt(2, kitTypeId); - stmt.setInt(3, kitReturnId); - stmt.setInt(4, carrierId); - stmt.setInt(5, kitDimensionId); - stmt.executeUpdate(); - ResultSet rs = stmt.getGeneratedKeys(); - return getPrimaryKey(rs, "ddp_kit_request_settings"); + + private String generateUserEmail() { + return "Test-" + System.currentTimeMillis() + "@broad.dev"; } - private Integer createCarrierInformation(Connection conn) throws SQLException { - if (carrierId != null) { - return carrierId; + private Integer getKitRequestInstanceRole(Connection conn) throws SQLException { + if (this.isJuniperStudy) { + return getInstanceRoleId(conn, "juniper_study"); + } else { + return getInstanceRoleId(conn, "kit_request_activated"); } - PreparedStatement stmt = conn.prepareStatement(INSERT_CARRIER, Statement.RETURN_GENERATED_KEYS); - stmt.executeUpdate(); - ResultSet rs = stmt.getGeneratedKeys(); - return getPrimaryKey(rs, "carrier_service"); } - private Integer createKitReturnInformation(Connection conn) throws SQLException { - if (kitReturnId != null) { - return kitReturnId; + private Integer getPtNotifInstanceRole(Connection conn) throws SQLException { + if (isJuniperStudy) { + return null; } - PreparedStatement stmt = conn.prepareStatement(INSERT_KIT_RETURN, Statement.RETURN_GENERATED_KEYS); - stmt.executeUpdate(); - ResultSet rs = stmt.getGeneratedKeys(); - return getPrimaryKey(rs, "kit_return_information"); + return getInstanceRoleId(conn, "kit_participant_notifications_activated"); } - private Integer createKitDimension(Connection conn) throws SQLException { - if (kitDimensionId != null) { - return kitDimensionId; - } - PreparedStatement stmt = conn.prepareStatement(INSERT_KIT_DIMENSION, Statement.RETURN_GENERATED_KEYS); - stmt.executeUpdate(); - ResultSet rs = stmt.getGeneratedKeys(); - return getPrimaryKey(rs, "kit_dimension"); + private Integer getInstanceRoleId(Connection conn, String instanceRoleName)throws SQLException { + PreparedStatement stmt = conn.prepareStatement(SELECT_INSTANCE_ROLE); + stmt.setString(1, instanceRoleName); + ResultSet rs = stmt.executeQuery(); + return getPrimaryKey(rs, "instance_role"); } private Integer getKitTypeId(Connection conn, String kitTypeName, String displayName, boolean isExistingKit) @@ -319,7 +260,9 @@ private Integer getKitTypeId(Connection conn, String kitTypeName, String display stmt.setString(2, displayName); } ResultSet rs = stmt.executeQuery(); - Integer kitTypeId = getPrimaryKey(rs, "kit_type"); + if (rs.next()) { + return rs.getInt(1); + } if (kitTypeId == null) { kitTypeId = createKitType(conn, kitTypeName, displayName); } @@ -339,139 +282,187 @@ private Integer createKitType(Connection conn, String kitTypeName, String displa return getPrimaryKey(rs, "kit_type"); } - private Integer getInstanceRole(Connection conn) throws SQLException { - if (instanceRoleId != null) { - return instanceRoleId; + public void changeKitToReceived(NotificationUtil notificationUtil, String kitLabel) { + BSPKit bspKit = new BSPKit(); + Optional optionalBSPKitDto = bspKit.canReceiveKit(kitLabel); + //kit does not exist in ddp_kit table + if (!optionalBSPKitDto.isEmpty()) { + //check if kit is from a pt which is withdrawn + Optional result = bspKit.getKitStatus(optionalBSPKitDto.get(), notificationUtil); + if (result.isEmpty()) { + //kit found in ddp_kit table + bspKit.receiveKit(kitLabel, optionalBSPKitDto.get(), notificationUtil, "BSP").orElseThrow(); + } } - PreparedStatement stmt = conn.prepareStatement(SELECT_INSTANCE_ROLE); - ResultSet rs = stmt.executeQuery(); - return getPrimaryKey(rs, "instance_role"); } - private Integer createDdpInstanceRole(Connection conn) throws SQLException { - if (ddpInstanceRoleId != null) { - return ddpInstanceRoleId; + protected Integer getPrimaryKey(ResultSet rs, String table) throws SQLException { + if (rs.next()) { + return rs.getInt(1); + } else { + throw new DsmInternalError(String.format("Unable to set up data in %s, going to role back transaction", table)); } - PreparedStatement stmt = conn.prepareStatement(INSERT_DDP_INSTANCE_ROLE, Statement.RETURN_GENERATED_KEYS); + } + + protected int createKitDimension(Connection conn) throws SQLException { + if (kitDimensionId != null) { + return kitDimensionId; + } + PreparedStatement stmt = conn.prepareStatement(INSERT_KIT_DIMENSION, Statement.RETURN_GENERATED_KEYS); + stmt.executeUpdate(); + ResultSet rs = stmt.getGeneratedKeys(); + return getPrimaryKey(rs, "kit_dimension"); + } + + protected int createKitReturnInformation(Connection conn) throws SQLException { + if (kitReturnId != null) { + return kitReturnId; + } + PreparedStatement stmt = conn.prepareStatement(INSERT_KIT_RETURN, Statement.RETURN_GENERATED_KEYS); + stmt.executeUpdate(); + ResultSet rs = stmt.getGeneratedKeys(); + return getPrimaryKey(rs, "kit_return_information"); + } + + protected int createCarrierInformation(Connection conn) throws SQLException { + if (carrierId != null) { + return carrierId; + } + PreparedStatement stmt = conn.prepareStatement(INSERT_CARRIER, Statement.RETURN_GENERATED_KEYS); + stmt.executeUpdate(); + ResultSet rs = stmt.getGeneratedKeys(); + return getPrimaryKey(rs, "carrier_service"); + } + + protected Integer createKitRequestSettingsInformation(Connection conn) throws SQLException { + if (ddpKitRequestSettingsId != null) { + return ddpKitRequestSettingsId; + } + if (ddpInstanceId == null || kitTypeId == null || kitReturnId == null || carrierId == null || kitDimensionId == null) { + throw new DsmInternalError("required settings have not been set up"); + } + PreparedStatement stmt = conn.prepareStatement(INSERT_DDP_KIT_REQUEST_SETTINGS, Statement.RETURN_GENERATED_KEYS); stmt.setInt(1, ddpInstanceId); - stmt.setInt(2, instanceRoleId); - stmt.setInt(3, instanceRoleId); + stmt.setInt(2, kitTypeId); + stmt.setInt(3, kitReturnId); + stmt.setInt(4, carrierId); + stmt.setInt(5, kitDimensionId); stmt.executeUpdate(); ResultSet rs = stmt.getGeneratedKeys(); - return getPrimaryKey(rs, "ddp_instance_role"); + return getPrimaryKey(rs, "ddp_kit_request_settings"); } - public Integer[] createSubKitsForTheStudy(String subkitName1, String subkitDisplayName1, int hideSample1, String subkitName2, - String subkitDisplayName2, int hideSample2) { - Integer[] ids = new Integer[2]; - Integer[] subKitIds = new Integer[2]; - inTransaction((conn) -> { - try { - subKitIds[0] = getKitTypeId(conn, subkitName1, subkitDisplayName1, false); - } catch (Exception e) { - throw new RuntimeException(e); + public void changeKitToQueue(String participantId, EasyPostUtil mockEasyPostUtil) { + KitRequestShipping[] kitRequests = + KitRequestShipping.getKitRequestsByRealm(instanceName, "uploaded", "SALIVA").toArray(new KitRequestShipping[1]); + Optional kitWeWantToChange = Arrays.stream(kitRequests) + .filter(kitRequestShipping -> kitRequestShipping.getParticipantId().equals(participantId)) + .findFirst(); + if (kitWeWantToChange.isPresent()) { + KitRequestCreateLabel.updateKitLabelRequested(new KitRequestShipping[] {kitWeWantToChange.get()}, userWithKitShippingAccess, + new DDPInstanceDao().getDDPInstanceByInstanceName(instanceName).orElseThrow()); + List kitsLabelTriggered = KitUtil.getListOfKitsLabelTriggered(); + if (!kitsLabelTriggered.isEmpty()) { + KitUtil.createLabel(kitsLabelTriggered, mockEasyPostUtil); } - return null; - }); - inTransaction((conn) -> { - try { - subKitIds[1] = getKitTypeId(conn, subkitName2, subkitDisplayName2, false); + } + } + + public List changeKitToSent(String ddpLabel, String kitLabel) { + List scanPayloads = new ArrayList<>(); + DDPInstanceDto ddpInstanceDto = new DDPInstanceDao().getDDPInstanceByInstanceName(instanceName).orElseThrow(); + SentAndFinalScanPayload sentAndFinalScanPayload = new SentAndFinalScanPayload(ddpLabel, kitLabel); + scanPayloads.add(sentAndFinalScanPayload); + List scanResultList = new ArrayList<>(); + KitPayload kitPayload = new KitPayload(scanPayloads, Integer.parseInt(userWithKitShippingAccess), ddpInstanceDto); + KitFinalScanUseCase kitFinalScanUseCase = new KitFinalScanUseCase(kitPayload, new KitDao()); + scanResultList.addAll(kitFinalScanUseCase.get()); + return scanResultList; + } + + + public void deleteKitsArray(List kitIds) { + for (String kitId : kitIds) { + try { + deleteKitByDdpKitRequestId(kitId); } catch (Exception e) { - throw new RuntimeException(e); + log.error("unable to delete kitId {}", kitId, e); + } finally { + continue; } - return null; - }); + } + } + + public void deleteKitByDdpKitRequestId(String ddpKitRequestId) { + List dsmKitRequestIds = new ArrayList<>(); inTransaction((conn) -> { - try { - ids[0] = insertSubKitsSettingsForStudy(ddpKitRequestSettingsId, subKitIds[0], hideSample1, conn); - ids[1] = insertSubKitsSettingsForStudy(ddpKitRequestSettingsId, subKitIds[1], hideSample2, conn); - } catch (Exception e) { - throw new RuntimeException(e); + try (PreparedStatement stmt = conn.prepareStatement(SELECT_DSM_KIT_REQUEST_ID)) { + stmt.setString(1, ddpKitRequestId); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + dsmKitRequestIds.add(rs.getInt("dsm_kit_request_id")); + } + if (dsmKitRequestIds.isEmpty()) { + throw new DsmInternalError( + String.format("Could not find kit %s to delete", ddpKitRequestId)); + } + } catch (SQLException e) { + throw new RuntimeException("Error selecting dsm_kit_request_id", e); + } + } catch (SQLException ex) { + throw new RuntimeException("Error deleting kit request " + ddpKitRequestId, ex); } return null; }); - return ids; + dsmKitRequestIds.forEach(this::deleteKitRequestShipping); } - public Integer insertSubKitsSettingsForStudy(int ddpKitRequestSettingsId, int subKitTypeId, int hideSample, Connection conn) - throws SQLException { - PreparedStatement stmt = conn.prepareStatement(INSERT_SUB_KITS_SETTINGS, Statement.RETURN_GENERATED_KEYS); - stmt.setInt(1, ddpKitRequestSettingsId); - stmt.setInt(2, subKitTypeId); - stmt.setInt(3, hideSample); - stmt.executeUpdate(); - ResultSet rs = stmt.getGeneratedKeys(); - return getPrimaryKey(rs, "sub_kits_settings"); + public void deleteKitRequestShipping(int dsmKitRequestId) { + kitDao.deleteKitRequestShipping(dsmKitRequestId); } - /** - * this method creates the test KitRequest in the database by calling - * `NonPepperKitCreationService.createNonPepperKit` and verifies the response is as expected - * - * @param juniperTestKitRequest a JuniperKitRequest that can be passed to the kti creation service - **/ - - public void createNonPepperTestKit(JuniperKitRequest juniperTestKitRequest, NonPepperKitCreationService nonPepperKitCreationService, - DDPInstance ddpInstance) { - createdKitIds.add(juniperTestKitRequest.getJuniperKitId()); - when(mockEasyPostShipment.getPostageLabel()).thenReturn(mockParticipantLabel); - when(mockEasyPostShipment.getTracker()).thenReturn(mockShipmentTracker); - when(mockShipmentTracker.getPublicUrl()).thenReturn("PUBLIC_URL"); - when(mockParticipantLabel.getLabelUrl()).thenReturn("MOCK_LABEL_URL"); - when(mockEasyPostAddress.getId()).thenReturn("SOME_STRING"); - when(mockEasyPostUtil.getEasyPostAddressId(any(), any(), any())).thenReturn("SOME_STRING"); - try { - when(mockEasyPostUtil.createParcel(any(), any(), any(), any())).thenReturn(mockEasyPostParcel); - when(mockEasyPostUtil.getAddress(any())).thenReturn(mockEasyPostAddress); - when(mockEasyPostUtil.createAddressWithoutValidation(any(), any(), any(), any(), any(), any(), any(), any())).thenReturn( - mockEasyPostAddress); - when(mockEasyPostUtil.buyShipment(any(), any(), any(), any(), any(), any(), any(), any())).thenReturn(mockEasyPostShipment); - } catch (EasyPostException e) { - e.printStackTrace(); - Assert.fail(e.getMessage()); + protected void delete(Connection conn, String tableName, String primaryColumn, String id) { + try (PreparedStatement stmt = conn.prepareStatement("DELETE from " + tableName + " WHERE " + primaryColumn + " = ? ;")) { + stmt.setString(1, id); + try { + stmt.executeUpdate(); + } catch (SQLException e) { + throw new RuntimeException("Error deleting from " + tableName, e); + } + } catch (SQLException ex) { + throw new RuntimeException("Error deleting ", ex); + } + } + + protected void delete(Connection conn, String tableName, String primaryColumn, Integer id) { + if (id == null) { + log.warn("Id is null, not deleting from " + tableName); + return; + } + try (PreparedStatement stmt = conn.prepareStatement("DELETE from " + tableName + " WHERE " + primaryColumn + " = ? ;")) { + stmt.setInt(1, id); + try { + stmt.executeUpdate(); + } catch (SQLException e) { + throw new RuntimeException("Error deleting from " + tableName, e); + } + } catch (SQLException ex) { + throw new RuntimeException("Error deleting ", ex); } - List oldKits = KitRequestShipping.getKitRequestsByRealm(instanceName, "overview", kitTypeName); - KitResponse kitResponse = - nonPepperKitCreationService.createNonPepperKit(juniperTestKitRequest, kitTypeName, mockEasyPostUtil, ddpInstance); - Assert.assertFalse(kitResponse.isError()); - Assert.assertNotNull(kitResponse.getKits()); - Assert.assertEquals(1, kitResponse.getKits().size()); - NonPepperKitStatusDto kitStatus = kitResponse.getKits().get(0); - Assert.assertEquals(juniperTestKitRequest.getJuniperKitId(), kitStatus.getJuniperKitId()); - Assert.assertNotNull(kitStatus.getDsmShippingLabel()); - Assert.assertNotNull(kitStatus.getCollaboratorSampleId()); - Assert.assertNotNull(kitStatus.getCollaboratorParticipantId()); - List newKits = KitRequestShipping.getKitRequestsByRealm(instanceName, "overview", kitTypeName); - Assert.assertEquals(oldKits.size() + 1, newKits.size()); - KitRequestShipping newKit = - newKits.stream().filter(kitRequestShipping -> kitRequestShipping.getDdpParticipantId() - .equals(juniperTestKitRequest.getJuniperParticipantID())) - .findAny().get(); - Assert.assertEquals(newKit.getBspCollaboratorParticipantId(), - collaboratorPrefix + "_" + juniperTestKitRequest.getJuniperParticipantID()); - Assert.assertEquals(newKit.getBspCollaboratorSampleId(), - collaboratorPrefix + "_" + juniperTestKitRequest.getJuniperParticipantID() + "_" + kitTypeName); } - public JuniperKitRequest generateKitRequestJson() { - String participantId = "TEST_PARTICIPANT"; - - String json = "{ \"firstName\":\"P\"," - + "\"lastName\":\"T\"," - + "\"street1\":\"415 Main st\"," - + "\"street2\":null," - + "\"city\":\"Cambridge\"," - + "\"state\":\"MA\"," - + "\"postalCode\":\"02142\"," - + "\"country\":\"USA\"," - + "\"phoneNumber\":\" 111 - 222 - 3344\"," - + "\"juniperKitId\":\"kitId_\"," - + "\"juniperParticipantID\":\"" + participantId + "\"," - + "\"skipAddressValidation\":false," - + "\"juniperStudyID\":\"Juniper-test-guid\"}"; - - return new Gson().fromJson(json, JuniperKitRequest.class); + protected Integer createDdpInstanceRole(Connection conn, Integer instanceRoleId) throws SQLException { + if (instanceRoleId == null) { + return null; + } + PreparedStatement stmt = conn.prepareStatement(INSERT_DDP_INSTANCE_ROLE, Statement.RETURN_GENERATED_KEYS); + stmt.setInt(1, ddpInstanceId); + stmt.setInt(2, instanceRoleId); + stmt.setInt(3, instanceRoleId); + stmt.executeUpdate(); + ResultSet rs = stmt.getGeneratedKeys(); + return getPrimaryKey(rs, "ddp_instance_role"); } public String createKitRequestShipping(KitRequestShipping kitRequestShipping, DDPInstance ddpInstance, @@ -483,7 +474,44 @@ public String createKitRequestShipping(KitRequestShipping kitRequestShipping, DD ddpInstance, kitTypeName, null); } - public void deleteKitRequestShipping(int dsmKitRequestId) { - kitDao.deleteKitRequestShipping(dsmKitRequestId); + public void createEventsForDDPInstance(String eventName, String eventType, String eventDescription, boolean nullKitType) { + SimpleResult results = inTransaction((conn) -> { + SimpleResult simpleResult = new SimpleResult(); + try { + PreparedStatement stmt = conn.prepareStatement(INSERT_EVENT_TYPE, Statement.RETURN_GENERATED_KEYS); + stmt.setInt(1, ddpInstanceId); + stmt.setString(2, eventName); + stmt.setString(3, eventDescription); + if (nullKitType) { + stmt.setNull(4, Types.INTEGER); + } else { + stmt.setInt(4, kitTypeId); + } + stmt.setString(5, eventType); + stmt.executeUpdate(); + } catch (SQLException e) { + throw new DsmInternalError("Error creating event ", e); + } + return simpleResult; + }); + } + + public List changeKitRequestShippingToSent(KitRequestShipping kitRequestShipping, String kitLabel) { + List scanPayloads = new ArrayList<>(); + DDPInstanceDto ddpInstanceDto = new DDPInstanceDao().getDDPInstanceByInstanceName(instanceName).orElseThrow(); + SentAndFinalScanPayload sentAndFinalScanPayload = new SentAndFinalScanPayload(kitRequestShipping.getDdpLabel(), kitLabel); + scanPayloads.add(sentAndFinalScanPayload); + List scanResultList = new ArrayList<>(); + KitPayload kitPayload = new KitPayload(scanPayloads, Integer.parseInt(userWithKitShippingAccess), ddpInstanceDto); + KitFinalScanUseCase kitFinalScanUseCase = new KitFinalScanUseCase(kitPayload, new KitDao()); + scanResultList.addAll(kitFinalScanUseCase.get()); + return scanResultList; + } + + public void setEsIndex(String esIndex) { + this.esIndex = esIndex; + new DDPInstanceDao().updateEsParticipantIndex(ddpInstanceId, esIndex); } + } + diff --git a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/service/EventServiceTest.java b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/service/EventServiceTest.java new file mode 100644 index 0000000000..2bdc77f2db --- /dev/null +++ b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/service/EventServiceTest.java @@ -0,0 +1,311 @@ +package org.broadinstitute.dsm.service; + +import static org.broadinstitute.dsm.service.EventService.MAX_TRIES; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.anyBoolean; +import static org.mockito.Mockito.anyLong; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; + +import java.io.IOException; +import java.util.List; +import java.util.Optional; + +import org.broadinstitute.ddp.notficationevent.KitReasonType; +import org.broadinstitute.dsm.DbAndElasticBaseTest; +import org.broadinstitute.dsm.db.DDPInstance; +import org.broadinstitute.dsm.db.KitRequestShipping; +import org.broadinstitute.dsm.db.dao.ddp.instance.DDPInstanceDao; +import org.broadinstitute.dsm.db.dao.ddp.participant.ParticipantDao; +import org.broadinstitute.dsm.db.dao.kit.ClinicalKitDao; +import org.broadinstitute.dsm.db.dao.kit.KitDao; +import org.broadinstitute.dsm.db.dao.queue.EventDao; +import org.broadinstitute.dsm.db.dto.ddp.instance.DDPInstanceDto; +import org.broadinstitute.dsm.db.dto.ddp.participant.ParticipantDto; +import org.broadinstitute.dsm.db.dto.kit.BSPKitDto; +import org.broadinstitute.dsm.db.dto.queue.EventDto; +import org.broadinstitute.dsm.kits.KitTestUtil; +import org.broadinstitute.dsm.model.gp.BSPKit; +import org.broadinstitute.dsm.model.gp.bsp.BSPKitStatus; +import org.broadinstitute.dsm.model.kit.ScanResult; +import org.broadinstitute.dsm.statics.DBConstants; +import org.broadinstitute.dsm.util.DDPRequestUtil; +import org.broadinstitute.dsm.util.ElasticTestUtil; +import org.broadinstitute.dsm.util.KitShippingTestUtil; +import org.broadinstitute.dsm.util.NotificationUtil; +import org.broadinstitute.dsm.util.TestParticipantUtil; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +public class EventServiceTest extends DbAndElasticBaseTest { + private static final String TEST_USER = "EVENT_USER"; + private static final DDPInstanceDao ddpInstanceDao = new DDPInstanceDao(); + private static final String INSTANCE_NAME = "event_instance"; + private static final String INSTANCE_GUID = "event_instance"; + private static final String SALIVA = "SALIVA"; + private static final String EVENT_TYPE_SENT = "SALIVA_SENT"; + private static final String EVENT_TYPE_RECEIVED = "SALIVA_RECEIVED"; + private static String esIndex; + private static KitShippingTestUtil kitShippingTestUtil; + private static DDPInstanceDto ddpInstanceDto; + private static DDPInstance ddpInstance; + private static KitTestUtil kitTestUtil; + private static ParticipantDto participantDto; + private static ParticipantDto unsuccessfulEventPtDto; + private static String ddpParticipantId; + private static String unsuccessfulEventPt; + private static final ParticipantDao participantDao = new ParticipantDao(); + private final EventDao eventDao = new EventDao(); + private final ClinicalKitDao clinicalKitDao = new ClinicalKitDao(); + + @BeforeClass + public static void setUp() { + esIndex = ElasticTestUtil.createIndex(INSTANCE_NAME, "elastic/lmsMappings.json", null); + kitShippingTestUtil = new KitShippingTestUtil(TEST_USER, "EVENT"); + kitTestUtil = new KitTestUtil(INSTANCE_NAME, INSTANCE_GUID, "event_test_prefix", "event-group", "SALIVA", "SALIVA", esIndex, + false); + kitTestUtil.setupInstanceAndSettings(); + ddpInstanceDto = ddpInstanceDao.getDDPInstanceByInstanceId(kitTestUtil.getDdpInstanceId()).orElseThrow(); + ddpInstance = DDPInstance.from(ddpInstanceDto); + ddpParticipantId = TestParticipantUtil.genDDPParticipantId("EVENT_PARTICIPANT"); + participantDto = TestParticipantUtil.createParticipant(ddpParticipantId, ddpInstanceDto.getDdpInstanceId()); + unsuccessfulEventPt = TestParticipantUtil.genDDPParticipantId("EVENT_PARTICIPANT_2"); + unsuccessfulEventPtDto = TestParticipantUtil.createParticipant(unsuccessfulEventPt, + ddpInstanceDto.getDdpInstanceId()); + kitTestUtil.createEventsForDDPInstance(EVENT_TYPE_SENT, "SENT", "test purpose: event for sent kit", false); + kitTestUtil.createEventsForDDPInstance(EVENT_TYPE_RECEIVED, "RECEIVED", "test purpose: event for received kit", false); + kitTestUtil.createEventsForDDPInstance(DBConstants.REQUIRED_SAMPLES_RECEIVED_EVENT, "RECEIVED", + "test purpose: event for participant", true); + } + + @AfterClass + public static void tearDown() { + kitShippingTestUtil.tearDown(); + participantDao.delete(participantDto.getParticipantId().get()); + participantDao.delete(unsuccessfulEventPtDto.getParticipantId().get()); + kitTestUtil.deleteGeneratedData(); + ElasticTestUtil.deleteIndex(esIndex); + } + + @Test + public void testKitSentEvent() { + try (MockedStatic utilities = Mockito.mockStatic(DDPRequestUtil.class)) { + utilities.when(() -> DDPRequestUtil.postRequest(anyString(), any(), anyString(), anyBoolean())) + .thenReturn(200); + + // Assert that mocking is working correctly + Assert.assertEquals(200L, (long)DDPRequestUtil.postRequest("", "", "", true)); + + int kitRequestId = kitShippingTestUtil.createTestKitShippingWithKitType(participantDto, ddpInstanceDto, SALIVA, + kitTestUtil.getKitTypeId(), false); + KitRequestShipping kitRequestShipping = KitDao.getKitRequest(kitRequestId).orElseThrow(); + String kitLabel = "EVENT_KIT_LABEL"; + List scanResultList = kitTestUtil.changeKitRequestShippingToSent(kitRequestShipping, kitLabel); + scanResultList.forEach(scanResult -> { + Assert.assertFalse(scanResult.hasError()); + Assert.assertEquals(scanResult.getKit(), kitRequestShipping.getDdpLabel()); + }); + EventDto eventDto = eventDao.getEventForKit(EVENT_TYPE_SENT, kitRequestShipping.getDsmKitRequestId()).orElseThrow(); + assertEvent(eventDto, true, kitRequestShipping.getDsmKitRequestId(), null, ddpInstanceDto.getDdpInstanceId(), EVENT_TYPE_SENT); + } catch (IOException e) { + e.printStackTrace(); + Assert.fail("Unexpected exception"); + } + } + + @Test + public void testParticipantEvent_successful() { + try (MockedStatic utilities = Mockito.mockStatic(DDPRequestUtil.class)) { + utilities.when(() -> DDPRequestUtil.postRequest(anyString(), any(), anyString(), anyBoolean())).thenReturn(200); + clinicalKitDao.triggerParticipantEvent(DDPInstance.from(ddpInstanceDto), ddpParticipantId, + DBConstants.REQUIRED_SAMPLES_RECEIVED_EVENT); + EventDto eventDto = + eventDao.getEventForParticipant(DBConstants.REQUIRED_SAMPLES_RECEIVED_EVENT, ddpParticipantId).orElseThrow(); + assertEvent(eventDto, true, 0, ddpParticipantId, ddpInstanceDto.getDdpInstanceId(), + DBConstants.REQUIRED_SAMPLES_RECEIVED_EVENT); + } catch (Exception e) { + e.printStackTrace(); + Assert.fail("Unexpected exception"); + } + + } + + @Test + public void testParticipantEvent_unsuccessful() { + try (MockedStatic eventServiceMockedStatic = Mockito.mockStatic(EventService.class, Mockito.CALLS_REAL_METHODS); + MockedStatic utilities = Mockito.mockStatic(DDPRequestUtil.class)) { + //we can't use the same participant as before, because the event is already triggered and so dsm won't trigger it again + utilities.when(() -> DDPRequestUtil.postRequest(anyString(), any(), anyString(), anyBoolean())).thenReturn(500); + clinicalKitDao.triggerParticipantEvent(ddpInstance, unsuccessfulEventPt, + DBConstants.REQUIRED_SAMPLES_RECEIVED_EVENT); + EventDto eventDto = + eventDao.getEventForParticipant(DBConstants.REQUIRED_SAMPLES_RECEIVED_EVENT, unsuccessfulEventPt).orElseThrow(); + assertEvent(eventDto, false, 0, unsuccessfulEventPt, ddpInstanceDto.getDdpInstanceId(), + DBConstants.REQUIRED_SAMPLES_RECEIVED_EVENT); + eventServiceMockedStatic.verify(() -> EventService.logTriggerFailure(any(), anyString(), anyString(), anyString(), any()), + never()); + eventServiceMockedStatic.verify(() -> EventService.logTriggerExhausted(ddpInstance, + DBConstants.REQUIRED_SAMPLES_RECEIVED_EVENT, unsuccessfulEventPt, unsuccessfulEventPt), times(1)); + } catch (Exception e) { + e.printStackTrace(); + Assert.fail("Unexpected exception"); + } + + } + + @Test + public void testUnsuccessfulEvent_BadResponse() { + try (MockedStatic eventServiceMockedStatic = Mockito.mockStatic(EventService.class, Mockito.CALLS_REAL_METHODS); + MockedStatic utilities = Mockito.mockStatic(DDPRequestUtil.class)) { + + utilities.when(() -> DDPRequestUtil.postRequest(anyString(), any(), anyString(), anyBoolean())).thenReturn(500); + + // Assert that mocking is working correctly + Assert.assertEquals(500L, (long)DDPRequestUtil.postRequest("", "", "", true)); + + int kitRequestId = kitShippingTestUtil.createTestKitShippingWithKitType(participantDto, ddpInstanceDto, SALIVA, + kitTestUtil.getKitTypeId(), false); + KitRequestShipping kitRequestShipping = KitDao.getKitRequest(kitRequestId).orElseThrow(); + String kitLabel = "EVENT_KIT_LABEL_2"; + kitTestUtil.changeKitRequestShippingToSent(kitRequestShipping, kitLabel); + EventDto eventDto = eventDao.getEventForKit(EVENT_TYPE_SENT, kitRequestShipping.getDsmKitRequestId()).orElseThrow(); + assertEvent(eventDto, false, kitRequestShipping.getDsmKitRequestId(), null, ddpInstanceDto.getDdpInstanceId(), + EVENT_TYPE_SENT); + + eventServiceMockedStatic.verify(() -> EventService.sendDDPEventRequest(EVENT_TYPE_SENT, ddpInstance, 0L, + ddpParticipantId, kitRequestShipping.getDdpKitRequestId(), KitReasonType.NORMAL), times(MAX_TRIES)); + eventServiceMockedStatic.verify(() -> EventService.logTriggerFailure(any(), anyString(), anyString(), anyString(), + any()), never()); + eventServiceMockedStatic.verify(() -> EventService.logTriggerExhausted(ddpInstance, EVENT_TYPE_SENT, + ddpParticipantId, kitRequestShipping.getDdpKitRequestId()), times(1)); + } catch (IOException e) { + e.printStackTrace(); + Assert.fail("Unexpected exception"); + } + } + + @Test + public void testUnsuccessfulEvent_Exception() { + IOException exception = new IOException("Test IOException"); + try (MockedStatic eventServiceMockedStatic = Mockito.mockStatic(EventService.class, Mockito.CALLS_REAL_METHODS)) { + eventServiceMockedStatic.when(() -> EventService.sendDDPEventRequest(anyString(), any(), anyLong(), anyString(), anyString(), + any())).thenThrow(exception); + + int kitRequestId = kitShippingTestUtil.createTestKitShippingWithKitType(participantDto, ddpInstanceDto, SALIVA, + kitTestUtil.getKitTypeId(), false); + KitRequestShipping kitRequestShipping = KitDao.getKitRequest(kitRequestId).orElseThrow(); + String kitLabel = "EVENT_KIT_LABEL_3"; + kitTestUtil.changeKitRequestShippingToSent(kitRequestShipping, kitLabel); + EventDto eventDto = eventDao.getEventForKit(EVENT_TYPE_SENT, kitRequestShipping.getDsmKitRequestId()).orElseThrow(); + assertEvent(eventDto, false, kitRequestShipping.getDsmKitRequestId(), null, + ddpInstanceDto.getDdpInstanceId(), EVENT_TYPE_SENT); + + eventServiceMockedStatic.verify(() -> EventService.sendDDPEventRequest(EVENT_TYPE_SENT, ddpInstance, 0L, + ddpParticipantId, kitRequestShipping.getDdpKitRequestId(), KitReasonType.NORMAL), times(MAX_TRIES)); + eventServiceMockedStatic.verify(() -> EventService.logTriggerFailure(any(), anyString(), anyString(), anyString(), + any()), times(MAX_TRIES)); + eventServiceMockedStatic.verify(() -> EventService.logTriggerExhausted(ddpInstance, EVENT_TYPE_SENT, + ddpParticipantId, kitRequestShipping.getDdpKitRequestId()), times(1)); + } catch (Exception e) { + e.printStackTrace(); + Assert.fail("Unexpected exception"); + } + } + + @Test + public void testUnsuccessfulEvent_EventuallySuccessful() { + try (MockedStatic eventServiceMockedStatic = Mockito.mockStatic(EventService.class, Mockito.CALLS_REAL_METHODS)) { + eventServiceMockedStatic.when(() -> EventService.sendDDPEventRequest(anyString(), any(), Mockito.anyLong(), anyString(), + anyString(), any())).thenAnswer(new Answer() { + private int count = 0; + + @Override + public Boolean answer(InvocationOnMock invocation) { + if (count < 2) { + count++; + return false; + } else { + return true; + } + } + }); + + int kitRequestId = kitShippingTestUtil.createTestKitShippingWithKitType(participantDto, ddpInstanceDto, SALIVA, + kitTestUtil.getKitTypeId(), false); + KitRequestShipping kitRequestShipping = KitDao.getKitRequest(kitRequestId).orElseThrow(); + String kitLabel = "EVENT_KIT_LABEL_4"; + kitTestUtil.changeKitRequestShippingToSent(kitRequestShipping, kitLabel); + EventDto eventDto = eventDao.getEventForKit(EVENT_TYPE_SENT, kitRequestShipping.getDsmKitRequestId()).orElseThrow(); + assertEvent(eventDto, true, kitRequestShipping.getDsmKitRequestId(), null, + ddpInstanceDto.getDdpInstanceId(), EVENT_TYPE_SENT); + + eventServiceMockedStatic.verify(() -> EventService.sendDDPEventRequest(EVENT_TYPE_SENT, ddpInstance, 0L, + ddpParticipantId, kitRequestShipping.getDdpKitRequestId(), KitReasonType.NORMAL), times(3)); + eventServiceMockedStatic.verify(() -> EventService.logTriggerFailure(any(), anyString(), anyString(), anyString(), + any()), never()); + eventServiceMockedStatic.verify(() -> EventService.logTriggerExhausted(ddpInstance, EVENT_TYPE_SENT, + ddpParticipantId, kitRequestShipping.getDdpKitRequestId()), never()); + } catch (Exception e) { + e.printStackTrace(); + Assert.fail("Unexpected exception"); + } + } + + @Test + public void testReceivedKitEvent() { + try (MockedStatic eventServiceMockedStatic = Mockito.mockStatic(EventService.class, Mockito.CALLS_REAL_METHODS); + MockedStatic utilities = Mockito.mockStatic(DDPRequestUtil.class)) { + NotificationUtil mockedNotificationUtil = mock(NotificationUtil.class); + + utilities.when(() -> DDPRequestUtil.postRequest(anyString(), any(), anyString(), anyBoolean())).thenReturn(200); + + int kitRequestId = kitShippingTestUtil.createTestKitShippingWithKitType(participantDto, ddpInstanceDto, SALIVA, + kitTestUtil.getKitTypeId(), false); + KitRequestShipping kitRequestShipping = KitDao.getKitRequest(kitRequestId).orElseThrow(); + String kitLabel = "EVENT_KIT_LABEL_5"; + kitTestUtil.changeKitRequestShippingToSent(kitRequestShipping, kitLabel); + + BSPKit bspKit = new BSPKit(); + Optional optionalBSPKitDto = bspKit.canReceiveKit(kitLabel); + if (optionalBSPKitDto.isEmpty()) { + Assert.fail("Kit not found in ddp_kit table"); + } + Optional result = bspKit.getKitStatus(optionalBSPKitDto.get(), mockedNotificationUtil); + if (!result.isEmpty()) { + Assert.fail("Kit should not be from a pt which is withdrawn"); + } + bspKit.receiveKit(kitLabel, optionalBSPKitDto.get(), mockedNotificationUtil, "BSP").get(); + + EventDto eventDto = eventDao.getEventForKit(EVENT_TYPE_RECEIVED, kitRequestShipping.getDsmKitRequestId()).orElseThrow(); + assertEvent(eventDto, true, kitRequestShipping.getDsmKitRequestId(), null, ddpInstanceDto.getDdpInstanceId(), + EVENT_TYPE_RECEIVED); + + eventServiceMockedStatic.verify(() -> EventService.sendDDPEventRequest(EVENT_TYPE_SENT, ddpInstance, 0L, + ddpParticipantId, kitRequestShipping.getDdpKitRequestId(), KitReasonType.NORMAL), times(1)); + eventServiceMockedStatic.verify(() -> EventService.logTriggerFailure(any(), anyString(), anyString(), anyString(), any()), + never()); + eventServiceMockedStatic.verify(() -> EventService.logTriggerExhausted(ddpInstance, EVENT_TYPE_SENT, + ddpParticipantId, kitRequestShipping.getDdpKitRequestId()), never()); + } catch (Exception e) { + e.printStackTrace(); + Assert.fail("Unexpected exception"); + } + } + + private void assertEvent(EventDto eventDto, boolean expectedTrigger, Integer expectedDsmKitRequestId, String expectedDdpParticipantId, + Integer ddpInstanceId, String eventType) { + Assert.assertEquals(expectedTrigger, eventDto.getEventTriggered()); + Assert.assertEquals(expectedDsmKitRequestId, eventDto.getDsmKitRequestId()); + Assert.assertEquals(expectedDdpParticipantId, eventDto.getDdpParticipantId()); + Assert.assertEquals((long) ddpInstanceId, eventDto.getDdpInstanceId()); + Assert.assertEquals(eventType, eventDto.getEventType()); + } +} diff --git a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/service/admin/UserAdminTestUtil.java b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/service/admin/UserAdminTestUtil.java index 4dfc85af4c..67b66f30df 100644 --- a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/service/admin/UserAdminTestUtil.java +++ b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/service/admin/UserAdminTestUtil.java @@ -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 + * @param adminRole PEPPER_ADMIN_ROLE or STUDY_USER_ADMIN * @param rolesToManage actual DSM roles * @return study admin user ID */ diff --git a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/service/adminoperation/UpdateKitToLegacyIdServiceTest.java b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/service/adminoperation/UpdateKitToLegacyIdServiceTest.java index 4aadfe3f2d..71fdd9e1c3 100644 --- a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/service/adminoperation/UpdateKitToLegacyIdServiceTest.java +++ b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/service/adminoperation/UpdateKitToLegacyIdServiceTest.java @@ -11,7 +11,7 @@ import org.broadinstitute.dsm.db.dao.ddp.instance.DDPInstanceDao; import org.broadinstitute.dsm.db.dto.ddp.instance.DDPInstanceDto; import org.broadinstitute.dsm.db.dto.ddp.participant.ParticipantDto; -import org.broadinstitute.dsm.kits.TestKitUtil; +import org.broadinstitute.dsm.kits.KitTestUtil; import org.broadinstitute.dsm.model.elastic.Dsm; import org.broadinstitute.dsm.model.elastic.search.ElasticSearchParticipantDto; import org.broadinstitute.dsm.service.elastic.ElasticSearchService; @@ -33,7 +33,7 @@ public class UpdateKitToLegacyIdServiceTest extends DbAndElasticBaseTest { private static String ddpParticipantId = "PT_SAMPLE_QUEUE_TEST"; private static int participantCounter = 0; private static Pair legacyParticipantPair; - private static TestKitUtil testKitUtil; + private static KitTestUtil kitTestUtil; private static final String newCollaboratorSampleId = "NEW_SAMPLE_ID"; private static final String newCollaboratorParticipantId = "NEW_PARTICIPANT_ID"; @@ -47,8 +47,9 @@ public class UpdateKitToLegacyIdServiceTest extends DbAndElasticBaseTest { @BeforeClass public static void doFirst() { esIndex = ElasticTestUtil.createIndex(instanceName, "elastic/lmsMappings.json", null); - testKitUtil = new TestKitUtil(instanceName, instanceName, "UpdateCollab", instanceName, "SALIVA", null, esIndex); - testKitUtil.setupInstanceAndSettings(); + kitTestUtil = new KitTestUtil(instanceName, instanceName, "UpdateCollab", instanceName, "SALIVA", null, esIndex, + false); + kitTestUtil.setupInstanceAndSettings(); ddpInstanceDto = ddpInstanceDao.getDDPInstanceByInstanceName(instanceName).orElseThrow(); legacyParticipantPair = TestParticipantUtil.createLegacyParticipant(ddpParticipantId, participantCounter++, ddpInstanceDto, shortId, legacyShortId); @@ -59,9 +60,9 @@ public static void doFirst() { .withBspCollaboratorParticipantId(oldCollaboratorParticipantId) .withDdpKitRequestId(ddpKitRequestId) .withKitTypeName("SALIVA") - .withKitTypeId(String.valueOf(testKitUtil.kitTypeId)).build(); + .withKitTypeId(String.valueOf(kitTestUtil.getKitTypeId())).build(); - String dsmKitRequestId = testKitUtil.createKitRequestShipping(kitRequestShipping, DDPInstance.from(ddpInstanceDto), "100"); + String dsmKitRequestId = kitTestUtil.createKitRequestShipping(kitRequestShipping, DDPInstance.from(ddpInstanceDto), "100"); createdKits.add(dsmKitRequestId); } @@ -69,8 +70,8 @@ public static void doFirst() { public static void tearDown() { participants.forEach(participantDto -> TestParticipantUtil.deleteParticipant(participantDto.getRequiredParticipantId())); - createdKits.forEach(dsmKitRequestId -> testKitUtil.deleteKitRequestShipping((Integer.parseInt(dsmKitRequestId)))); - testKitUtil.deleteGeneratedData(); + createdKits.forEach(dsmKitRequestId -> kitTestUtil.deleteKitRequestShipping((Integer.parseInt(dsmKitRequestId)))); + kitTestUtil.deleteGeneratedData(); ddpInstanceDao.delete(ddpInstanceDto.getDdpInstanceId()); ElasticTestUtil.deleteIndex(esIndex); } @@ -110,8 +111,8 @@ public void test_notUpdateWhenDuplicateCollaboratorSampleID() { .withBspCollaboratorParticipantId(collaboratorParticipantId) .withDdpKitRequestId("KIT_REQ_ID_DUP_KIT1") .withKitTypeName("SALIVA") - .withKitTypeId(String.valueOf(testKitUtil.kitTypeId)).build(); - String dsmKitRequestId = testKitUtil.createKitRequestShipping(kitRequestShipping, DDPInstance.from(ddpInstanceDto), "100"); + .withKitTypeId(String.valueOf(kitTestUtil.getKitTypeId())).build(); + String dsmKitRequestId = kitTestUtil.createKitRequestShipping(kitRequestShipping, DDPInstance.from(ddpInstanceDto), "100"); createdKits.add(dsmKitRequestId); String dupCollaboratorSampleId = "DUP_COLLABORATOR_SAMPLE_ID"; KitRequestShipping kitRequestShipping2 = KitRequestShipping.builder() @@ -120,8 +121,8 @@ public void test_notUpdateWhenDuplicateCollaboratorSampleID() { .withBspCollaboratorParticipantId(collaboratorParticipantId) .withDdpKitRequestId("KIT_REQ_ID_DUP_KIT2") .withKitTypeName("SALIVA") - .withKitTypeId(String.valueOf(testKitUtil.kitTypeId)).build(); - String dsmKitRequestId2 = testKitUtil.createKitRequestShipping(kitRequestShipping2, DDPInstance.from(ddpInstanceDto), "100"); + .withKitTypeId(String.valueOf(kitTestUtil.getKitTypeId())).build(); + String dsmKitRequestId2 = kitTestUtil.createKitRequestShipping(kitRequestShipping2, DDPInstance.from(ddpInstanceDto), "100"); createdKits.add(dsmKitRequestId2); UpdateKitToLegacyIdsRequest duplicateSampleIdRequest = new UpdateKitToLegacyIdsRequest(collaboratorSampleId, diff --git a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/util/KitShippingTestUtil.java b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/util/KitShippingTestUtil.java index ad567b1e69..68dce365d2 100644 --- a/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/util/KitShippingTestUtil.java +++ b/pepper-apis/dsm-core/src/test/java/org/broadinstitute/dsm/util/KitShippingTestUtil.java @@ -59,14 +59,21 @@ public void tearDown() { } public int createTestKitShipping(ParticipantDto participant, DDPInstanceDto instanceDto) { + KitTypeDto kitTypeDto = createKitType("SALIVA"); + return createTestKitShippingWithKitType(participant, instanceDto, kitTypeDto.getKitTypeName(), kitTypeDto.getKitTypeId(), true); + } + + public int createTestKitShippingWithKitType(ParticipantDto participant, DDPInstanceDto instanceDto, String kitTypeName, int kitTypeId, + boolean addKitType) { participantCounter++; String ddpParticipantId = participant.getDdpParticipantIdOrThrow(); - KitTypeDto kitTypeDto = createKitType("SALIVA"); - addKitType(ddpParticipantId, kitTypeDto.getKitTypeId()); - int kitRequestId = createKitShipping(participant, instanceDto, kitTypeDto); - addKitRequest(ddpParticipantId, kitRequestId); - log.info("Created kit request with id {} for ptp {}", kitRequestId, ddpParticipantId); - return kitRequestId; + if (addKitType) { + addKitType(ddpParticipantId, kitTypeId); + } + int dsmKitRequestId = createKitShipping(participant, instanceDto, kitTypeName, kitTypeId); + addKitRequest(ddpParticipantId, dsmKitRequestId); + log.info("Created kit request with id {} for ptp {}", dsmKitRequestId, ddpParticipantId); + return dsmKitRequestId; } public List getParticipantKitRequestIds(String ddpParticipantId) { @@ -77,13 +84,17 @@ public List getParticipantKitRequestIds(String ddpParticipantId) { return ids; } - private int createKitShipping(ParticipantDto participant, DDPInstanceDto instanceDto, KitTypeDto kitTypeDto) { + /** + * Creates a kit shipping request for a participant. + * @return dsmKitRequestId + */ + public int createKitShipping(ParticipantDto participant, DDPInstanceDto instanceDto, String kitTypeName, int kitTypeId) { DDPInstance ddpInstance = DDPInstance.getDDPInstance(instanceDto.getInstanceName()); String dsmKitRequestId = genDsmKitRequestId(); String kitReqestIdStr = KitRequestShipping.writeRequest(instanceDto.getDdpInstanceId().toString(), - dsmKitRequestId, kitTypeDto.getKitTypeId(), participant.getDdpParticipantIdOrThrow(), + dsmKitRequestId, kitTypeId, participant.getDdpParticipantIdOrThrow(), "test", "test", testUser, "test", "", "test", - false, "test", ddpInstance, kitTypeDto.getKitTypeName(), dsmKitRequestId); + false, null, ddpInstance, kitTypeName, dsmKitRequestId); return Integer.parseInt(kitReqestIdStr); } diff --git a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/content/RenderValueProvider.java b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/content/RenderValueProvider.java index cc95b9fb1c..9ed6dcf936 100644 --- a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/content/RenderValueProvider.java +++ b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/content/RenderValueProvider.java @@ -22,7 +22,7 @@ import org.broadinstitute.ddp.model.activity.instance.answer.PicklistAnswer; import org.broadinstitute.ddp.model.activity.instance.question.Question; import org.broadinstitute.ddp.model.activity.types.QuestionType; -import org.broadinstitute.ddp.model.dsm.KitReasonType; +import org.broadinstitute.ddp.notficationevent.KitReasonType; import org.broadinstitute.ddp.model.dsm.TestResult; /** @@ -130,10 +130,10 @@ public String participantBirthDate(String format) { /** * If the current activity has been previously completed, returns the date of completion. - * + * *

See {@link java.time.format.DateTimeFormatter#ofPattern(String)} for more information * about supported format strings. - * @param format The date format string to use. + * @param format The date format string to use. * @param defaultValue The string to return if there is no valid date * @return the formatted date of first completion, or `defaultValue` if one does not exist */ @@ -271,10 +271,10 @@ public String activityInstanceNumberDisplay(int offsetToSubtract, int numberCuto /** * Returns a string value depending on whether a specified PICKLIST question's option * is selected or not. - * - *

If {@link useDefaultsForDdpMethods} is true, this method will always return + * + *

If {@link #useDefaultsForDdpMethods} is true, this method will always return * a value of the form "stringIfMatches/stringOtherwise". - * + * *

If an activity does not have a response, * or the question does not have an associated answer, a match will be assumed, * and the `stringIfMatches` value will be returned. diff --git a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/db/dao/EventTriggerDao.java b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/db/dao/EventTriggerDao.java index a49321625e..1b158627cc 100644 --- a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/db/dao/EventTriggerDao.java +++ b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/db/dao/EventTriggerDao.java @@ -6,8 +6,8 @@ import org.broadinstitute.ddp.db.DaoException; import org.broadinstitute.ddp.model.activity.types.EventTriggerType; import org.broadinstitute.ddp.model.activity.types.InstanceStatusType; -import org.broadinstitute.ddp.model.dsm.DsmNotificationEventType; import org.broadinstitute.ddp.model.user.EnrollmentStatusType; +import org.broadinstitute.ddp.notficationevent.DsmNotificationEventType; import org.jdbi.v3.sqlobject.CreateSqlObject; public interface EventTriggerDao { diff --git a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/db/dao/EventTriggerSql.java b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/db/dao/EventTriggerSql.java index 5a7b3b3f34..9df56f29f8 100644 --- a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/db/dao/EventTriggerSql.java +++ b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/db/dao/EventTriggerSql.java @@ -1,7 +1,7 @@ package org.broadinstitute.ddp.db.dao; import org.broadinstitute.ddp.model.activity.types.EventTriggerType; -import org.broadinstitute.ddp.model.dsm.DsmNotificationEventType; +import org.broadinstitute.ddp.notficationevent.DsmNotificationEventType; import org.broadinstitute.ddp.model.user.EnrollmentStatusType; import org.jdbi.v3.sqlobject.SqlObject; import org.jdbi.v3.sqlobject.customizer.Bind; diff --git a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/db/dto/EventConfigurationDto.java b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/db/dto/EventConfigurationDto.java index 80de272909..50a7b90c68 100644 --- a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/db/dto/EventConfigurationDto.java +++ b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/db/dto/EventConfigurationDto.java @@ -11,7 +11,7 @@ import org.broadinstitute.ddp.model.activity.types.EventActionType; import org.broadinstitute.ddp.model.activity.types.EventTriggerType; import org.broadinstitute.ddp.model.activity.types.InstanceStatusType; -import org.broadinstitute.ddp.model.dsm.DsmNotificationEventType; +import org.broadinstitute.ddp.notficationevent.DsmNotificationEventType; import org.broadinstitute.ddp.model.event.NotificationServiceType; import org.broadinstitute.ddp.model.event.NotificationType; import org.broadinstitute.ddp.model.event.PdfAttachment; diff --git a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/event/pubsubtask/api/PubSubTaskConnectionService.java b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/event/pubsubtask/api/PubSubTaskConnectionService.java index c106ea8e4b..351c59cd4b 100644 --- a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/event/pubsubtask/api/PubSubTaskConnectionService.java +++ b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/event/pubsubtask/api/PubSubTaskConnectionService.java @@ -9,7 +9,6 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; - import com.google.api.gax.core.ExecutorProvider; import com.google.api.gax.core.InstantiatingExecutorProvider; import com.google.cloud.pubsub.v1.Publisher; diff --git a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/model/event/DsmNotificationSignal.java b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/model/event/DsmNotificationSignal.java index 30d78ba188..1d6309c738 100644 --- a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/model/event/DsmNotificationSignal.java +++ b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/model/event/DsmNotificationSignal.java @@ -3,9 +3,9 @@ import javax.annotation.Nullable; import org.broadinstitute.ddp.model.activity.types.EventTriggerType; -import org.broadinstitute.ddp.model.dsm.DsmNotificationEventType; -import org.broadinstitute.ddp.model.dsm.KitReasonType; +import org.broadinstitute.ddp.notficationevent.DsmNotificationEventType; import org.broadinstitute.ddp.model.dsm.TestResult; +import org.broadinstitute.ddp.notficationevent.KitReasonType; public class DsmNotificationSignal extends EventSignal { diff --git a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/model/event/DsmNotificationTrigger.java b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/model/event/DsmNotificationTrigger.java index 8c29145529..7aa6551964 100644 --- a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/model/event/DsmNotificationTrigger.java +++ b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/model/event/DsmNotificationTrigger.java @@ -1,7 +1,7 @@ package org.broadinstitute.ddp.model.event; import org.broadinstitute.ddp.db.dto.EventConfigurationDto; -import org.broadinstitute.ddp.model.dsm.DsmNotificationEventType; +import org.broadinstitute.ddp.notficationevent.DsmNotificationEventType; import org.jdbi.v3.core.Handle; public class DsmNotificationTrigger extends EventTrigger { diff --git a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/route/ReceiveDsmNotificationRoute.java b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/route/ReceiveDsmNotificationRoute.java index 73ce3472c8..8ddf83ad1c 100644 --- a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/route/ReceiveDsmNotificationRoute.java +++ b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/route/ReceiveDsmNotificationRoute.java @@ -17,10 +17,10 @@ import org.broadinstitute.ddp.db.dto.StudyDto; import org.broadinstitute.ddp.db.dto.kit.KitConfigurationDto; import org.broadinstitute.ddp.exception.DDPException; -import org.broadinstitute.ddp.json.dsm.DsmNotificationPayload; +import org.broadinstitute.ddp.notficationevent.DsmNotificationPayload; import org.broadinstitute.ddp.json.errors.ApiError; -import org.broadinstitute.ddp.model.dsm.DsmNotificationEventType; -import org.broadinstitute.ddp.model.dsm.KitReasonType; +import org.broadinstitute.ddp.notficationevent.DsmNotificationEventType; +import org.broadinstitute.ddp.notficationevent.KitReasonType; import org.broadinstitute.ddp.model.dsm.KitType; import org.broadinstitute.ddp.model.dsm.TestResult; import org.broadinstitute.ddp.model.event.DsmNotificationSignal; diff --git a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/service/ActivityInstanceCreationService.java b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/service/ActivityInstanceCreationService.java index 50f3363b16..95645b2b78 100644 --- a/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/service/ActivityInstanceCreationService.java +++ b/pepper-apis/dss-core/src/main/java/org/broadinstitute/ddp/service/ActivityInstanceCreationService.java @@ -16,11 +16,11 @@ import org.broadinstitute.ddp.exception.DDPException; import org.broadinstitute.ddp.model.activity.types.EventTriggerType; import org.broadinstitute.ddp.model.activity.types.InstanceStatusType; -import org.broadinstitute.ddp.model.dsm.DsmNotificationEventType; import org.broadinstitute.ddp.model.dsm.TestResult; import org.broadinstitute.ddp.model.event.ActivityInstanceStatusChangeSignal; import org.broadinstitute.ddp.model.event.DsmNotificationSignal; import org.broadinstitute.ddp.model.event.EventSignal; +import org.broadinstitute.ddp.notficationevent.DsmNotificationEventType; import org.jdbi.v3.core.Handle; /** diff --git a/pepper-apis/dss-core/src/test/java/org/broadinstitute/ddp/export/DataExporterTest.java b/pepper-apis/dss-core/src/test/java/org/broadinstitute/ddp/export/DataExporterTest.java index 7142334b19..c823b9a309 100644 --- a/pepper-apis/dss-core/src/test/java/org/broadinstitute/ddp/export/DataExporterTest.java +++ b/pepper-apis/dss-core/src/test/java/org/broadinstitute/ddp/export/DataExporterTest.java @@ -92,7 +92,6 @@ import org.broadinstitute.ddp.model.activity.types.TemplateType; import org.broadinstitute.ddp.model.activity.types.TextInputType; import org.broadinstitute.ddp.model.address.MailAddress; -import org.broadinstitute.ddp.model.dsm.KitReasonType; import org.broadinstitute.ddp.model.files.FileScanResult; import org.broadinstitute.ddp.model.files.FileUpload; import org.broadinstitute.ddp.model.governance.AgeOfMajorityRule; @@ -102,6 +101,7 @@ import org.broadinstitute.ddp.model.user.EnrollmentStatusType; import org.broadinstitute.ddp.model.user.User; import org.broadinstitute.ddp.model.user.UserProfile; +import org.broadinstitute.ddp.notficationevent.KitReasonType; import org.broadinstitute.ddp.pex.PexInterpreter; import org.broadinstitute.ddp.service.AddressService; import org.broadinstitute.ddp.service.DsmAddressValidationStatus; diff --git a/pepper-apis/dss-core/src/test/java/org/broadinstitute/ddp/pex/TreeWalkInterpreterTest.java b/pepper-apis/dss-core/src/test/java/org/broadinstitute/ddp/pex/TreeWalkInterpreterTest.java index 7f8f6a347e..8eb89f1ec2 100644 --- a/pepper-apis/dss-core/src/test/java/org/broadinstitute/ddp/pex/TreeWalkInterpreterTest.java +++ b/pepper-apis/dss-core/src/test/java/org/broadinstitute/ddp/pex/TreeWalkInterpreterTest.java @@ -69,8 +69,8 @@ import org.broadinstitute.ddp.model.activity.types.MatrixSelectMode; import org.broadinstitute.ddp.model.activity.types.TemplateType; import org.broadinstitute.ddp.model.activity.types.TextInputType; -import org.broadinstitute.ddp.model.dsm.DsmNotificationEventType; -import org.broadinstitute.ddp.model.dsm.KitReasonType; +import org.broadinstitute.ddp.notficationevent.DsmNotificationEventType; +import org.broadinstitute.ddp.notficationevent.KitReasonType; import org.broadinstitute.ddp.model.dsm.TestResult; import org.broadinstitute.ddp.model.event.ActivityInstanceStatusChangeSignal; import org.broadinstitute.ddp.model.event.DsmNotificationSignal; diff --git a/pepper-apis/dss-core/src/test/java/org/broadinstitute/ddp/route/ReceiveDsmNotificationRouteTest.java b/pepper-apis/dss-core/src/test/java/org/broadinstitute/ddp/route/ReceiveDsmNotificationRouteTest.java index d846bf00b9..92762dc57f 100644 --- a/pepper-apis/dss-core/src/test/java/org/broadinstitute/ddp/route/ReceiveDsmNotificationRouteTest.java +++ b/pepper-apis/dss-core/src/test/java/org/broadinstitute/ddp/route/ReceiveDsmNotificationRouteTest.java @@ -1,10 +1,10 @@ package org.broadinstitute.ddp.route; import static io.restassured.RestAssured.given; -import static org.broadinstitute.ddp.model.dsm.DsmNotificationEventType.SALIVA_RECEIVED; -import static org.broadinstitute.ddp.model.dsm.DsmNotificationEventType.TESTBOSTON_RECEIVED; -import static org.broadinstitute.ddp.model.dsm.DsmNotificationEventType.TESTBOSTON_SENT; -import static org.broadinstitute.ddp.model.dsm.DsmNotificationEventType.TEST_RESULT; +import static org.broadinstitute.ddp.notficationevent.DsmNotificationEventType.SALIVA_RECEIVED; +import static org.broadinstitute.ddp.notficationevent.DsmNotificationEventType.TESTBOSTON_RECEIVED; +import static org.broadinstitute.ddp.notficationevent.DsmNotificationEventType.TESTBOSTON_SENT; +import static org.broadinstitute.ddp.notficationevent.DsmNotificationEventType.TEST_RESULT; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertEquals; @@ -47,13 +47,13 @@ import org.broadinstitute.ddp.db.dto.QueuedNotificationDto; import org.broadinstitute.ddp.db.dto.SendgridEmailEventActionDto; import org.broadinstitute.ddp.db.dto.StudyDto; -import org.broadinstitute.ddp.json.dsm.DsmNotificationPayload; +import org.broadinstitute.ddp.notficationevent.DsmNotificationPayload; import org.broadinstitute.ddp.model.activity.definition.FormActivityDef; import org.broadinstitute.ddp.model.activity.definition.i18n.Translation; import org.broadinstitute.ddp.model.activity.instance.ActivityResponse; import org.broadinstitute.ddp.model.activity.revision.RevisionMetadata; -import org.broadinstitute.ddp.model.dsm.DsmNotificationEventType; -import org.broadinstitute.ddp.model.dsm.KitReasonType; +import org.broadinstitute.ddp.notficationevent.DsmNotificationEventType; +import org.broadinstitute.ddp.notficationevent.KitReasonType; import org.broadinstitute.ddp.model.dsm.TestResult; import org.broadinstitute.ddp.model.pex.Expression; import org.broadinstitute.ddp.model.user.EnrollmentStatusType; diff --git a/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/EventBuilder.java b/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/EventBuilder.java index de418e8b0c..4a940ae169 100644 --- a/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/EventBuilder.java +++ b/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/EventBuilder.java @@ -42,7 +42,7 @@ import org.broadinstitute.ddp.model.copy.CopyLocationType; import org.broadinstitute.ddp.model.copy.CopyPreviousInstanceFilter; import org.broadinstitute.ddp.model.copy.UserType; -import org.broadinstitute.ddp.model.dsm.DsmNotificationEventType; +import org.broadinstitute.ddp.notficationevent.DsmNotificationEventType; import org.broadinstitute.ddp.model.event.ActivityStatusChangeTrigger; import org.broadinstitute.ddp.model.event.DsmNotificationTrigger; import org.broadinstitute.ddp.model.event.EventTrigger; diff --git a/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/CircadiaUpdateDLMOInstructionsTrigger.java b/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/CircadiaUpdateDLMOInstructionsTrigger.java index 0380857d3f..0718c97294 100644 --- a/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/CircadiaUpdateDLMOInstructionsTrigger.java +++ b/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/CircadiaUpdateDLMOInstructionsTrigger.java @@ -1,5 +1,11 @@ package org.broadinstitute.ddp.studybuilder.task; +import java.io.File; +import java.nio.file.Path; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; + import com.google.gson.Gson; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; @@ -21,10 +27,10 @@ import org.broadinstitute.ddp.model.activity.definition.FormSectionDef; import org.broadinstitute.ddp.model.activity.types.EventTriggerType; import org.broadinstitute.ddp.model.activity.types.InstanceStatusType; -import org.broadinstitute.ddp.model.dsm.DsmNotificationEventType; import org.broadinstitute.ddp.model.event.ActivityInstanceCreationEventAction; import org.broadinstitute.ddp.model.event.DsmNotificationTrigger; import org.broadinstitute.ddp.model.event.EventConfiguration; +import org.broadinstitute.ddp.notficationevent.DsmNotificationEventType; import org.broadinstitute.ddp.util.ConfigUtil; import org.broadinstitute.ddp.util.GsonUtil; import org.jdbi.v3.core.Handle; @@ -33,12 +39,6 @@ import org.jdbi.v3.sqlobject.statement.SqlQuery; import org.jdbi.v3.sqlobject.statement.SqlUpdate; -import java.io.File; -import java.nio.file.Path; -import java.util.Comparator; -import java.util.List; -import java.util.stream.Collectors; - /** * One-off task to update configurations and events to support kit uploads and adhoc survey in deployed environments. */ diff --git a/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/LmsInsertDsmEvents.java b/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/LmsInsertDsmEvents.java index c032a260ac..702bb509b8 100644 --- a/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/LmsInsertDsmEvents.java +++ b/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/LmsInsertDsmEvents.java @@ -7,9 +7,9 @@ import org.broadinstitute.ddp.db.dao.JdbiUmbrellaStudy; import org.broadinstitute.ddp.model.activity.types.EventActionType; import org.broadinstitute.ddp.model.activity.types.EventTriggerType; -import org.broadinstitute.ddp.model.dsm.DsmNotificationEventType; import org.broadinstitute.ddp.model.event.DsmNotificationTrigger; import org.broadinstitute.ddp.model.event.EventConfiguration; +import org.broadinstitute.ddp.notficationevent.DsmNotificationEventType; import org.jdbi.v3.core.Handle; @Slf4j diff --git a/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/OsteoInsertDsmEvents.java b/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/OsteoInsertDsmEvents.java index fff5c88d16..6885c32ada 100644 --- a/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/OsteoInsertDsmEvents.java +++ b/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/OsteoInsertDsmEvents.java @@ -7,7 +7,7 @@ import org.broadinstitute.ddp.db.dao.JdbiUmbrellaStudy; import org.broadinstitute.ddp.model.activity.types.EventActionType; import org.broadinstitute.ddp.model.activity.types.EventTriggerType; -import org.broadinstitute.ddp.model.dsm.DsmNotificationEventType; +import org.broadinstitute.ddp.notficationevent.DsmNotificationEventType; import org.broadinstitute.ddp.model.event.DsmNotificationTrigger; import org.broadinstitute.ddp.model.event.EventConfiguration; import org.jdbi.v3.core.Handle; diff --git a/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/TestBostonEnableKitUploads.java b/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/TestBostonEnableKitUploads.java index c50d7da098..29a951b2e2 100644 --- a/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/TestBostonEnableKitUploads.java +++ b/pepper-apis/studybuilder-cli/src/main/java/org/broadinstitute/ddp/studybuilder/task/TestBostonEnableKitUploads.java @@ -21,7 +21,7 @@ import org.broadinstitute.ddp.model.activity.types.EventActionType; import org.broadinstitute.ddp.model.activity.types.EventTriggerType; import org.broadinstitute.ddp.model.activity.types.InstanceStatusType; -import org.broadinstitute.ddp.model.dsm.DsmNotificationEventType; +import org.broadinstitute.ddp.notficationevent.DsmNotificationEventType; import org.broadinstitute.ddp.model.event.ActivityStatusChangeTrigger; import org.broadinstitute.ddp.model.event.DsmNotificationTrigger; import org.broadinstitute.ddp.model.event.EventConfiguration;