首页 > 解决方案 > Hapi FHIR RestfulServer 未解析 R4 同意资源的 id

问题描述

在我的 tomcat 应用程序中,我有一个扩展 RestfulServer 的 FHIRServlet。它注册了一个拦截器,以便能够检索 servlet 接收到的原始 JSON(我需要对其进行签名并返回它)和一个处理接收到的同意资源的同意资源提供程序:

package com.myapp.servlet;

import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer;
import com.myapp.fhir.resourceprovider.ConsentResourceProvider;
import com.myapp.fhir.resourceprovider.component.PreprocessedRequestInterceptor;
import com.myapp.util.Configuration;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;


@WebServlet(urlPatterns = {"/fhir/*"}, displayName = "FHIR Server")
public class FHIRServlet extends RestfulServer {

    @Override
    protected void initialize() throws ServletException {
        setFhirContext(Configuration.getInstance().getFhirContext());

        registerInterceptor(new PreprocessedRequestInterceptor());

        setResourceProviders(List.of(new ConsentResourceProvider()));
    }
}

不幸的是,我有两个问题:

  1. 当我尝试检索同意的 ID 时,它返回 null。如果我使用相同的 FhirContext 手动解析原始 JSON,它会很好地检索 id。
package com.myapp.fhir.resourceprovider;

import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.hl7.fhir.r4.model.Consent;
import com.myapp.util.Configuration;

public class ConsentResourceProvider implements IResourceProvider {
    private final Logger logger = LogManager.getLogger(ConsentResourceProvider.class);

    @Override
    public Class<Consent> getResourceType() {
        return Consent.class;
    }

    @Create
    public MethodOutcome createConsent(@ResourceParam Consent theConsent, HttpServletRequest theRequest) throws Exception {
        logger.info("Identifier: " + getConsentIDWithVersion(theConsent)); // Returns null

        FhirContext fhirContext = Configuration.getInstance().getFhirContext();

        IParser parser = fhirContext.newJsonParser().setPrettyPrint(true);

        String userConsentChangeLogToSign = getUserConsentChangeLogToSign(theRequest);

        theConsent = parser.parseResource(Consent.class, userConsentChangeLogToSign);

        logger.info("Identifier: " + getConsentIDWithVersion(theConsent)); // Returns Consent/6139f5375d04d763fa8d06aa/_history/1631194843361

        Provenance provenance = createConsentSignature(theConsent, signedUserConsentChangeLog);

        logger.debug("Signature: "+ parser.encodeResourceToString(provenance));

        MethodOutcome methodOutcome = new MethodOutcome();
        methodOutcome.setResource(provenance);

        return methodOutcome;
    }

    protected String getUserConsentChangeLogToSign(HttpServletRequest theRequest) throws InvalidRequestException {
        String originalJSONConsent = new String((byte[])theRequest.getAttribute("originalJSONConsent"), StandardCharsets.UTF_8);

        logger.info("Retrieved originalJSONConsent: "+ originalJSONConsent);

        return originalJSONConsent;
    }

    protected Provenance createConsentSignature(Consent theConsent, String signedUserConsentChangeLog) {
        Provenance provenance = new Provenance();

        String consentId = getConsentIDWithVersion(theConsent);

        logger.debug("ConsentId: "+ consentId);

        provenance.getTargetFirstRep()
            .setType("Consent")
            .setReference(consentId);

        return provenance;
    }

    protected String getConsentIDWithVersion(Consent theConsent) {
        return theConsent.getId();
    }
}
package com.myapp.fhir.resourceprovider.component;

import ca.uhn.fhir.interceptor.api.Hook;
import ca.uhn.fhir.interceptor.api.Pointcut;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.servlet.http.HttpServletRequest;
import ca.uhn.fhir.rest.api.server.RequestDetails;

public class PreprocessedRequestInterceptor {
    protected Logger logger = LogManager.getLogger(PreprocessedRequestInterceptor.class);

    @Hook(Pointcut.SERVER_INCOMING_REQUEST_POST_PROCESSED)
    public boolean interceptRequest(HttpServletRequest theRequest, RequestDetails requestDetails) {
        if(!"Consent".equalsIgnoreCase(requestDetails.getResourceName())) {
            logger.debug("Not a Consent resource: "+ requestDetails.getResourceName());
            return true;
        }

        requestDetails.loadRequestContents();

        if(requestDetails.getRequestContentsIfLoaded() == null) {
            logger.debug("RequestContents if not loaded");
            return true;
        }

        logger.info("Set originalJSONConsent attribute to "+ new String(requestDetails.getRequestContentsIfLoaded()));

        theRequest.setAttribute("originalJSONConsent", requestDetails.getRequestContentsIfLoaded());

        return true;
    }
}

我尝试禁用(不注册)最后一堂课,但没有帮助。

  1. 当我在目标中使用 Consent id 创建出处资源时,它会被截断,因此它只包含“Consent/6139f5375d04d763fa8d06aa”而没有整个 _history 部分。

编辑 > 解析器有一个选项:

getFhirContext().getParserOptions().setStripVersionsFromReferences(false);

这解决了第二个问题。

感觉好像我做错了什么,但我在文档中找不到任何有用的信息。

谢谢你的帮助。

标签: javahl7-fhirhapihapi-fhir

解决方案


推荐阅读