Skip to content

Commit

Permalink
Extend Study participant object details in audits to include StudyDes…
Browse files Browse the repository at this point in the history
…cription, SeriesDescription and Modality #4555
  • Loading branch information
vrindanayak committed Sep 5, 2024
1 parent 41c13a3 commit 43001bc
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

/**
* @author Vrinda Nayak <[email protected]>
Expand Down Expand Up @@ -100,6 +100,9 @@ class AuditInfo {
static final int FHIR_WEB_APP_NAME = 40;
static final int ARCHIVE_USER_ID = 41;
static final int QR_LEVEL = 42;
static final int STUDY_DESC = 43;
static final int SERIES_DESC = 44;
static final int MODALITY = 45;

private final String[] fields;

Expand Down Expand Up @@ -147,7 +150,10 @@ class AuditInfo {
encode(i.status),
encode(i.fhirWebAppName),
encode(i.archiveUserID),
encode(i.qrLevel)
encode(i.qrLevel),
encode(i.studyDesc),
encode(i.seriesDesc),
encode(i.modality)
};
}

Expand All @@ -163,24 +169,14 @@ private static String decode(String val) {
if (val == null)
return null;

try {
return URLDecoder.decode(val, "UTF-8");
} catch (UnsupportedEncodingException e) {
LOG.info("URL decoding of value {} failed", val);
return val;
}
return URLDecoder.decode(val, StandardCharsets.UTF_8);
}

private static String encode(String val) {
if (val == null)
return null;

try {
return URLEncoder.encode(val, "UTF-8");
} catch (UnsupportedEncodingException e) {
LOG.info("URL encoding of value {} failed", val);
return val;
}
return URLEncoder.encode(val, StandardCharsets.UTF_8);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ class AuditInfoBuilder {
final String fhirWebAppName;
final String archiveUserID;
final String qrLevel;
final String studyDesc;
final String seriesDesc;
final String modality;

static class Builder {
private String callingHost;
Expand Down Expand Up @@ -147,6 +150,9 @@ static class Builder {
private String fhirWebAppName;
private String archiveUserID;
private String qrLevel;
private String studyDesc;
private String seriesDesc;
private String modality;

Builder callingHost(String val) {
callingHost = val;
Expand Down Expand Up @@ -202,6 +208,18 @@ Builder studyUIDAccNumDate(Attributes attrs, ArchiveDeviceExtension arcDev) {
}
return this;
}
Builder addAttrs(Attributes attrs, ArchiveDeviceExtension arcDev) {
studyUID = arcDev.auditUnknownStudyInstanceUID();
if (attrs != null) {
studyUID = attrs.getString(Tag.StudyInstanceUID);
accNum = attrs.getString(Tag.AccessionNumber);
studyDate = attrs.getString(Tag.StudyDate);
studyDesc = attrs.getString(Tag.StudyDescription);
seriesDesc = attrs.getString(Tag.SeriesDescription);
modality = attrs.getString(Tag.Modality);
}
return this;
}
Builder studyIUID(String val) {
studyUID = val;
return this;
Expand Down Expand Up @@ -405,6 +423,9 @@ private AuditInfoBuilder(Builder builder) {
fhirWebAppName = builder.fhirWebAppName;
archiveUserID = builder.archiveUserID;
qrLevel = builder.qrLevel;
studyDesc = builder.studyDesc;
modality = builder.modality;
seriesDesc = builder.seriesDesc;
}

private static String idWithIssuer(ArchiveDeviceExtension arcDev, String cx) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ private void spoolInstancesRejected(StoreContext ctx) {
if (schedulerDeletedExpiredStudies) {
studyRejected.add(new AuditInfoBuilder.Builder()
.callingUserID(device.getDeviceName())
.studyUIDAccNumDate(ctx.getAttributes(), arcDev)
.addAttrs(ctx.getAttributes(), arcDev)
.pIDAndName(ctx.getAttributes(), arcDev)
.outcome(ctx.getException() == null ? null : ctx.getException().getMessage())
.warning(ctx.getRejectionNote().getRejectionNoteCode().getCodeMeaning())
Expand All @@ -246,7 +246,7 @@ private void spoolInstancesRejected(StoreContext ctx) {
.callingUserID(callingUserID)
.callingHost(storeSession.getRemoteHostName())
.calledUserID(calledUserID)
.studyUIDAccNumDate(ctx.getAttributes(), arcDev)
.addAttrs(ctx.getAttributes(), arcDev)
.pIDAndName(ctx.getAttributes(), arcDev)
.outcome(ctx.getException() == null ? null : ctx.getException().getMessage())
.warning(ctx.getRejectionNote().getRejectionNoteCode().getCodeMeaning())
Expand All @@ -273,7 +273,7 @@ private void spoolPreviousInstancesDeleted(StoreContext ctx) {
.callingUserID(storeSession.getCallingAET())
.calledUserID(storeSession.getCalledAET())
.outcome(ctx.getException() == null ? null : ctx.getException().getMessage())
.studyUIDAccNumDate(prevStudy.getAttributes(), arcDev)
.addAttrs(prevStudy.getAttributes(), arcDev)
.pIDAndName(prevStudy.getPatient().getAttributes(), arcDev)
.toAuditInfo());
prevInstancesDeleted.add(new AuditInfoBuilder.Builder()
Expand All @@ -297,7 +297,7 @@ void spoolStudyDeleted(StudyDeleteContext ctx) {
if (httpServletRequestInfo == null) {
studyDeleted.add(new AuditInfoBuilder.Builder()
.callingUserID(device.getDeviceName())
.studyUIDAccNumDate(study.getAttributes(), arcDev)
.addAttrs(study.getAttributes(), arcDev)
.pIDAndName(study.getPatient().getAttributes(), arcDev)
.outcome(ctx.getException() == null ? null : ctx.getException().getMessage())
.toAuditInfo());
Expand All @@ -310,7 +310,7 @@ void spoolStudyDeleted(StudyDeleteContext ctx) {
.callingUserID(httpServletRequestInfo.requesterUserID)
.callingHost(httpServletRequestInfo.requesterHost)
.calledUserID(httpServletRequestInfo.requestURIWithQueryStr())
.studyUIDAccNumDate(study.getAttributes(), arcDev)
.addAttrs(study.getAttributes(), arcDev)
.pIDAndName(study.getPatient().getAttributes(), arcDev)
.outcome(ctx.getException() == null ? null : ctx.getException().getMessage())
.toAuditInfo());
Expand Down Expand Up @@ -348,7 +348,7 @@ void spoolExternalRejection(RejectionNoteSent rejectionNoteSent) {
.destNapID(rejectionNoteSent.getRemoteAE().getConnections().get(0).getHostname())
.outcome(rejectionNoteSent.getErrorComment())
.warning(codeItem.getString(Tag.CodeMeaning))
.studyUIDAccNumDate(attrs, arcDev)
.addAttrs(attrs, arcDev)
.pIDAndName(attrs, arcDev)
.toAuditInfo());
studyRejectionNoteSent.addAll(sopInstancesRejectionNote(rejectionNoteSent.getRejectionNote()));
Expand Down Expand Up @@ -476,7 +476,7 @@ void spoolExternalRetrieve(ExternalRetrieveContext ctx) {
.cMoveOriginator(ctx.getRemoteAET())
.calledHost(ctx.getRemoteHostName())
.destUserID(ctx.getDestinationAET())
.studyUIDAccNumDate(ctx.getKeys(), getArchiveDevice())
.addAttrs(ctx.getKeys(), getArchiveDevice())
.warning(warning)
.outcome(outcome)
.errorCode(Integer.parseInt(ctx.getResponse().getString(Tag.Status)))
Expand All @@ -493,7 +493,7 @@ void spoolExternalRetrieve(ExternalRetrieveContext ctx) {
.calledUserID(httpServletRequestInfo.requestURI)
.queryString(httpServletRequestInfo.queryString)
.destUserID(ctx.getDestinationAET())
.studyUIDAccNumDate(ctx.getKeys(), getArchiveDevice())
.addAttrs(ctx.getKeys(), getArchiveDevice())
.warning(warning)
.outcome(outcome)
.errorCode(Integer.parseInt(ctx.getResponse().getString(Tag.Status)))
Expand Down Expand Up @@ -577,7 +577,7 @@ void spoolStudySizeEvent(StudySizeEvent event) {
try {
AuditInfo auditInfo = new AuditInfoBuilder.Builder()
.callingUserID(device.getDeviceName())
.studyUIDAccNumDate(event.getStudy().getAttributes(), getArchiveDevice())
.addAttrs(event.getStudy().getAttributes(), getArchiveDevice())
.pIDAndName(event.getStudy().getPatient().getAttributes(), getArchiveDevice())
.toAuditInfo();
writeSpoolFile(AuditUtils.EventType.STUDY_READ.name(), false, auditInfo);
Expand Down Expand Up @@ -792,7 +792,7 @@ private void spoolInstancesStoredByCStore(AuditInfo instanceInfo, AuditUtils.Eve
.callingHost(storeSession.getRemoteHostName())
.callingUserID(storeSession.getCallingAET())
.calledUserID(storeSession.getCalledAET())
.studyUIDAccNumDate(attrs, arcDev)
.addAttrs(attrs, arcDev)
.pIDAndName(attrs, arcDev)
.toAuditInfo();
String fileName = eventType.name()
Expand All @@ -814,7 +814,7 @@ private void spoolInstancesStoredBySTOW(AuditInfo instanceInfo, AuditUtils.Event
.callingHost(storeSession.getRemoteHostName())
.callingUserID(httpServletRequestInfo.requesterUserID)
.calledUserID(httpServletRequestInfo.requestURIWithQueryStr())
.studyUIDAccNumDate(attrs, arcDev)
.addAttrs(attrs, arcDev)
.pIDAndName(attrs, arcDev)
.toAuditInfo();
String fileName = eventType.name()
Expand All @@ -836,7 +836,7 @@ private void spoolInstancesStoredByHL7(AuditInfo instanceInfo, AuditUtils.EventT
.callingHost(storeSession.getRemoteHostName())
.callingUserID(msh.getSendingApplicationWithFacility())
.calledUserID(msh.getReceivingApplicationWithFacility())
.studyUIDAccNumDate(attrs, arcDev)
.addAttrs(attrs, arcDev)
.pIDAndName(attrs, arcDev)
.toAuditInfo();
String fileName = eventType.name()
Expand All @@ -859,15 +859,15 @@ private void spoolInstancesStoredImpaxReport(AuditInfo instanceInfo, AuditUtils.
? new AuditInfoBuilder.Builder()
.callingUserID(device.getDeviceName())
.calledUserID(storeSession.getCalledAET())
.studyUIDAccNumDate(attrs, arcDev)
.addAttrs(attrs, arcDev)
.pIDAndName(attrs, arcDev)
.impaxEndpoint(storeSession.getImpaxReportEndpoint())
.toAuditInfo()
: new AuditInfoBuilder.Builder()
.callingHost(storeSession.getRemoteHostName())
.callingUserID(httpServletRequestInfo.requesterUserID)
.calledUserID(httpServletRequestInfo.requestURIWithQueryStr())
.studyUIDAccNumDate(attrs, arcDev)
.addAttrs(attrs, arcDev)
.pIDAndName(attrs, arcDev)
.impaxEndpoint(storeSession.getImpaxReportEndpoint())
.toAuditInfo();
Expand All @@ -894,7 +894,7 @@ private void spoolImpaxReportPatientMismatch(StoreContext ctx, AuditInfo instanc
AuditInfo auditInfoPatientMismatch = httpServletRequestInfo == null
? new AuditInfoBuilder.Builder()
.callingUserID(device.getDeviceName())
.studyUIDAccNumDate(attrs, arcDev)
.addAttrs(attrs, arcDev)
.pIDAndName(attrs, arcDev)
.impaxEndpoint(storeSession.getImpaxReportEndpoint())
.patMismatchCode(ctx.getImpaxReportPatientMismatch().toString())
Expand All @@ -903,7 +903,7 @@ private void spoolImpaxReportPatientMismatch(StoreContext ctx, AuditInfo instanc
.callingUserID(httpServletRequestInfo.requesterUserID)
.callingHost(storeSession.getRemoteHostName())
.calledUserID(httpServletRequestInfo.requestURIWithQueryStr())
.studyUIDAccNumDate(attrs, arcDev)
.addAttrs(attrs, arcDev)
.pIDAndName(attrs, arcDev)
.impaxEndpoint(storeSession.getImpaxReportEndpoint())
.patMismatchCode(ctx.getImpaxReportPatientMismatch().toString())
Expand Down Expand Up @@ -932,7 +932,7 @@ void spoolWADOURI(RetrieveContext ctx) {
.callingUserID(httpServletRequestInfo.requesterUserID)
.callingHost(httpServletRequestInfo.requesterHost)
.calledUserID(httpServletRequestInfo.requestURIWithQueryStr())
.studyUIDAccNumDate(attrs, getArchiveDevice())
.addAttrs(attrs, getArchiveDevice())
.pIDAndName(attrs, getArchiveDevice())
.outcome(ctx.getException() == null ? null : ctx.getException().getMessage())
.toAuditInfo();
Expand Down Expand Up @@ -1146,7 +1146,7 @@ private void spoolStudyUpdateRecord(StudyMgtContext ctx) {
.callingUserID(httpServletRequestInfo.requesterUserID)
.callingHost(ctx.getRemoteHostName())
.calledUserID(httpServletRequestInfo.requestURIWithQueryStr())
.studyUIDAccNumDate((study == null ? ctx.getAttributes() : study.getAttributes()), arcDev)
.addAttrs((study == null ? ctx.getAttributes() : study.getAttributes()), arcDev)
.pIDAndName((patient == null ? ctx.getAttributes() : patient.getAttributes()), arcDev)
.outcome(ctx.getException() == null ? null : ctx.getException().getMessage())
.toAuditInfo();
Expand All @@ -1165,7 +1165,7 @@ private void spoolStudyExpired(StudyMgtContext ctx) {
.callingUserID(httpServletRequestInfo.requesterUserID)
.callingHost(ctx.getRemoteHostName())
.calledUserID(httpServletRequestInfo.requestURIWithQueryStr())
.studyUIDAccNumDate(ctx.getStudy().getAttributes(), arcDev)
.addAttrs(ctx.getStudy().getAttributes(), arcDev)
.pIDAndName(ctx.getPatient().getAttributes(), arcDev)
.outcome(ctx.getException() == null ? null : ctx.getException().getMessage())
.expirationDate(ctx.getExpirationDate().toString())
Expand All @@ -1180,7 +1180,7 @@ private void spoolStudyExpiredByHL7(StudyMgtContext ctx) {
.callingUserID(msh.getSendingApplicationWithFacility())
.callingHost(ctx.getRemoteHostName())
.calledUserID(msh.getReceivingApplicationWithFacility())
.studyUIDAccNumDate(ctx.getStudy().getAttributes(), arcDev)
.addAttrs(ctx.getStudy().getAttributes(), arcDev)
.pIDAndName(ctx.getPatient().getAttributes(), arcDev)
.outcome(ctx.getException() == null ? null : ctx.getException().getMessage())
.expirationDate(ctx.getExpirationDate().toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,14 @@ private static ParticipantObjectIdentification study(AuditInfo auditInfo, SpoolF
study.setParticipantObjectIDTypeCode(AuditMessages.ParticipantObjectIDTypeCode.StudyInstanceUID);
study.setParticipantObjectTypeCode(AuditMessages.ParticipantObjectTypeCode.SystemObject);
study.setParticipantObjectTypeCodeRole(AuditMessages.ParticipantObjectTypeCodeRole.Report);
study.getParticipantObjectDetail()
.add(AuditMessages.createParticipantObjectDetail("StudyDate", auditInfo.getField(AuditInfo.STUDY_DATE)));
study.getParticipantObjectDetail().add(
AuditMessages.createParticipantObjectDetail("StudyDate", auditInfo.getField(AuditInfo.STUDY_DATE)));
study.getParticipantObjectDetail().add(
AuditMessages.createParticipantObjectDetail("StudyDescription", auditInfo.getField(AuditInfo.STUDY_DESC)));
study.getParticipantObjectDetail().add(
AuditMessages.createParticipantObjectDetail("SeriesDescription", auditInfo.getField(AuditInfo.SERIES_DESC)));
study.getParticipantObjectDetail().add(
AuditMessages.createParticipantObjectDetail("Modality", auditInfo.getField(AuditInfo.MODALITY)));
InstanceInfo instanceInfo = instanceInfo(auditInfo, reader);
boolean showSOPIUIDs = auditInfo.getField(AuditInfo.OUTCOME) != null || auditLogger.isIncludeInstanceUID();
study.setParticipantObjectDescription(studyParticipantObjDesc(instanceInfo, showSOPIUIDs));
Expand Down
Loading

0 comments on commit 43001bc

Please sign in to comment.