1 /*
2 * Copyright 2018 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package org.openehealth.ipf.commons.audit.event;
18
19 import org.openehealth.ipf.commons.audit.AuditException;
20 import org.openehealth.ipf.commons.audit.codes.*;
21 import org.openehealth.ipf.commons.audit.types.EventType;
22 import org.openehealth.ipf.commons.audit.types.PurposeOfUse;
23
24 import java.util.Collections;
25
26 /**
27 * Builds an Audit Event representing a DICOM Instances Transferred event as specified in
28 * http://dicom.nema.org/medical/dicom/current/output/html/part15.html#sect_A.5.3.7
29 * <p>
30 * This message describes the event of the completion of transferring DICOM SOP Instances
31 * between two Application Entities. This message may only include information about a
32 * single patient.
33 * </p>
34 * <p>
35 * This message may have been preceded by a {@link BeginTransferringDicomInstancesBuilder} message.
36 * The Begin Transferring Instances message conveys the intent to store SOP Instances,
37 * while the Instances Transferred message records the completion of the transfer.
38 * Any disagreement between the two messages might indicate a potential security breach.
39 * </p>
40 *
41 * @author Christian Ohr
42 * @since 3.5
43 */
44 public class DicomInstancesTransferredBuilder extends BaseAuditMessageBuilder<DicomInstancesTransferredBuilder> {
45
46 public DicomInstancesTransferredBuilder(EventOutcomeIndicator outcome,
47 String eventOutcomeDescription,
48 EventActionCode eventActionCode,
49 EventType eventType,
50 PurposeOfUse... purposesOfUse) {
51 super();
52 setEventIdentification(outcome,
53 eventOutcomeDescription,
54 eventActionCode,
55 EventIdCode.DICOMInstancesTransferred,
56 eventType,
57 purposesOfUse
58 );
59 }
60
61 /**
62 * @param userId The identity of the process sending the data
63 * @param altUserId Alternate UserID
64 * @param userName UserName
65 * @param networkId Network Access Point ID
66 * @param userIsRequestor Whether the destination participant represents the requestor (i.e. pull request)
67 * @return this
68 */
69 public DicomInstancesTransferredBuilder setSendingProcessParticipant(String userId,
70 String altUserId,
71 String userName,
72 String networkId,
73 boolean userIsRequestor) {
74 return addSourceActiveParticipant(userId, altUserId, userName, networkId, userIsRequestor);
75 }
76
77 /**
78 * @param userId The identity of the process receiving the data
79 * @param altUserId Alternate UserID
80 * @param userName UserName
81 * @param networkId Network Access Point ID
82 * @param userIsRequestor Whether the destination participant represents the requestor (i.e. pull request)
83 * @return this
84 */
85 public DicomInstancesTransferredBuilder setReceivingProcessParticipant(String userId,
86 String altUserId,
87 String userName,
88 String networkId,
89 boolean userIsRequestor) {
90 return addDestinationActiveParticipant(userId, altUserId, userName, networkId, userIsRequestor);
91 }
92
93 /**
94 * @param patientId patient ID
95 * @param patientName patient name
96 * @return this
97 */
98 public DicomInstancesTransferredBuilder setPatientParticipantObject(String patientId, String patientName) {
99 if (patientId != null) {
100 addPatientParticipantObject(patientId, patientName, Collections.emptyList(), null);
101 }
102 return self();
103 }
104
105 @Override
106 public void validate() {
107 super.validate();
108 if (getMessage().findActiveParticipants(ap -> ap.getRoleIDCodes().contains(ActiveParticipantRoleIdCode.Source)).size() != 1) {
109 throw new AuditException("Must have one ActiveParticipant with RoleIDCode Source");
110 }
111 if (getMessage().findActiveParticipants(ap -> ap.getRoleIDCodes().contains(ActiveParticipantRoleIdCode.Destination)).size() != 1) {
112 throw new AuditException("Must have one ActiveParticipant with RoleIDCode Destination");
113 }
114 if (getMessage().findParticipantObjectIdentifications(poi -> poi.getParticipantObjectIDTypeCode() == ParticipantObjectIdTypeCode.PatientNumber).size() != 1) {
115 throw new AuditException("Must one ParticipantObjectIdentification with ParticipantObjectIDTypeCode PatientNumber");
116 }
117 if (getMessage().findParticipantObjectIdentifications(poi -> poi.getParticipantObjectIDTypeCode() == ParticipantObjectIdTypeCode.StudyInstanceUID).isEmpty()) {
118 throw new AuditException("Must have one or more ParticipantObjectIdentification with ParticipantObjectIDTypeCode StudyInstanceUID");
119 }
120 }
121 }