001package ca.cdr.test.app.clients; 002 003import ca.uhn.hl7v2.HL7Exception; 004import ca.uhn.hl7v2.model.Message; 005import ca.uhn.hl7v2.parser.PipeParser; 006import com.google.common.base.Charsets; 007import jakarta.annotation.Nonnull; 008import jakarta.annotation.Nullable; 009import org.apache.commons.lang3.StringUtils; 010import org.apache.commons.lang3.Validate; 011import org.springframework.web.client.RestClient; 012 013import java.util.Base64; 014import java.util.Objects; 015 016import static org.springframework.http.HttpHeaders.CONTENT_TYPE; 017import static org.springframework.http.HttpHeaders.AUTHORIZATION; 018 019/** 020 * A REST client for sending HL7V2 messages to a Smile CDR server. 021 */ 022public class HL7V2RestClient { 023 private static final String HL7V2_MEDIA_TYPE = "application/hl7-v2"; 024 private final RestClient myRestClient; 025 private final PipeParser myParser; 026 027 /** 028 * Constructor with a pre-configured RestClient. 029 * 030 * @param theRestClient The RestClient to use 031 */ 032 HL7V2RestClient(RestClient theRestClient) { 033 myRestClient = theRestClient; 034 myParser = new PipeParser(); 035 } 036 037 /** 038 * Build a new HL7V2RestClient with the given base URL, username, and password. 039 * 040 * @param theBaseUrl The base URL of the HL7V2 endpoint, including port if needed. 041 * @param theUsername The username for authentication (optional) 042 * @param thePassword The password for authentication (optional) 043 * @return A new HL7V2RestClient 044 */ 045 public static HL7V2RestClient build(String theBaseUrl, @Nullable String theUsername, @Nullable String thePassword) { 046 RestClient.Builder builder = RestClient.builder() 047 .baseUrl(theBaseUrl) 048 .defaultHeader(CONTENT_TYPE, HL7V2_MEDIA_TYPE); 049 if (!StringUtils.isBlank(theUsername) && !StringUtils.isBlank(thePassword)) { 050 builder.defaultHeader( 051 AUTHORIZATION, 052 "Basic " 053 + Base64.getEncoder() 054 .encodeToString((theUsername + ":" + thePassword).getBytes(Charsets.UTF_8))); 055 } 056 return new HL7V2RestClient(builder.build()); 057 } 058 059 /** 060 * Send an HL7V2 message to the server. 061 * 062 * @param theMessage The HL7V2 message to send 063 * @return The response message from the server 064 * @throws HL7Exception If there is an error parsing the response 065 */ 066 @Nonnull 067 public Message sendMessage(String theMessage) throws HL7Exception { 068 Validate.notEmpty(theMessage, "Message is required"); 069 070 String responseBody = myRestClient 071 .post() 072 .body(theMessage) 073 .retrieve() 074 .body(String.class); 075 076 return myParser.parse(Objects.requireNonNull(responseBody)); 077 } 078 079 /** 080 * Send a pre-parsed HL7V2 message to the server. 081 * 082 * @param theMessage The pre-parsed HL7V2 message to send 083 * @return The response message from the server 084 * @throws HL7Exception If there is an error encoding the message or parsing the response 085 */ 086 @Nonnull 087 public Message sendMessage(Message theMessage) throws HL7Exception { 088 Validate.notNull(theMessage, "Message is required"); 089 return sendMessage(theMessage.encode()); 090 } 091}