ehrbase / fhir-bridge

FHIR Bridge acts as a broker between an HL7 FHIR client and an openEHR server.
31 stars 20 forks source link

Unexpected Errors in Alternative Flow Smoking Status #240

Closed af-pwo closed 3 years ago

af-pwo commented 3 years ago

Test Case/s To Reproduce Issue

Alternative Flows Observation Smoking Status

# path to test case
tests/robot/OBSERVATION/016_create_alternative_flows.robot

# robot command to execute related test case(s) in your terminal/console

robot -d results/ -L TRACE -i alternativeANDsmoking-status robot

# by test case name (wildcards possible)

042 Create Smoking Status status effective absent

## Actual Result

422

Robot error message:

{'issue': [{'code': 'processing',
                     'diagnostics': 'Cannot invoke "java.util.GregorianCalendar.toZonedDateTime()" because the return value of "org.hl7.fhir.r4.model.DateTimeType.getValueAsCalendar()" is null',
                     'severity': 'error'}]

## Expected Result

201

## Stack Trace

2021-02-24 15:56:14.181 ERROR 24500 --- [nio-8888-exec-3] o.a.c.p.e.DefaultErrorHandler            : Failed delivery for (MessageId: FCE0A2AD3FC1CF0-0000000000000006 on ExchangeId: FCE0A2AD3FC1CF0-0000000000000006). Exhausted after delivery attempt: 1 caught: ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException: Cannot invoke "java.util.GregorianCalendar.toZonedDateTime()" because the return value of "org.hl7.fhir.r4.model.DateTimeType.getValueAsCalendar()" is null. Processed by failure processor: FatalFallbackErrorHandler[Channel[DelegateSync[org.ehrbase.fhirbridge.camel.processor.DefaultExceptionHandler@24090832]]]

Message History (complete message history is disabled)
---------------------------------------------------------------------------------------------------------------------------------------
RouteId              ProcessorId          Processor                                                                        Elapsed (ms)
[route9            ] [route9            ] [from[fhir-create-observation://fhirConsumer?fhirContext=%23fhirContext]       ] [       274]

Stacktrace
---------------------------------------------------------------------------------------------------------------------------------------

ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException: Cannot invoke "java.util.GregorianCalendar.toZonedDateTime()" because the return value of "org.hl7.fhir.r4.model.DateTimeType.getValueAsCalendar()" is null
    at org.ehrbase.fhirbridge.ehr.converter.SmokingStatusCompositionConverter.toComposition(SmokingStatusCompositionConverter.java:71) ~[classes!/:na]
    at org.ehrbase.fhirbridge.ehr.converter.SmokingStatusCompositionConverter.toComposition(SmokingStatusCompositionConverter.java:19) ~[classes!/:na]
    at org.ehrbase.fhirbridge.camel.component.ehr.composition.CompositionProducer.mergeCompositionEntity(CompositionProducer.java:55) ~[classes!/:na]
    at org.ehrbase.fhirbridge.camel.component.ehr.composition.CompositionProducer.process(CompositionProducer.java:39) ~[classes!/:na]
    at org.apache.camel.support.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:66) ~[camel-support-3.7.0.jar!/:3.7.0]
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:169) ~[camel-core-processor-3.7.0.jar!/:3.7.0]
    at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$RedeliveryTask.doRun(RedeliveryErrorHandler.java:714) ~[camel-core-processor-3.7.0.jar!/:3.7.0]
    at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$RedeliveryTask.run(RedeliveryErrorHandler.java:623) ~[camel-core-processor-3.7.0.jar!/:3.7.0]
    at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:148) ~[camel-base-engine-3.7.0.jar!/:3.7.0]
    at org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:60) ~[camel-base-engine-3.7.0.jar!/:3.7.0]
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:147) ~[camel-core-processor-3.7.0.jar!/:3.7.0]
    at org.apache.camel.impl.engine.CamelInternalProcessor.process(CamelInternalProcessor.java:312) ~[camel-base-engine-3.7.0.jar!/:3.7.0]
    at org.apache.camel.impl.engine.DefaultAsyncProcessorAwaitManager.process(DefaultAsyncProcessorAwaitManager.java:83) ~[camel-base-engine-3.7.0.jar!/:3.7.0]
    at org.apache.camel.support.AsyncProcessorSupport.process(AsyncProcessorSupport.java:41) ~[camel-support-3.7.0.jar!/:3.7.0]
    at org.openehealth.ipf.platform.camel.ihe.fhir.core.intercept.consumer.ConsumerAuditInterceptor.process(ConsumerAuditInterceptor.java:60) ~[ipf-platform-camel-ihe-fhir-core-4.0.0.jar!/:na]
    at org.openehealth.ipf.platform.camel.ihe.fhir.core.FhirConsumer.runRoute(FhirConsumer.java:192) ~[ipf-platform-camel-ihe-fhir-core-4.0.0.jar!/:na]
    at org.openehealth.ipf.platform.camel.ihe.fhir.core.FhirConsumer.handleInRoute(FhirConsumer.java:165) ~[ipf-platform-camel-ihe-fhir-core-4.0.0.jar!/:na]
    at org.openehealth.ipf.platform.camel.ihe.fhir.core.FhirConsumer.handleAction(FhirConsumer.java:137) ~[ipf-platform-camel-ihe-fhir-core-4.0.0.jar!/:na]
    at org.openehealth.ipf.commons.ihe.fhir.AbstractPlainProvider.requestAction(AbstractPlainProvider.java:170) ~[ipf-commons-ihe-fhir-core-4.0.0.jar!/:na]
    at org.ehrbase.fhirbridge.fhir.observation.CreateObservationProvider.create(CreateObservationProvider.java:20) ~[classes!/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
    at ca.uhn.fhir.rest.server.method.BaseMethodBinding.invokeServerMethod(BaseMethodBinding.java:245) ~[hapi-fhir-server-5.2.0.jar!/:na]
    at ca.uhn.fhir.rest.server.method.BaseOutcomeReturningMethodBinding.invokeServer(BaseOutcomeReturningMethodBinding.java:154) ~[hapi-fhir-server-5.2.0.jar!/:na]
    at ca.uhn.fhir.rest.server.method.CreateMethodBinding.invokeServer(CreateMethodBinding.java:41) ~[hapi-fhir-server-5.2.0.jar!/:na]
    at ca.uhn.fhir.rest.server.RestfulServer.handleRequest(RestfulServer.java:1052) ~[hapi-fhir-server-5.2.0.jar!/:na]
    at ca.uhn.fhir.rest.server.RestfulServer.doPost(RestfulServer.java:377) ~[hapi-fhir-server-5.2.0.jar!/:na]
    at ca.uhn.fhir.rest.server.RestfulServer.service(RestfulServer.java:1749) ~[hapi-fhir-server-5.2.0.jar!/:na]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) ~[tomcat-embed-core-9.0.41.jar!/:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.41.jar!/:9.0.41]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) ~[spring-web-5.3.2.jar!/:5.3.2]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.2.jar!/:5.3.2]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.3.2.jar!/:5.3.2]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.2.jar!/:5.3.2]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.3.2.jar!/:5.3.2]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.2.jar!/:5.3.2]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:93) ~[spring-boot-actuator-2.4.1.jar!/:2.4.1]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.2.jar!/:5.3.2]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.3.2.jar!/:5.3.2]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.3.2.jar!/:5.3.2]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.41.jar!/:9.0.41]
    at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na]
subigre commented 3 years ago

The error is logic according to the following code in SmokingStatusCompositionConverter (line 45):

effectiveDateTime = observation.getEffectiveDateTimeType().getValueAsCalendar().toZonedDateTime();

According to the SmokingStatus profile, effectiveDateTime is not mandatory. As a result, a NullPointerException occurs when .toZonedDateTime() is invoked when the value is not provided in the JSON.

I just pushed the following fix:

GregorianCalendar effectiveDateTime = observation.getEffectiveDateTimeType().getValueAsCalendar();
if (effectiveDateTime != null) {
    result.setStartTimeValue(effectiveDateTime.toZonedDateTime());
}
ppazos commented 3 years ago

thanks @subigre that is a known issue of many mappings that were not taking into account the alternatives for effective[x]

ppazos commented 3 years ago

Done.