| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.camel.component.fhir.api; |
| |
| import java.util.Map; |
| import ca.uhn.fhir.rest.client.api.IGenericClient; |
| import ca.uhn.fhir.rest.gclient.IOperationProcessMsg; |
| import ca.uhn.fhir.rest.gclient.IOperationProcessMsgMode; |
| import ca.uhn.fhir.rest.gclient.IOperationUnnamed; |
| import ca.uhn.fhir.rest.gclient.IOperationUntyped; |
| import ca.uhn.fhir.rest.gclient.IOperationUntypedWithInput; |
| |
| import org.apache.camel.util.ObjectHelper; |
| |
| import org.hl7.fhir.instance.model.api.IBaseBundle; |
| import org.hl7.fhir.instance.model.api.IBaseParameters; |
| import org.hl7.fhir.instance.model.api.IBaseResource; |
| import org.hl7.fhir.instance.model.api.IIdType; |
| |
| /** |
| * API for extended FHIR operations https://www.hl7.org/fhir/operations.html |
| */ |
| public class FhirOperation { |
| |
| private final IGenericClient client; |
| |
| public FhirOperation(IGenericClient client) { |
| this.client = client; |
| } |
| |
| /** |
| * Perform the operation across all versions of all resources of the given type on the server |
| * |
| * @param resourceType The resource type to operate on |
| * @param name Operation name |
| * @param parameters The parameters to use as input. May also be <code>null</code> if the operation |
| * does not require any input parameters. |
| * @param outputParameterType The type to use for the output parameters (this should be set to |
| * <code>Parameters.class</code> drawn from the version of the FHIR structures you are using), may be NULL |
| * @param useHttpGet use HTTP GET verb |
| * @param returnType If this operation returns a single resource body as its return type instead of a <code>Parameters</code> |
| * resource, use this method to specify that resource type. This is useful for certain |
| * operations (e.g. <code>Patient/NNN/$everything</code>) which return a bundle instead of |
| * a Parameters resource, may be NULL |
| * @param extraParameters see {@link ExtraParameters} for a full list of parameters that can be passed, may be NULL |
| * @param <T> extends {@link IBaseParameters} |
| * @return the {@link IBaseResource} |
| */ |
| public <T extends IBaseParameters> IBaseResource onType(Class<IBaseResource> resourceType, String name, |
| T parameters, Class<T> outputParameterType, boolean useHttpGet, Class<IBaseResource> returnType, Map<ExtraParameters, Object> extraParameters) { |
| IOperationUnnamed operationUnnamed = client.operation().onType(resourceType); |
| IOperationUntypedWithInput<? extends IBaseResource> operationUntypedWithInput = processNamedOperationParameters( |
| name, parameters, outputParameterType, useHttpGet, returnType, extraParameters, operationUnnamed); |
| return operationUntypedWithInput.execute(); |
| } |
| |
| /** |
| * Perform the operation across all versions of all resources of all types on the server |
| * |
| * @param name Operation name |
| * @param parameters The parameters to use as input. May also be <code>null</code> if the operation |
| * does not require any input parameters. |
| * @param outputParameterType The type to use for the output parameters (this should be set to |
| * <code>Parameters.class</code> drawn from the version of the FHIR structures you are using), may be NULL |
| * @param useHttpGet use HTTP GET verb |
| * @param returnType If this operation returns a single resource body as its return type instead of a <code>Parameters</code> |
| * resource, use this method to specify that resource type. This is useful for certain |
| * operations (e.g. <code>Patient/NNN/$everything</code>) which return a bundle instead of |
| * a Parameters resource, may be NULL |
| * @param extraParameters see {@link ExtraParameters} for a full list of parameters that can be passed, may be NULL |
| * @param <T> extends {@link IBaseParameters} |
| * @return the {@link IBaseResource} |
| */ |
| public <T extends IBaseParameters> IBaseResource onServer( |
| String name, T parameters, Class<T> outputParameterType, boolean useHttpGet, Class<IBaseResource> returnType, Map<ExtraParameters, Object> extraParameters) { |
| IOperationUnnamed operationUnnamed = client.operation().onServer(); |
| IOperationUntypedWithInput<? extends IBaseResource> operationUntypedWithInput = processNamedOperationParameters( |
| name, parameters, outputParameterType, useHttpGet, returnType, extraParameters, operationUnnamed); |
| return operationUntypedWithInput.execute(); |
| } |
| |
| /** |
| * Perform the operation across all versions of a specific resource (by ID and type) on the server. |
| * Note that <code>theId</code> must be populated with both a resource type and a resource ID at |
| * a minimum. |
| * |
| * @param id Resource (version will be stripped) |
| * @param name Operation name |
| * @param parameters The parameters to use as input. May also be <code>null</code> if the operation |
| * does not require any input parameters. |
| * @param outputParameterType The type to use for the output parameters (this should be set to |
| * <code>Parameters.class</code> drawn from the version of the FHIR structures you are using), may be NULL |
| * @param useHttpGet use HTTP GET verb |
| * @param returnType If this operation returns a single resource body as its return type instead of a <code>Parameters</code> |
| * resource, use this method to specify that resource type. This is useful for certain |
| * operations (e.g. <code>Patient/NNN/$everything</code>) which return a bundle instead of |
| * a Parameters resource, may be NULL |
| * @param extraParameters see {@link ExtraParameters} for a full list of parameters that can be passed, may be NULL |
| * @param <T> extends {@link IBaseParameters} |
| * |
| * @throws IllegalArgumentException If <code>theId</code> does not contain at least a resource type and ID |
| * |
| * @return the {@link IBaseResource} |
| */ |
| public <T extends IBaseParameters> IBaseResource onInstance( |
| IIdType id, String name, T parameters, Class<T> outputParameterType, boolean useHttpGet, Class<IBaseResource> returnType, Map<ExtraParameters, Object> extraParameters) { |
| IOperationUnnamed operationUnnamed = client.operation().onInstanceVersion(id); |
| IOperationUntypedWithInput<? extends IBaseResource> operationUntypedWithInput = processNamedOperationParameters( |
| name, parameters, outputParameterType, useHttpGet, returnType, extraParameters, operationUnnamed); |
| return operationUntypedWithInput.execute(); |
| } |
| |
| |
| /** |
| * This operation operates on a specific version of a resource |
| * |
| * @param id Resource version |
| * @param name Operation name |
| * @param parameters The parameters to use as input. May also be <code>null</code> if the operation |
| * does not require any input parameters. |
| * @param outputParameterType The type to use for the output parameters (this should be set to |
| * <code>Parameters.class</code> drawn from the version of the FHIR structures you are using), may be NULL |
| * @param useHttpGet use HTTP GET verb |
| * @param returnType If this operation returns a single resource body as its return type instead of a <code>Parameters</code> |
| * resource, use this method to specify that resource type. This is useful for certain |
| * operations (e.g. <code>Patient/NNN/$everything</code>) which return a bundle instead of |
| * a Parameters resource, may be NULL |
| * @param extraParameters see {@link ExtraParameters} for a full list of parameters that can be passed, may be NULL |
| * @param <T> extends {@link IBaseParameters} |
| * @return the {@link IBaseResource} |
| */ |
| public <T extends IBaseParameters> IBaseResource onInstanceVersion( |
| IIdType id, String name, T parameters, Class<T> outputParameterType, boolean useHttpGet, Class<IBaseResource> returnType, Map<ExtraParameters, Object> extraParameters) { |
| IOperationUnnamed operationUnnamed = client.operation().onInstanceVersion(id); |
| IOperationUntypedWithInput<? extends IBaseResource> operationUntypedWithInput = processNamedOperationParameters( |
| name, parameters, outputParameterType, useHttpGet, returnType, extraParameters, operationUnnamed); |
| return operationUntypedWithInput.execute(); |
| } |
| |
| /** |
| * This operation is called <b><a href="https://www.hl7.org/fhir/messaging.html">$process-message</a></b> as defined by the FHIR |
| * specification.<br><br> |
| * @param respondToUri An optional query parameter indicating that responses from the receiving server should be sent to this URI, may be NULL |
| * @param msgBundle Set the Message Bundle to POST to the messaging server |
| * @param asynchronous Whether to process the message asynchronously or synchronously, defaults to synchronous. |
| * @param responseClass the response class |
| * @param extraParameters see {@link ExtraParameters} for a full list of parameters that can be passed, may be NULL |
| * @param <T> extends {@link IBaseBundle} |
| * @return the {@link IBaseBundle} |
| */ |
| public <T extends IBaseBundle> T processMessage(String respondToUri, IBaseBundle msgBundle, boolean asynchronous, Class<T> responseClass, Map<ExtraParameters, Object> extraParameters) { |
| IOperationProcessMsg operationProcessMsg = client.operation().processMessage(); |
| |
| if (ObjectHelper.isNotEmpty(respondToUri)) { |
| operationProcessMsg.setResponseUrlParam(respondToUri); |
| } |
| |
| IOperationProcessMsgMode<T> operationProcessMsgMode = operationProcessMsg.setMessageBundle(msgBundle); |
| |
| if (asynchronous) { |
| operationProcessMsgMode.asynchronous(responseClass); |
| } else { |
| operationProcessMsgMode.synchronous(responseClass); |
| } |
| |
| ExtraParameters.process(extraParameters, operationProcessMsgMode); |
| return operationProcessMsgMode.execute(); |
| } |
| |
| private <T extends IBaseParameters> IOperationUntypedWithInput<? extends IBaseResource> processNamedOperationParameters(String name, T parameters, Class<T> outputParameterType, |
| boolean useHttpGet, Class<? extends IBaseResource> returnType, Map<ExtraParameters, Object> extraParameters, IOperationUnnamed operationUnnamed) { |
| IOperationUntyped named = operationUnnamed.named(name); |
| IOperationUntypedWithInput<? extends IBaseResource> operationUntypedWithInput; |
| if (outputParameterType != null) { |
| operationUntypedWithInput = named.withNoParameters(outputParameterType); |
| } else { |
| operationUntypedWithInput = named.withParameters(parameters); |
| } |
| if (useHttpGet) { |
| operationUntypedWithInput.useHttpGet(); |
| } |
| if (returnType != null) { |
| operationUntypedWithInput.returnResourceType(returnType); |
| } |
| ExtraParameters.process(extraParameters, operationUntypedWithInput); |
| return operationUntypedWithInput; |
| } |
| } |