001/*- 002 * #%L 003 * Smile CDR - CDR 004 * %% 005 * Copyright (C) 2016 - 2024 Smile CDR, Inc. 006 * %% 007 * All rights reserved. 008 * #L% 009 */ 010package ca.cdr.api.util; 011 012import ca.cdr.api.model.json.TransactionLogStepJson; 013import ca.cdr.api.pub.hl7v2.model.MappingMessage; 014import ca.uhn.fhir.rest.api.server.RequestDetails; 015import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; 016import com.fasterxml.jackson.core.JsonProcessingException; 017import com.fasterxml.jackson.databind.ObjectMapper; 018import jakarta.annotation.Nullable; 019import org.apache.commons.lang3.Validate; 020 021import java.util.ArrayList; 022import java.util.Collections; 023import java.util.HashMap; 024import java.util.List; 025import java.util.Map; 026 027import static java.util.Objects.isNull; 028 029public class TransactionLogRequestDetailsAccess { 030 private static final org.slf4j.Logger ourLog = 031 org.slf4j.LoggerFactory.getLogger(TransactionLogRequestDetailsAccess.class); 032 public static final String STEPS_LIST_KEY = TransactionLogRequestDetailsAccess.class.getName() + "_STEPS_LIST"; 033 public static final String REQUEST_SUBTYPE_KEY = 034 TransactionLogRequestDetailsAccess.class.getName() + "_REQUEST_SUBTYPE_KEY"; 035 private static final String MESSAGES_LIST_KEY = TransactionLogRequestDetailsAccess.class.getName() + "_STEPS_LIST"; 036 private static final String ADDITIONAL_JSON_MAP_KEY = 037 TransactionLogRequestDetailsAccess.class.getName() + "_ADDITIONAL_JSON_MAP"; 038 039 private static final ObjectMapper ourObjectMapper = new ObjectMapper(); 040 041 public static void addMessageToRequest(RequestDetails theDetails, MappingMessage theMessage) { 042 Validate.notNull(theDetails, "theDetails must not be null"); 043 Validate.notNull(theMessage, "theMessage must not be null"); 044 @SuppressWarnings("unchecked") 045 List<MappingMessage> messages = 046 (List<MappingMessage>) theDetails.getUserData().get(MESSAGES_LIST_KEY); 047 if (messages == null) { 048 messages = new ArrayList<>(); 049 theDetails.getUserData().put(MESSAGES_LIST_KEY, messages); 050 } 051 messages.add(theMessage); 052 } 053 054 @SuppressWarnings("unchecked") 055 public static List<MappingMessage> getMessagesOnRequest(RequestDetails theDetails) { 056 List<MappingMessage> messages = 057 (List<MappingMessage>) theDetails.getUserData().get(MESSAGES_LIST_KEY); 058 if (messages == null) { 059 return Collections.emptyList(); 060 } 061 return Collections.unmodifiableList(messages); 062 } 063 064 @SuppressWarnings("unchecked") 065 public static @Nullable List<TransactionLogStepJson> getTransactionLogStepsFromRequest( 066 ServletRequestDetails theRequestDetails) { 067 if (theRequestDetails == null) { 068 return null; 069 } 070 071 return (List<TransactionLogStepJson>) 072 theRequestDetails.getServletRequest().getAttribute(TransactionLogRequestDetailsAccess.STEPS_LIST_KEY); 073 } 074 075 /** 076 * Utility method to add key/value pairs to a transactionLog. The provided value object needs to be serializable 077 * with Jackson since pairs are accumulated and subsequently formatted in an inline Json string. 078 * 079 * IllegalArgumentException is thrown if <code>theObject</code> is not Json serializable with Jackson or <code>null</code>. 080 * 081 * @param theRequestDetails The request details where the pairs will be stored 082 * @param theKey The key for referencing to theObject. Keys are transformed into json properties when serializing a pair. 083 * @param theObject The value needing storage. Values are transformed into json values when serializing a pair. 084 * 085 */ 086 public static void addAdditionalJsonProperty(RequestDetails theRequestDetails, String theKey, Object theObject) { 087 Validate.notNull(theRequestDetails, "theDetails must not be null"); 088 Validate.notNull(theKey, "theKey must not be null"); 089 Validate.notNull(theObject, "theObject must not be null"); 090 091 try { 092 ourObjectMapper.writeValueAsString(theObject); 093 } catch (JsonProcessingException e) { 094 throw new IllegalArgumentException( 095 String.format( 096 "Unable to add pair with key %s to the additional Json property as the provided value object could not be parsed.", 097 theKey), 098 e); 099 } 100 101 Map<String, Object> additionalJsonPropertiesMap = getAdditionalJsonPropertiesMap(theRequestDetails); 102 103 additionalJsonPropertiesMap.put(theKey, theObject); 104 } 105 106 public static Map<String, Object> getAdditionalJsonPropertiesMap(RequestDetails theRequestDetails) { 107 Validate.notNull(theRequestDetails, "theDetails must not be null"); 108 109 @SuppressWarnings("unchecked") 110 Map<String, Object> additionalJsonPropertiesMap = 111 (Map<String, Object>) theRequestDetails.getAttribute(ADDITIONAL_JSON_MAP_KEY); 112 113 if (isNull(additionalJsonPropertiesMap)) { 114 additionalJsonPropertiesMap = new HashMap<>(); 115 theRequestDetails.setAttribute(ADDITIONAL_JSON_MAP_KEY, additionalJsonPropertiesMap); 116 } 117 118 return additionalJsonPropertiesMap; 119 } 120}