Skip to content

Commit

Permalink
#224 Study-Preview Mode: Cleanup after Preview
Browse files Browse the repository at this point in the history
- Reset Participant-Status
- Recreate Registration-Token
- Clear Study-Data

-> Tell the Gateway to collect data in Preview-Mode
  • Loading branch information
ja-fra committed May 14, 2024
1 parent 5a144eb commit 6c54dd7
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
*/
package io.redlink.more.studymanager.model.transformer;

import io.redlink.more.studymanager.api.v1.model.*;
import io.redlink.more.studymanager.api.v1.model.ContactDTO;
import io.redlink.more.studymanager.api.v1.model.StatusChangeDTO;
import io.redlink.more.studymanager.api.v1.model.StudyDTO;
import io.redlink.more.studymanager.api.v1.model.StudyStatusDTO;
import io.redlink.more.studymanager.model.Contact;
import io.redlink.more.studymanager.model.Study;
import io.redlink.more.studymanager.model.scheduler.Duration;

import java.util.Optional;

public class StudyTransformer {

private StudyTransformer() {}
Expand Down Expand Up @@ -60,6 +61,6 @@ public static StudyDTO toStudyDTO_V1(Study study) {
}

public static Study.Status fromStatusChangeDTO_V1(StatusChangeDTO statusChangeDTO) {
return Study.Status.valueOf(statusChangeDTO.getStatus().getValue().toUpperCase());
return Study.Status.fromValue(statusChangeDTO.getStatus().getValue());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/
package io.redlink.more.studymanager.repository;

import com.google.common.base.Supplier;
import io.redlink.more.studymanager.exception.BadRequestException;
import io.redlink.more.studymanager.model.Participant;
import java.util.List;
Expand All @@ -24,6 +25,7 @@
import org.springframework.transaction.annotation.Transactional;

import static io.redlink.more.studymanager.repository.RepositoryUtils.getValidNullableIntegerValue;
import static io.redlink.more.studymanager.repository.RepositoryUtils.intReader;

@Component
public class ParticipantRepository {
Expand Down Expand Up @@ -136,9 +138,23 @@ public void cleanupParticipants(Long studyId) {
namedTemplate.update("DELETE FROM push_notifications_token WHERE study_id = :study_id", params);
}

public void updateRegistrationToken(Long studyId, Integer participantId, String registrationToken) {
namedTemplate.update(UPDATE_REGISTRATION_TOKEN,
toParams(studyId, participantId).addValue("token", registrationToken));
@Transactional
public void resetParticipants(final Long studyId, final Supplier<String> tokenSource) {
// First clear credentials and tokens...
cleanupParticipants(studyId);
// ... then reset participant-status and start-date ...
final var pIDs = namedTemplate.query(
"UPDATE participants SET status = DEFAULT, start = NULL WHERE study_id = :study_id RETURNING *",
toParams(studyId),
intReader("participant_id")
);
// ... and finally create new token for the participants
namedTemplate.batchUpdate(
UPDATE_REGISTRATION_TOKEN,
pIDs.stream()
.map(pid -> toParams(studyId, pid).addValue("token", tokenSource.get()))
.toArray(MapSqlParameterSource[]::new)
);
}

public void clear() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.sql.SQLException;
import java.time.Instant;
import java.time.LocalDate;
import org.springframework.jdbc.core.RowMapper;

public final class RepositoryUtils {

Expand Down Expand Up @@ -69,4 +70,12 @@ public static String toParam(Participant.Status status) {
case LOCKED -> "locked";
};
}

public static RowMapper<Integer> intReader(String columnLabel) {
return (rs, rowNum) -> {
int anInt = rs.getInt(columnLabel);
if (rs.wasNull()) return null;
return anInt;
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import io.redlink.more.studymanager.model.data.SimpleDataPoint;
import io.redlink.more.studymanager.properties.ElasticProperties;
import io.redlink.more.studymanager.utils.MapperUtils;
import java.util.Objects;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
Expand Down Expand Up @@ -265,7 +266,12 @@ public List<ParticipationData> getParticipationData(Long studyId){
}
return participationDataList;
}catch (IOException | ElasticsearchException e) {
LOG.error("Elastic Query failed", e);
if (e instanceof ElasticsearchException ee) {
if (Objects.equals(ee.error().type(), "index_not_found_exception")) {
return List.of();
}
}
LOG.warn("Elastic Query failed", e);
return new ArrayList<>();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,11 @@ public Participant updateParticipant(Participant participant) {

@Transactional
public void alignParticipantsWithStudyState(Study study) {
if (EnumSet.of(Study.Status.CLOSED, Study.Status.DRAFT).contains(study.getStudyState())) {
if (EnumSet.of(Study.Status.CLOSED).contains(study.getStudyState())) {
participantRepository.cleanupParticipants(study.getStudyId());
}
if (EnumSet.of(Study.Status.PREVIEW).contains(study.getStudyState())) {
participantRepository.listParticipants(study.getStudyId())
.forEach(p -> participantRepository.updateRegistrationToken(
p.getStudyId(), p.getParticipantId(), RandomTokenGenerator.generate()
));
if (EnumSet.of(Study.Status.DRAFT).contains(study.getStudyState())) {
participantRepository.resetParticipants(study.getStudyId(), RandomTokenGenerator::generate);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ public class StudyService {
private static final Map<Study.Status, Set<Study.Status>> VALID_STUDY_TRANSITIONS = Map.of(
Study.Status.DRAFT, EnumSet.of(Study.Status.PREVIEW, Study.Status.ACTIVE),
Study.Status.PREVIEW, EnumSet.of(Study.Status.PAUSED_PREVIEW, Study.Status.DRAFT),
Study.Status.PAUSED_PREVIEW, EnumSet.of(Study.Status.DRAFT),
Study.Status.PAUSED_PREVIEW, EnumSet.of(Study.Status.PREVIEW, Study.Status.DRAFT),
Study.Status.ACTIVE, EnumSet.of(Study.Status.PAUSED, Study.Status.CLOSED),
Study.Status.PAUSED, EnumSet.of(Study.Status.ACTIVE)
Study.Status.PAUSED, EnumSet.of(Study.Status.ACTIVE, Study.Status.CLOSED)
);

private final StudyRepository studyRepository;
Expand Down Expand Up @@ -128,6 +128,7 @@ public void setStatus(Long studyId, Study.Status newState, User user) {
)
);
participantService.alignParticipantsWithStudyState(s);
elasticService.deleteIndex(s.getStudyId());
} catch (Exception e) {
log.warn("Could not set new state for study id {}; old state: {}; new state: {}", studyId, oldState.getValue(), s.getStudyState().getValue());
//ROLLBACK
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- Update gateway-view to consider preview
CREATE OR REPLACE VIEW auth_routing_info (api_id, api_secret, study_id, participant_id, study_group_id, study_is_active) AS
SELECT api_credentials.*, pt.study_group_id, s.status IN ('active', 'preview')
FROM api_credentials
INNER JOIN participants pt
ON (api_credentials.study_id = pt.study_id and api_credentials.participant_id = pt.participant_id)
INNER JOIN studies s
ON (api_credentials.study_id = s.study_id)
;

0 comments on commit 6c54dd7

Please sign in to comment.