1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.openehealth.ipf.commons.ihe.fhir.support.audit.marshal;
18
19 import ca.uhn.fhir.context.FhirContext;
20 import ca.uhn.fhir.parser.IParser;
21 import org.hl7.fhir.dstu3.model.AuditEvent;
22 import org.hl7.fhir.dstu3.model.CodeableConcept;
23 import org.hl7.fhir.dstu3.model.Coding;
24 import org.hl7.fhir.dstu3.model.Identifier;
25 import org.hl7.fhir.exceptions.FHIRException;
26 import org.openehealth.ipf.commons.audit.AuditException;
27 import org.openehealth.ipf.commons.audit.codes.EventActionCode;
28 import org.openehealth.ipf.commons.audit.codes.EventOutcomeIndicator;
29 import org.openehealth.ipf.commons.audit.codes.NetworkAccessPointTypeCode;
30 import org.openehealth.ipf.commons.audit.marshal.SerializationStrategy;
31 import org.openehealth.ipf.commons.audit.model.*;
32 import org.openehealth.ipf.commons.audit.types.CodedValueType;
33
34 import java.io.IOException;
35 import java.io.Writer;
36 import java.sql.Date;
37
38
39
40
41 abstract class AbstractFhirAuditEvent implements SerializationStrategy {
42
43 private final FhirContext fhirContext;
44
45 public AbstractFhirAuditEvent() {
46 this(FhirContext.forDstu3());
47 }
48
49 public AbstractFhirAuditEvent(FhirContext fhirContext) {
50 this.fhirContext = fhirContext;
51 }
52
53 @Override
54 public void marshal(AuditMessage auditMessage, Writer writer, boolean pretty) throws IOException {
55 getParser(fhirContext)
56 .setPrettyPrint(pretty)
57 .encodeResourceToWriter(translate(auditMessage), writer);
58 }
59
60 protected abstract IParser getParser(FhirContext fhirContext);
61
62 protected AuditEvent translate(AuditMessage auditMessage) {
63 EventIdentificationType eit = auditMessage.getEventIdentification();
64 AuditEvent auditEvent = new AuditEvent()
65 .setType(codedValueTypeToCoding(eit.getEventID()))
66 .setAction(getAuditEventAction(eit.getEventActionCode()))
67 .setRecorded(Date.from(eit.getEventDateTime()))
68 .setOutcome(getAuditEventOutcome(eit.getEventOutcomeIndicator()))
69 .setOutcomeDesc(eit.getEventOutcomeDescription());
70 eit.getEventTypeCode().forEach(etc ->
71 auditEvent.addSubtype(codedValueTypeToCoding(etc)));
72 eit.getPurposesOfUse().forEach(pou ->
73 auditEvent.addPurposeOfEvent(codedValueTypeToCodeableConcept(pou)));
74
75 auditMessage.getActiveParticipants().forEach(ap ->
76 auditEvent.addAgent(activeParticipantToAgent(ap)));
77
78 auditEvent.setSource(auditSourceIdentificationToEventSource(auditMessage.getAuditSourceIdentification()));
79
80 auditMessage.getParticipantObjectIdentifications().forEach(poit ->
81 auditEvent.addEntity(participantObjectIdentificationToEntity(poit)));
82 return auditEvent;
83 }
84
85 protected AuditEvent.AuditEventEntityComponent participantObjectIdentificationToEntity(ParticipantObjectIdentificationType poit) {
86 AuditEvent.AuditEventEntityComponent entity = new AuditEvent.AuditEventEntityComponent()
87 .setIdentifier(new Identifier()
88 .setValue(poit.getParticipantObjectID()))
89
90 .setType(new Coding()
91 .setCode(String.valueOf(poit.getParticipantObjectTypeCode().getValue()))
92 .setSystem("http://hl7.org/fhir/audit-entity-type"))
93 .setRole(new Coding()
94 .setCode(String.valueOf(poit.getParticipantObjectTypeCodeRole().getValue()))
95 .setSystem("http://hl7.org/fhir/object-role"))
96 .setLifecycle(new Coding()
97 .setCode(String.valueOf(poit.getParticipantObjectDataLifeCycle().getValue()))
98 .setSystem("http://hl7.org/fhir/dicom-audit-lifecycle"))
99 .addSecurityLabel(new Coding()
100 .setCode(poit.getParticipantObjectSensitivity()))
101 .setName(poit.getParticipantObjectName())
102
103 .setQuery(poit.getParticipantObjectQuery());
104
105 poit.getParticipantObjectDetails().forEach(tvp ->
106 entity.addDetail(new AuditEvent.AuditEventEntityDetailComponent()
107 .setType(tvp.getType())
108 .setValue(tvp.getValue())));
109
110 return entity;
111
112 }
113
114 protected AuditEvent.AuditEventSourceComponent auditSourceIdentificationToEventSource(AuditSourceIdentificationType asit) {
115 AuditEvent.AuditEventSourceComponent source = new AuditEvent.AuditEventSourceComponent()
116 .setSite(asit.getAuditEnterpriseSiteID())
117 .setIdentifier(new Identifier().setValue(asit.getAuditSourceID()));
118 asit.getAuditSourceType().forEach(ast ->
119 source.addType(codedValueTypeToCoding(ast)));
120 return source;
121 }
122
123 protected AuditEvent.AuditEventAgentComponent activeParticipantToAgent(ActiveParticipantType ap) {
124 AuditEvent.AuditEventAgentComponent agent = new AuditEvent.AuditEventAgentComponent()
125 .setUserId(new Identifier().setValue(ap.getUserID()))
126 .setAltId(ap.getAlternativeUserID())
127 .setName(ap.getUserName())
128 .setRequestor(ap.isUserIsRequestor())
129 .setMedia(codedValueTypeToCoding(ap.getMediaType()))
130 .setNetwork(new AuditEvent.AuditEventAgentNetworkComponent()
131 .setAddress(ap.getNetworkAccessPointID())
132 .setType(auditEventNetworkType(ap.getNetworkAccessPointTypeCode())));
133 ap.getRoleIDCodes().forEach(roleID ->
134 agent.addPolicy(roleID.getCode()));
135 return agent;
136 }
137
138 protected AuditEvent.AuditEventAgentNetworkType auditEventNetworkType(NetworkAccessPointTypeCode naptc) {
139 try {
140 return AuditEvent.AuditEventAgentNetworkType.fromCode(String.valueOf(naptc.getValue()));
141 } catch (FHIRException e) {
142
143 throw new AuditException(e);
144 }
145 }
146
147
148 protected AuditEvent.AuditEventOutcome getAuditEventOutcome(EventOutcomeIndicator eventOutcomeIndicator) {
149 try {
150 return AuditEvent.AuditEventOutcome.fromCode(String.valueOf(eventOutcomeIndicator.getValue()));
151 } catch (FHIRException e) {
152
153 throw new AuditException(e);
154 }
155 }
156
157 protected AuditEvent.AuditEventAction getAuditEventAction(EventActionCode eventActionCode) {
158 try {
159 return AuditEvent.AuditEventAction.fromCode(eventActionCode.getValue());
160 } catch (FHIRException e) {
161
162 throw new AuditException(e);
163 }
164 }
165
166
167 protected Coding codedValueTypeToCoding(CodedValueType cvt) {
168 return cvt != null ?
169 new Coding(cvt.getCodeSystemName(),
170 cvt.getCode(),
171 cvt.getOriginalText()) :
172 null;
173 }
174
175 protected CodeableConcept codedValueTypeToCodeableConcept(CodedValueType cvt) {
176 return cvt != null ?
177 new CodeableConcept().addCoding(codedValueTypeToCoding(cvt)) :
178 null;
179 }
180 }