View Javadoc
1   /*
2    * Copyright 2012 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  package org.openehealth.ipf.commons.ihe.core.atna.custom;
17  
18  import org.apache.commons.lang3.StringUtils;
19  import org.openhealthtools.ihe.atna.auditor.XDSAuditor;
20  import org.openhealthtools.ihe.atna.auditor.codes.dicom.DICOMEventIdCodes;
21  import org.openhealthtools.ihe.atna.auditor.codes.ihe.IHETransactionEventTypeCodes;
22  import org.openhealthtools.ihe.atna.auditor.codes.ihe.IHETransactionParticipantObjectIDTypeCodes;
23  import org.openhealthtools.ihe.atna.auditor.codes.rfc3881.RFC3881EventCodes;
24  import org.openhealthtools.ihe.atna.auditor.codes.rfc3881.RFC3881ParticipantObjectCodes;
25  import org.openhealthtools.ihe.atna.auditor.context.AuditorModuleContext;
26  import org.openhealthtools.ihe.atna.auditor.events.ihe.GenericIHEAuditEventMessage;
27  import org.openhealthtools.ihe.atna.auditor.models.rfc3881.CodedValueType;
28  import org.openhealthtools.ihe.atna.auditor.models.rfc3881.TypeValuePairType;
29  import org.openhealthtools.ihe.atna.auditor.utils.EventUtils;
30  
31  import java.nio.charset.StandardCharsets;
32  import java.util.ArrayList;
33  import java.util.List;
34  
35  import static org.openehealth.ipf.commons.ihe.core.atna.custom.CustomAuditorUtils.configureEvent;
36  
37  /**
38   * Implementation of ATNA Auditors for the following XDS-based transactions:
39   * <ul>
40   *     <li>ITI-51 -- XDS.b Multi-Patient Stored Query</li>
41   *     <li>ITI-57 -- XDS.b Update Document Set</li>
42   *     <li>ITI-61 -- XDS.b Register On-Demand Document Entry</li>
43   *     <li>ITI-62 -- RMD Remove Metadata</li>
44   *     <li>ITI-63 -- XCF Cross-Community Fetch</li>
45   *     <li>ITI-86 -- RMD Remove Documents</li>
46   *     <li>CH-XCMU -- XCMU Cross-Gateway Update Document Set</li>
47   *     <li>RAD-69 -- XDS-I.b Retrieve Imaging Document Set</li>
48   *     <li>RAD-75 -- XCA-I Cross-Gateway Retrieve Imaging Document Set</li>
49   * </ul>
50   *
51   * @author Dmytro Rud
52   * @deprecated
53   */
54  public class CustomXdsAuditor extends XDSAuditor {
55  
56      public static CustomXdsAuditor getAuditor() {
57          AuditorModuleContext ctx = AuditorModuleContext.getContext();
58          return (CustomXdsAuditor) ctx.getAuditor(CustomXdsAuditor.class);
59      }
60  
61  
62      /**
63       * Audits an ITI-51 Multi-Patient Query event.
64       *
65       * @param serverSide         <code>true</code> for the Document Registry actor,
66       *                           <code>false</code> for the Document Consumer actor.
67       * @param eventOutcome       event outcome code.
68       * @param userId             user ID (contents of the WS-Addressing &lt;ReplyTo&gt; header).
69       * @param userName           user name on the Document Consumer side (for XUA).
70       * @param serviceEndpointUri network endpoint URI of the Document Registry actor.
71       * @param clientIpAddress    IP address of the Document Consumer actor.
72       * @param queryUuid          UUID of the XDS query.
73       * @param requestPayload     the whole XDS request as an XML String.
74       * @param homeCommunityId    home community ID (optional).
75       * @param patientId          patient ID as an HL7 v2 CX string.
76       * @param purposesOfUse      &lt;PurposeOfUse&gt; attributes from XUA SAML assertion.
77       * @param userRoles          user role codes from XUA SAML assertion.
78       */
79      public void auditIti51(
80              boolean serverSide,
81              RFC3881EventCodes.RFC3881EventOutcomeCodes eventOutcome,
82              String userId,
83              String userName,
84              String serviceEndpointUri,
85              String clientIpAddress,
86              String queryUuid,
87              String requestPayload,
88              String homeCommunityId,
89              String patientId,
90              List<CodedValueType> purposesOfUse,
91              List<CodedValueType> userRoles)
92      {
93          if (!isAuditorEnabled()) {
94              return;
95          }
96  
97          doAuditQueryEvent(
98                  serverSide,
99                  new CustomIHETransactionEventTypeCodes.MultiPatientQuery(),
100                 eventOutcome,
101                 userId,
102                 userName,
103                 serviceEndpointUri,
104                 clientIpAddress,
105                 queryUuid,
106                 requestPayload,
107                 homeCommunityId,
108                 patientId,
109                 purposesOfUse,
110                 userRoles);
111     }
112 
113     /**
114      * Audits an intra-community (ITI-57) or cross-community (ITI_X1) Update Document Set events.
115      *
116      * @param serverSide            <code>true</code> for the Document Administrator / XCMU Initiating Gateway actor,
117      *                              <code>false</code> for the Document Registry / XCMU Responding Gateway actor.
118      * @param eventTypeCode         transaction code (ITI-57 or CH-XCMU)
119      * @param eventOutcome          event outcome indicator
120      * @param sourceUserId          ID of the user which triggered the transaction
121      * @param registryEndpointUri   Web service endpoint URI for the document registry
122      * @param submissionSetUniqueId UniqueID of the Submission Set registered
123      * @param homeCommunityId       home community ID (optional for ITI-57, required for CH-XCMU).
124      * @param patientId             Patient Id that this submission pertains to
125      * @param purposesOfUse         &lt;PurposeOfUse&gt; attributes from XUA SAML assertion.
126      * @param userRoles             user role codes from XUA SAML assertion.
127      */
128     private void auditUpdateDocumentSet(
129             boolean serverSide,
130             IHETransactionEventTypeCodes eventTypeCode,
131             RFC3881EventCodes.RFC3881EventOutcomeCodes eventOutcome,
132             String sourceUserId,
133             String sourceIpAddress,
134             String humanUserName,
135             String registryEndpointUri,
136             String submissionSetUniqueId,
137             String homeCommunityId,
138             String patientId,
139             List<CodedValueType> purposesOfUse,
140             List<CodedValueType> userRoles)
141     {
142         if (! isAuditorEnabled()) {
143             return;
144         }
145 
146         GenericIHEAuditEventMessage event = new GenericIHEAuditEventMessage(
147                 ! serverSide,
148                 eventOutcome,
149                 RFC3881EventCodes.RFC3881EventActionCodes.UPDATE,
150                 serverSide ? new DICOMEventIdCodes.Import() : new DICOMEventIdCodes.Export(),
151                 eventTypeCode,
152                 purposesOfUse);
153 
154         event.setAuditSourceId(getAuditSourceId(), getAuditEnterpriseSiteId());
155 
156         event.addSourceActiveParticipant(
157                 sourceUserId,
158                 serverSide ? null : getSystemAltUserId(),
159                 null,
160                 serverSide ? sourceIpAddress : getSystemNetworkId(),
161                 true);
162 
163         if (!EventUtils.isEmptyOrNull(humanUserName)) {
164             event.addHumanRequestorActiveParticipant(humanUserName, null, humanUserName, userRoles);
165         }
166 
167         event.addDestinationActiveParticipant(
168                 registryEndpointUri,
169                 serverSide ? getSystemAltUserId() : null,
170                 null,
171                 EventUtils.getAddressForUrl(registryEndpointUri, false),
172                 false);
173 
174         if (!EventUtils.isEmptyOrNull(patientId)) {
175             event.addPatientParticipantObject(patientId);
176         }
177 
178         List<TypeValuePairType> pairs = new ArrayList<>();
179         if (StringUtils.isNotEmpty(homeCommunityId)) {
180             TypeValuePairType pair = new TypeValuePairType();
181             pair.setType("ihe:homeCommunityID");
182             pair.setValue(homeCommunityId.getBytes(StandardCharsets.UTF_8));
183             pairs.add(pair);
184         }
185 
186         event.addParticipantObjectIdentification(
187                 new IHETransactionParticipantObjectIDTypeCodes.SubmissionSet(),
188                 null,
189                 null,
190                 pairs,
191                 submissionSetUniqueId,
192                 RFC3881ParticipantObjectCodes.RFC3881ParticipantObjectTypeCodes.SYSTEM,
193                 RFC3881ParticipantObjectCodes.RFC3881ParticipantObjectTypeRoleCodes.JOB,
194                 null,
195                 null);
196 
197         audit(event);
198     }
199 
200     public void auditIti57(
201             boolean serverSide,
202             RFC3881EventCodes.RFC3881EventOutcomeCodes eventOutcome,
203             String sourceUserId,
204             String sourceIpAddress,
205             String humanUserName,
206             String registryEndpointUri,
207             String submissionSetUniqueId,
208             String homeCommunityId,
209             String patientId,
210             List<CodedValueType> purposesOfUse,
211             List<CodedValueType> userRoles)
212     {
213         auditUpdateDocumentSet(
214                 serverSide,
215                 new CustomIHETransactionEventTypeCodes.UpdateDocumentSet(),
216                 eventOutcome,
217                 sourceUserId,
218                 sourceIpAddress,
219                 humanUserName,
220                 registryEndpointUri,
221                 submissionSetUniqueId,
222                 homeCommunityId,
223                 patientId,
224                 purposesOfUse,
225                 userRoles);
226     }
227 
228     /**
229      * Audits an ITI-61 Register On-Demand Document Entry event.
230      *
231      * @param serverSide            <code>true</code> for the Document Registry actor,
232      *                              <code>false</code> for the On-Demand Document Source actor.
233      * @param eventOutcome          event outcome code.
234      * @param userId                user ID (contents of the WS-Addressing &lt;ReplyTo&gt; header).
235      * @param userName              user name on the Document Consumer side (for XUA).
236      * @param serviceEndpointUri    network endpoint URI of the Document Registry actor.
237      * @param clientIpAddress       IP address of the Document On-Demand Document Source actor.
238      * @param submissionSetUniqueId unique ID of the XDS submission set.
239      * @param patientId             patient ID as an HL7 v2 CX string.
240      * @param purposesOfUse         &lt;PurposeOfUse&gt; attributes from XUA SAML assertion.
241      * @param userRoles             user role codes from XUA SAML assertion.
242      */
243     public void auditIti61(
244             boolean serverSide,
245             RFC3881EventCodes.RFC3881EventOutcomeCodes eventOutcome,
246             String userId,
247             String userName,
248             String serviceEndpointUri,
249             String clientIpAddress,
250             String submissionSetUniqueId,
251             String patientId,
252             List<CodedValueType> purposesOfUse,
253             List<CodedValueType> userRoles)
254     {
255         if (! isAuditorEnabled()) {
256             return;
257         }
258 
259         GenericIHEAuditEventMessage event = new GenericIHEAuditEventMessage(
260                 ! serverSide,
261                 eventOutcome,
262                 serverSide ? RFC3881EventCodes.RFC3881EventActionCodes.CREATE : RFC3881EventCodes.RFC3881EventActionCodes.READ,
263                 serverSide ? new DICOMEventIdCodes.Import() : new DICOMEventIdCodes.Export(),
264                 new CustomIHETransactionEventTypeCodes.RegisterOnDemandDocumentEntry(),
265                 purposesOfUse);
266 
267         configureEvent(this, serverSide, event, userId, userName, serviceEndpointUri, serviceEndpointUri, clientIpAddress, userRoles);
268         if (!EventUtils.isEmptyOrNull(patientId)) {
269             event.addPatientParticipantObject(patientId);
270         }
271         event.addSubmissionSetParticipantObject(submissionSetUniqueId);
272         audit(event);
273     }
274 
275     /**
276      * Sends an audit message for the XDS Delete Document Set event.
277      *
278      * @param serverSide <code>true</code> for XDS Registry, <code>false</code> for Document Administrator
279      * @param eventOutcome The event outcome indicator
280      * @param userId ID of the user at the actor performing audit trail
281      * @param userName name of the user at the actor performing audit trail
282      * @param serviceEndpointUri Web Service endpoint URI of the Document Registry
283      * @param clientIpAddress IP address of the Document Administrator
284      * @param patientId ID of the patient related to the deleted registry objects
285      * @param objectUuids UUIDs of the registry objects being deleted
286      * @param purposesOfUse &lt;PurposeOfUse&gt; attributes from XUA SAML assertion.
287      * @param userRoles user role codes from XUA SAML assertion.
288      */
289     public void auditIti62(
290             boolean serverSide,
291             RFC3881EventCodes.RFC3881EventOutcomeCodes eventOutcome,
292             String userId,
293             String userName,
294             String serviceEndpointUri,
295             String clientIpAddress,
296             String patientId,
297             String[] objectUuids,
298             List<CodedValueType> purposesOfUse,
299             List<CodedValueType> userRoles)
300     {
301         if (! isAuditorEnabled()) {
302             return;
303         }
304 
305         GenericIHEAuditEventMessage event = new GenericIHEAuditEventMessage(
306                 ! serverSide,
307                 eventOutcome,
308                 RFC3881EventCodes.RFC3881EventActionCodes.DELETE,
309                 new DICOMEventIdCodes.PatientRecord(),
310                 new CustomIHETransactionEventTypeCodes.RemoveMetadata(),
311                 purposesOfUse);
312 
313         event.addSourceActiveParticipant(
314                 serverSide ? null : userId,
315                 serverSide ? null : getSystemAltUserId(),
316                 null,
317                 serverSide ? clientIpAddress : getSystemNetworkId(),
318                 true);
319 
320         if (!EventUtils.isEmptyOrNull(userName)) {
321             event.addHumanRequestorActiveParticipant(userName, null, userName, userRoles);
322         }
323 
324         event.addDestinationActiveParticipant(
325                 serviceEndpointUri,
326                 serverSide ? getSystemAltUserId() : null,
327                 null,
328                 serverSide ? getSystemNetworkId() : EventUtils.getAddressForUrl(serviceEndpointUri, false),
329                 false);
330 
331         event.setAuditSourceId(getAuditSourceId(), getAuditEnterpriseSiteId());
332 
333         if (!EventUtils.isEmptyOrNull(patientId)) {
334             event.addPatientParticipantObject(patientId);
335         }
336 
337         if (objectUuids != null) {
338             for (String uuid : objectUuids) {
339                 event.addRemovedRegistryObject(new IHETransactionParticipantObjectIDTypeCodes.RegistryObjectReference(), uuid);
340             }
341         }
342 
343         audit(event);
344     }
345 
346     /**
347      * Audits an ITI-63 XCF Cross-Community Fetch event.
348      *
349      * @param serverSide         <code>true</code> for the Responding Gateway actor,
350      *                           <code>false</code> for the Initiating Gateway actor.
351      * @param eventOutcome       event outcome code.
352      * @param userId             user ID (contents of the WS-Addressing &lt;ReplyTo&gt; header).
353      * @param userName           user name on the Document Consumer side (for XUA).
354      * @param serviceEndpointUri network endpoint URI of the XCF Responding Gateway actor.
355      * @param clientIpAddress    IP address of the XCF Initiating Gateway actor.
356      * @param queryUuid          UUID of the XCF query.
357      * @param requestPayload     the whole XCF request as an XML String.
358      * @param homeCommunityId    home community ID.
359      * @param patientId          patient ID as an HL7 v2 CX string.
360      * @param purposesOfUse      &lt;PurposeOfUse&gt; attributes from XUA SAML assertion.
361      * @param userRoles          user role codes from XUA SAML assertion.
362      */
363     public void auditIti63(
364             boolean serverSide,
365             RFC3881EventCodes.RFC3881EventOutcomeCodes eventOutcome,
366             String userId,
367             String userName,
368             String serviceEndpointUri,
369             String clientIpAddress,
370             String queryUuid,
371             String requestPayload,
372             String homeCommunityId,
373             String patientId,
374             List<CodedValueType> purposesOfUse,
375             List<CodedValueType> userRoles)
376     {
377         if (! isAuditorEnabled()) {
378             return;
379         }
380 
381         doAuditQueryEvent(
382                 serverSide,
383                 new CustomIHETransactionEventTypeCodes.CrossCommunityFetch(),
384                 eventOutcome,
385                 userId,
386                 userName,
387                 serviceEndpointUri,
388                 clientIpAddress,
389                 queryUuid,
390                 requestPayload,
391                 homeCommunityId,
392                 patientId,
393                 purposesOfUse,
394                 userRoles);
395     }
396 
397     public void auditIti86(
398             boolean serverSide,
399             RFC3881EventCodes.RFC3881EventOutcomeCodes eventOutcome,
400             String userId,
401             String userName,
402             String clientIpAddress,
403             String serviceEndpointUri,
404             String patientId,
405             String[] documentUniqueIds,
406             String[] repositoryUniqueIds,
407             String[] homeCommunityIds,
408             List<CodedValueType> purposesOfUse,
409             List<CodedValueType> userRoles)
410     {
411         if (! isAuditorEnabled()) {
412             return;
413         }
414 
415         RemoveDocumentsEvent event = new RemoveDocumentsEvent(!serverSide, eventOutcome, purposesOfUse);
416 
417         event.addSourceActiveParticipant(
418                 userId,
419                 serverSide ? null : getSystemAltUserId(),
420                 null,
421                 serverSide ? clientIpAddress : getSystemNetworkId(),
422                 true);
423 
424         if (!EventUtils.isEmptyOrNull(userName)) {
425             event.addHumanRequestorActiveParticipant(userName, null, userName, userRoles);
426         }
427 
428         event.addDestinationActiveParticipant(
429                 serviceEndpointUri,
430                 serverSide ? getSystemAltUserId() : null,
431                 null,
432                 serverSide ? getSystemNetworkId() : EventUtils.getAddressForUrl(serviceEndpointUri, false),
433                 false);
434 
435         event.setAuditSourceId(getAuditSourceId(), getAuditEnterpriseSiteId());
436 
437         if (!EventUtils.isEmptyOrNull(patientId)) {
438             event.addPatientParticipantObject(patientId);
439         }
440 
441         for (int i = 0; i < documentUniqueIds.length; ++i) {
442             event.addRemovedDocumentParticipantObject(documentUniqueIds[i], repositoryUniqueIds[i]);
443         }
444 
445         audit(event);
446     }
447 
448     public void auditChXcmu(
449             boolean serverSide,
450             RFC3881EventCodes.RFC3881EventOutcomeCodes eventOutcome,
451             String sourceUserId,
452             String sourceIpAddress,
453             String humanUserName,
454             String registryEndpointUri,
455             String submissionSetUniqueId,
456             String homeCommunityId,
457             String patientId,
458             List<CodedValueType> purposesOfUse,
459             List<CodedValueType> userRoles)
460     {
461         auditUpdateDocumentSet(
462                 serverSide,
463                 new CustomIHETransactionEventTypeCodes.CrossGatewayUpdateDocumentSet(),
464                 eventOutcome,
465                 sourceUserId,
466                 sourceIpAddress,
467                 humanUserName,
468                 registryEndpointUri,
469                 submissionSetUniqueId,
470                 homeCommunityId,
471                 patientId,
472                 purposesOfUse,
473                 userRoles);
474     }
475 
476     /**
477      * Audits an RAD-69 Retrieve Imaging Document Set event.
478      *
479      * @param serverSide               <code>true</code> for the Imaging Document source actor,
480      *                                 <code>false</code> for the Imaging Document Consumer actor.
481      * @param eventOutcome             event outcome code.
482      * @param userId                   user ID (contents of the WS-Addressing &lt;ReplyTo&gt; header).
483      * @param userName                 user name on the Document Consumer side (for XUA).
484      * @param serviceEndpointUri       network endpoint URI of the Imaging Document Source actor.
485      * @param clientIpAddress          IP address of the Imaging Document Consumer actor.
486      * @param studyInstanceUniqueIds,  list of study instance unique IDs.
487      * @param seriesInstanceUniqueIds, list of series instance unique IDs.
488      * @param documentUniqueIds,       list of document unique IDs.
489      * @param repositoryUniqueIds,     list of unique IDs of document repositories.
490      * @param homeCommunityIds,        list of home community IDs.
491      * @param patientId                patient ID as an HL7 v2 CX string (if known).
492      * @param purposesOfUse            &lt;PurposeOfUse&gt; attributes from XUA SAML assertion.
493      * @param userRoles                user role codes from XUA SAML assertion.
494      */
495     public void auditRad69(
496             boolean serverSide,
497             RFC3881EventCodes.RFC3881EventOutcomeCodes eventOutcome,
498             String userId,
499             String userName,
500             String serviceEndpointUri,
501             String clientIpAddress,
502             String[] studyInstanceUniqueIds,
503             String[] seriesInstanceUniqueIds,
504             String[] documentUniqueIds,
505             String[] repositoryUniqueIds,
506             String[] homeCommunityIds,
507             String patientId,
508             List<CodedValueType> purposesOfUse,
509             List<CodedValueType> userRoles)
510     {
511         if (! isAuditorEnabled()) {
512             return;
513         }
514 
515         doAuditImagingEvent(
516                 serverSide,
517                 new CustomIHETransactionEventTypeCodes.RetrieveImagingDocumentSet(),
518                 eventOutcome,
519                 userId,
520                 userName,
521                 serviceEndpointUri,
522                 clientIpAddress,
523                 studyInstanceUniqueIds,
524                 seriesInstanceUniqueIds,
525                 documentUniqueIds,
526                 repositoryUniqueIds,
527                 homeCommunityIds,
528                 patientId,
529                 purposesOfUse,
530                 userRoles);
531     }
532 
533 
534     /**
535      * Audits an RAD-75 Cross-Gateway Retrieve Imaging Document Set event.
536      *
537      * @param serverSide              <code>true</code> for the Document Registry actor,
538      *                                <code>false</code> for the Document Consumer actor.
539      * @param eventOutcome            event outcome code.
540      * @param userId                  user ID (contents of the WS-Addressing &lt;ReplyTo&gt; header).
541      * @param userName                user name on the Document Consumer side (for XUA).
542      * @param serviceEndpointUri      network endpoint URI of the Responding Gateway actor.
543      * @param clientIpAddress         IP address of the Initiating Gateway actor.
544      * @param studyInstanceUniqueIds  list of study instance unique IDs.
545      * @param seriesInstanceUniqueIds list of series instance unique IDs.
546      * @param documentUniqueIds       list of document unique IDs.
547      * @param repositoryUniqueIds     list of unique IDs of document repositories.
548      * @param homeCommunityIds        list of home community IDs.
549      * @param patientId               patient ID as an HL7 v2 CX string (if known).
550      * @param purposesOfUse           &lt;PurposeOfUse&gt; attributes from XUA SAML assertion.
551      * @param userRoles               user role codes from XUA SAML assertion.
552      */
553     public void auditRad75(
554             boolean serverSide,
555             RFC3881EventCodes.RFC3881EventOutcomeCodes eventOutcome,
556             String userId,
557             String userName,
558             String serviceEndpointUri,
559             String clientIpAddress,
560             String[] studyInstanceUniqueIds,
561             String[] seriesInstanceUniqueIds,
562             String[] documentUniqueIds,
563             String[] repositoryUniqueIds,
564             String[] homeCommunityIds,
565             String patientId,
566             List<CodedValueType> purposesOfUse,
567             List<CodedValueType> userRoles)
568     {
569         if (! isAuditorEnabled()) {
570             return;
571         }
572 
573         doAuditImagingEvent(
574                 serverSide,
575                 new CustomIHETransactionEventTypeCodes.CrossGatewayRetrieveImagingDocumentSet(),
576                 eventOutcome,
577                 userId,
578                 userName,
579                 serviceEndpointUri,
580                 clientIpAddress,
581                 studyInstanceUniqueIds,
582                 seriesInstanceUniqueIds,
583                 documentUniqueIds,
584                 repositoryUniqueIds,
585                 homeCommunityIds,
586                 patientId,
587                 purposesOfUse,
588                 userRoles);
589     }
590 
591 
592     private void doAuditImagingEvent(
593             boolean serverSide,
594             IHETransactionEventTypeCodes transactionEventTypeCodes,
595             RFC3881EventCodes.RFC3881EventOutcomeCodes eventOutcome,
596             String userId,
597             String userName,
598             String serviceEndpointUri,
599             String clientIpAddress,
600             String[] studyInstanceUniqueIds,
601             String[] seriesInstanceUniqueIds,
602             String[] documentUniqueIds,
603             String[] repositoryUniqueIds,
604             String[] homeCommunityIds,
605             String patientId,
606             List<CodedValueType> purposesOfUse,
607             List<CodedValueType> userRoles)
608     {
609         ImagingRetrieveEvent event = new ImagingRetrieveEvent(
610                 ! serverSide,
611                 eventOutcome,
612                 transactionEventTypeCodes,
613                 purposesOfUse);
614 
615         event.addSourceActiveParticipant(
616                 serviceEndpointUri,
617                 serverSide ? getSystemAltUserId() : null,
618                 null,
619                 serverSide ? getSystemNetworkId() : EventUtils.getAddressForUrl(serviceEndpointUri, false),
620                 false);
621 
622         event.addDestinationActiveParticipant(
623                 userId,
624                 serverSide ? null : getSystemAltUserId(),
625                 null,
626                 serverSide ? clientIpAddress : getSystemNetworkId(),
627                 true);
628 
629         if (! EventUtils.isEmptyOrNull(userName)) {
630             event.addHumanRequestorActiveParticipant(userName, null, userName, userRoles);
631         }
632 
633         event.setAuditSourceId(getAuditSourceId(), getAuditEnterpriseSiteId());
634 
635         if (! EventUtils.isEmptyOrNull(patientId)) {
636             event.addPatientParticipantObject(patientId);
637         }
638 
639         if (! EventUtils.isEmptyOrNull(documentUniqueIds)) {
640             for (int i = 0; i < documentUniqueIds.length; i++) {
641                 event.addDocumentParticipantObject(
642                         studyInstanceUniqueIds[i],
643                         seriesInstanceUniqueIds[i],
644                         documentUniqueIds[i],
645                         repositoryUniqueIds[i],
646                         homeCommunityIds[i]);
647             }
648         }
649 
650         audit(event);
651     }
652 
653 
654     private void doAuditQueryEvent(
655             boolean serverSide,
656             IHETransactionEventTypeCodes transactionEventTypeCode,
657             RFC3881EventCodes.RFC3881EventOutcomeCodes eventOutcome,
658             String userId,
659             String userName,
660             String serverEndpointUri,
661             String clientIpAddress,
662             String queryUuid,
663             String requestPayload,
664             String homeCommunityId,
665             String patientId,
666             List<CodedValueType> purposesOfUse,
667             List<CodedValueType> userRoles)
668     {
669         auditQueryEvent(
670                 ! serverSide,
671                 transactionEventTypeCode,
672                 eventOutcome,
673                 getAuditSourceId(),
674                 getAuditEnterpriseSiteId(),
675                 userId,
676                 serverSide ? null : getSystemAltUserId(),
677                 null,
678                 serverSide ? clientIpAddress : getSystemNetworkId(),
679                 userName,
680                 userName,
681                 false,
682                 serverEndpointUri,
683                 serverSide ? getSystemAltUserId() : null,
684                 queryUuid,
685                 requestPayload,
686                 homeCommunityId,
687                 patientId,
688                 purposesOfUse,
689                 userRoles);
690     }
691 
692 }