Skip to content

Commit

Permalink
fix: (2.39) Indiscriminately sending program notifications [DHIS2-171…
Browse files Browse the repository at this point in the history
…80] (#17948)
  • Loading branch information
zubaira authored Jul 2, 2024
1 parent f07cdb4 commit 877838e
Show file tree
Hide file tree
Showing 7 changed files with 369 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ public TrackerTypeReport persist(Session session, TrackerBundle bundle) {
}
}

if (!bundle.isSkipSideEffects()) {
sideEffectDataBundles.add(handleSideEffects(bundle, convertedDto));
}

//
// Add the entity to the Preheat
//
Expand All @@ -154,10 +158,6 @@ public TrackerTypeReport persist(Session session, TrackerBundle bundle) {
session.flush();
}

if (!bundle.isSkipSideEffects()) {
sideEffectDataBundles.add(handleSideEffects(bundle, convertedDto));
}

bundle.setUpdatedTrackedEntities(updatedTrackedEntities);
} catch (Exception e) {
final String msg =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
*/
package org.hisp.dhis.tracker.bundle.persister;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import org.hibernate.Session;
import org.hisp.dhis.program.ProgramInstance;
Expand All @@ -42,6 +44,7 @@
import org.hisp.dhis.tracker.converter.TrackerConverterService;
import org.hisp.dhis.tracker.converter.TrackerSideEffectConverterService;
import org.hisp.dhis.tracker.domain.Enrollment;
import org.hisp.dhis.tracker.job.SideEffectTrigger;
import org.hisp.dhis.tracker.job.TrackerSideEffectDataBundle;
import org.hisp.dhis.tracker.preheat.TrackerPreheat;
import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -124,6 +127,22 @@ protected boolean isNew(TrackerPreheat preheat, String uid) {
@Override
protected TrackerSideEffectDataBundle handleSideEffects(
TrackerBundle bundle, ProgramInstance programInstance) {
TrackerPreheat preheat = bundle.getPreheat();
List<SideEffectTrigger> triggers = new ArrayList<>();

if (isNew(preheat, programInstance.getUid())) {
triggers.add(SideEffectTrigger.ENROLLMENT);
if (programInstance.isCompleted()) {
triggers.add(SideEffectTrigger.ENROLLMENT_COMPLETION);
}
} else {
ProgramInstance exitingEnrollment = preheat.getEnrollment(programInstance.getUid());
if (exitingEnrollment.getStatus() != programInstance.getStatus()
&& programInstance.isCompleted()) {
triggers.add(SideEffectTrigger.ENROLLMENT_COMPLETION);
}
}

return TrackerSideEffectDataBundle.builder()
.klass(ProgramInstance.class)
.enrollmentRuleEffects(
Expand All @@ -134,6 +153,9 @@ protected TrackerSideEffectDataBundle handleSideEffects(
.accessedBy(bundle.getUsername())
.programInstance(programInstance)
.program(programInstance.getProgram())
.programInstance(programInstance)
.program(programInstance.getProgram())
.triggers(triggers)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@
import static com.google.common.base.Preconditions.checkNotNull;

import java.time.Instant;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
Expand All @@ -59,6 +61,7 @@
import org.hisp.dhis.tracker.converter.TrackerSideEffectConverterService;
import org.hisp.dhis.tracker.domain.DataValue;
import org.hisp.dhis.tracker.domain.Event;
import org.hisp.dhis.tracker.job.SideEffectTrigger;
import org.hisp.dhis.tracker.job.TrackerSideEffectDataBundle;
import org.hisp.dhis.tracker.preheat.TrackerPreheat;
import org.hisp.dhis.util.DateUtils;
Expand Down Expand Up @@ -116,6 +119,21 @@ protected boolean isNew(TrackerPreheat preheat, String uid) {
@Override
protected TrackerSideEffectDataBundle handleSideEffects(
TrackerBundle bundle, ProgramStageInstance programStageInstance) {
TrackerPreheat preheat = bundle.getPreheat();
List<SideEffectTrigger> triggers = new ArrayList<>();

if (isNew(preheat, programStageInstance.getUid())) {
if (programStageInstance.isCompleted()) {
triggers.add(SideEffectTrigger.EVENT_COMPLETION);
}
} else {
ProgramStageInstance existingEvent = preheat.getEvent(programStageInstance.getUid());
if (existingEvent.getStatus() != programStageInstance.getStatus()
&& programStageInstance.isCompleted()) {
triggers.add(SideEffectTrigger.EVENT_COMPLETION);
}
}

return TrackerSideEffectDataBundle.builder()
.klass(ProgramStageInstance.class)
.enrollmentRuleEffects(new HashMap<>())
Expand All @@ -126,6 +144,9 @@ protected TrackerSideEffectDataBundle handleSideEffects(
.accessedBy(bundle.getUsername())
.programStageInstance(programStageInstance)
.program(programStageInstance.getProgramStage().getProgram())
.programStageInstance(programStageInstance)
.program(programStageInstance.getProgramStage().getProgram())
.triggers(triggers)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2004-2024, University of Oslo
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* Neither the name of the HISP project nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.hisp.dhis.tracker.job;

/**
* @author Zubair Asghar
*/
public enum SideEffectTrigger {
ENROLLMENT,
ENROLLMENT_COMPLETION,
EVENT_COMPLETION,
NONE
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,10 @@
*/
package org.hisp.dhis.tracker.job;

import com.google.common.collect.ImmutableMap;
import java.util.Map;
import java.util.function.Consumer;
import org.hisp.dhis.common.BaseIdentifiableObject;
import org.hisp.dhis.common.IdentifiableObjectManager;
import org.hisp.dhis.program.ProgramInstance;
import org.hisp.dhis.program.ProgramStageInstance;
import org.hisp.dhis.program.notification.ProgramNotificationService;
import org.hisp.dhis.security.SecurityContextRunnable;
import org.hisp.dhis.system.notification.NotificationLevel;
Expand All @@ -52,30 +50,25 @@
public class TrackerNotificationThread extends SecurityContextRunnable {
private final Notifier notifier;

private ProgramNotificationService programNotificationService;

private TrackerSideEffectDataBundle sideEffectDataBundle;

private IdentifiableObjectManager manager;

private final ImmutableMap<Class<? extends BaseIdentifiableObject>, Consumer<Long>>
serviceMapper =
new ImmutableMap.Builder<Class<? extends BaseIdentifiableObject>, Consumer<Long>>()
.put(
ProgramInstance.class,
id -> programNotificationService.sendEnrollmentNotifications(id))
.put(
ProgramStageInstance.class,
id -> programNotificationService.sendEventCompletionNotifications(id))
.build();
private final Map<SideEffectTrigger, Consumer<Long>> serviceMapper;

public TrackerNotificationThread(
ProgramNotificationService programNotificationService,
Notifier notifier,
IdentifiableObjectManager manager) {
this.programNotificationService = programNotificationService;
this.notifier = notifier;
this.manager = manager;
this.serviceMapper =
Map.of(
SideEffectTrigger.ENROLLMENT, programNotificationService::sendEnrollmentNotifications,
SideEffectTrigger.EVENT_COMPLETION,
programNotificationService::sendEventCompletionNotifications,
SideEffectTrigger.ENROLLMENT_COMPLETION,
programNotificationService::sendEnrollmentCompletionNotifications);
}

@Override
Expand All @@ -84,11 +77,14 @@ public void call() {
return;
}

if (serviceMapper.containsKey(sideEffectDataBundle.getKlass())) {
BaseIdentifiableObject object =
manager.get(sideEffectDataBundle.getKlass(), sideEffectDataBundle.getObject());

serviceMapper.get(sideEffectDataBundle.getKlass()).accept(object.getId());
for (SideEffectTrigger trigger : sideEffectDataBundle.getTriggers()) {
if (serviceMapper.containsKey(trigger)) {
BaseIdentifiableObject object =
manager.get(sideEffectDataBundle.getKlass(), sideEffectDataBundle.getObject());
if (object != null) {
serviceMapper.get(trigger).accept(object.getId());
}
}
}

notifier.notify(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -68,6 +69,9 @@ public class TrackerSideEffectDataBundle implements Message {

@JsonProperty private ProgramStageInstance programStageInstance;

@JsonProperty
private List<org.hisp.dhis.tracker.job.SideEffectTrigger> triggers = new ArrayList<>();

@JsonProperty @Builder.Default
private Map<String, List<TrackerRuleEngineSideEffect>> enrollmentRuleEffects = new HashMap<>();

Expand Down
Loading

0 comments on commit 877838e

Please sign in to comment.