1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.openehealth.ipf.platform.camel.ihe.fhir.core;
18
19 import ca.uhn.fhir.context.FhirContext;
20 import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
21 import ca.uhn.fhir.validation.FhirValidator;
22 import ca.uhn.fhir.validation.ValidationResult;
23 import org.apache.camel.Exchange;
24 import org.apache.camel.Processor;
25 import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
26 import org.hl7.fhir.instance.model.api.IBaseResource;
27 import org.openehealth.ipf.commons.ihe.fhir.Constants;
28 import org.openehealth.ipf.commons.ihe.fhir.FhirInteractionId;
29 import org.openehealth.ipf.commons.ihe.fhir.FhirTransactionValidator;
30 import org.openehealth.ipf.platform.camel.core.adapter.ValidatorAdapter;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import static org.openehealth.ipf.commons.ihe.core.Constants.INTERACTION_ID_NAME;
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 public final class FhirCamelValidators {
74
75 private static final Logger LOG = LoggerFactory.getLogger(FhirCamelValidators.class);
76
77 private FhirCamelValidators() {
78 }
79
80 public static final String VALIDATION_MODE = "fhir.validation.mode";
81
82 public static final int MODEL = 4;
83 public static final int SCHEMATRON = 2;
84 public static final int SCHEMA = 1;
85 public static final int OFF = 0;
86
87 static boolean isValidateSchema(int actualMode) {
88 return (actualMode & SCHEMA) == SCHEMA;
89 }
90
91 static boolean isValidateSchematron(int actualMode) {
92 return (actualMode & SCHEMATRON) == SCHEMATRON;
93 }
94
95 static boolean isValidateModel(int actualMode) {
96 return (actualMode & MODEL) == MODEL;
97 }
98
99
100
101
102
103 public static Processor itiRequestValidator() {
104 return exchange -> {
105 FhirContext context = exchange.getIn().getHeader(Constants.FHIR_CONTEXT, FhirContext.class);
106 if (context != null) {
107 if (exchange.getIn().getBody() instanceof IBaseResource) {
108 if (ValidatorAdapter.validationEnabled(exchange)) {
109 Integer mode = exchange.getIn().getHeader(VALIDATION_MODE, Integer.class);
110 if (mode == null) mode = SCHEMA;
111 if (isValidateSchema(mode) || isValidateSchematron(mode)) {
112 validate(exchange, context, isValidateSchema(mode), isValidateSchematron(mode));
113 }
114 if (isValidateModel(mode)) {
115 FhirInteractionId fhirInteractionId = exchange.getIn().getHeader(INTERACTION_ID_NAME, FhirInteractionId.class);
116 if (fhirInteractionId != null) {
117 FhirTransactionValidator validator = fhirInteractionId.getFhirTransactionConfiguration().getFhirValidator();
118 validator.validateRequest(context, exchange.getIn().getBody(), exchange.getIn().getHeaders());
119 } else {
120 LOG.warn("Could not validate request because FHIR Transaction ID is unknown");
121 }
122 }
123 }
124 }
125 } else {
126 LOG.warn("Could not validate request because FHIR Context is unknown");
127 }
128 };
129 }
130
131
132
133
134
135 public static Processor itiResponseValidator() {
136 return exchange -> {
137 FhirContext context = exchange.getIn().getHeader(Constants.FHIR_CONTEXT, FhirContext.class);
138 if (context != null && exchange.getIn().getBody() instanceof IBaseResource) {
139 int mode = exchange.getIn().getHeader(VALIDATION_MODE, Integer.class);
140 if (isValidateSchema(mode) || isValidateSchematron(mode)) {
141 validate(exchange, context, isValidateSchema(mode), isValidateSchematron(mode));
142 }
143 if (isValidateModel(mode)) {
144 FhirInteractionId fhirInteractionId = exchange.getIn().getHeader(INTERACTION_ID_NAME, FhirInteractionId.class);
145 if (fhirInteractionId != null) {
146 FhirTransactionValidator validator = fhirInteractionId.getFhirTransactionConfiguration().getFhirValidator();
147 validator.validateResponse(context, exchange.getIn().getBody(), exchange.getIn().getHeaders());
148 } else {
149 LOG.warn("Could not validate request because FHIR Transaction ID is unknown");
150 }
151 }
152 } else {
153 LOG.warn("Could not validate request because FHIR Context is unknown");
154 }
155 };
156 }
157
158 private static void validate(Exchange exchange, FhirContext context, boolean checkSchema, boolean checkSchematron) {
159 ValidationResult result = getValidator(context, checkSchema, checkSchematron)
160 .validateWithResult(exchange.getIn().getBody(IBaseResource.class));
161 if (!result.isSuccessful()) {
162 IBaseOperationOutcome outcome = result.toOperationOutcome();
163 LOG.debug("FHIR Validation failed with outcome {}", outcome);
164 throw new UnprocessableEntityException("FHIR Validation Error", outcome);
165 } else {
166 LOG.debug("FHIR Validation succeeded");
167 }
168 }
169
170 private static FhirValidator getValidator(FhirContext context, boolean checkSchema, boolean checkSchematron) {
171 FhirValidator validator = context.newValidator();
172 validator.setValidateAgainstStandardSchema(checkSchema);
173
174 if (checkSchematron) validator.setValidateAgainstStandardSchematron(true);
175 return validator;
176 }
177 }