Skip to content

ITI-78 audit message with query string for POST /Patient/_search #514

Description

@rbastiaansen732

public FhirQueryAuditDataset enrichAuditDatasetFromRequest(FhirQueryAuditDataset auditDataset, Object request, Map<String, Object> parameters) {

Suggest to support query string for POST /Patient/_search in ITI-78 audit message:

    /**
     * Enrich the audit dataset with the FHIR search criteria.
     * <p>
     * IPF's {@link org.openehealth.ipf.commons.ihe.fhir.audit.FhirQueryAuditStrategy} populates
     * {@code queryString} from the URL query string (the {@code FhirHttpQuery} header, which
     * is {@code httpServletRequest.getQueryString()}). For {@code POST /Patient/_search}
     * (IHE ITI-78 §3.78.4.1.2) the parameters live in the {@code application/x-www-form-urlencoded}
     * request body, not the URL, so the URL query string is empty and the audit's
     * {@code ParticipantObjectQuery} would otherwise lack the search criteria.
     * <p>
     * HAPI merges URL and form-body parameters into {@link RequestDetails#getParameters()}
     * (Servlet API behaviour for form-encoded POSTs), so we recover the search criteria from
     * there when the URL-derived query string is absent. The reconstructed string is in
     * URL-decoded form to match {@code FhirQueryAuditStrategy}'s decoded result.
     */
    @Override
    public FhirQueryAuditDataset enrichAuditDatasetFromRequest(FhirQueryAuditDataset auditDataset,
                                                               Object request, Map<String, Object> parameters) {
        var dataset = super.enrichAuditDatasetFromRequest(auditDataset, request, parameters);
        if (request instanceof IdType idType) {
            dataset.getPatientIds().add(idType.getValue());
        }
        if (dataset.getQueryString() == null || dataset.getQueryString().isEmpty()) {
            RequestDetails requestDetails = (RequestDetails) parameters.get(Constants.FHIR_REQUEST_DETAILS);
            if (requestDetails != null) {
                String rebuilt = buildQueryString(requestDetails.getParameters());
                if (!rebuilt.isEmpty()) {
                    dataset.setQueryString(rebuilt);
                }
            }
        }
        return dataset;
    }

    private static String buildQueryString(Map<String, String[]> params) {
        if (params == null || params.isEmpty()) {
            return "";
        }
        StringJoiner joiner = new StringJoiner("&");
        params.forEach((key, values) -> {
            if (values == null) {
                return;
            }
            for (String value : values) {
                joiner.add(key + "=" + (value == null ? "" : value));
            }
        });
        return joiner.toString();
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions