001/*- 002 * #%L 003 * Smile CDR - CDR 004 * %% 005 * Copyright (C) 2016 - 2025 Smile CDR, Inc. 006 * %% 007 * All rights reserved. 008 * #L% 009 */ 010package ca.cdr.api.transactionlog; 011 012import ca.cdr.api.model.enm.TransactionLogEventSubTypeEnum; 013import ca.cdr.api.model.enm.TransactionLogEventTypeEnum; 014import ca.cdr.api.model.json.TransactionLogEventsJson; 015import ca.cdr.api.model.json.TransactionLogStepJson; 016import com.fasterxml.jackson.core.JsonProcessingException; 017import com.fasterxml.jackson.databind.ObjectMapper; 018import org.apache.commons.lang3.StringUtils; 019 020import java.util.List; 021import java.util.Map; 022import java.util.Objects; 023 024import static org.apache.commons.lang3.ObjectUtils.isEmpty; 025 026/** 027 * Parameter Object class encapsulating the properties required to persist a {@link TransactionLogEventsJson.TransactionLogEventJson} 028 * NOTE: IncomingTransactionLogBuilder class is using vanilla Jackson - FHIR resources can not be serialized. 029 * 030 * @apiNote myType the type of event that is logged 031 * @apiNote mySubType sub-categories precising the type 032 * @apiNote myTransactionGuid the GUID of the transaction log 033 * @apiNote myInitialSteps the {@link TransactionLogStepJson} to add to this transaction log 034 * @apiNote myTransactionId unique ID identifying the request for which this transaction is created 035 * @apiNote myModuleId the ID of the module creating the log 036 * @apiNote myUserPid the PID of the user creating the log 037 * @apiNote myAdditionalJson inline JSON of client provided key/value pairs 038 * 039 */ 040public class IncomingTransactionLog { 041 private final TransactionLogEventTypeEnum myType; 042 private final TransactionLogEventSubTypeEnum mySubType; 043 private final List<TransactionLogStepJson> myInitialSteps; 044 private final String myTransactionId; 045 private final String myTransactionGuid; 046 private final String myModuleId; 047 private final String myAdditionalJson; 048 049 private final Long myUserPid; 050 private final String myUsername; 051 052 public static IncomingTransactionLogBuilder builder() { 053 return new IncomingTransactionLogBuilder(); 054 } 055 056 public static IncomingTransactionLogBuilder from(IncomingTransactionLog theIncomingTransactionLog) { 057 return builder() 058 .withType(theIncomingTransactionLog.myType) 059 .withSubType(theIncomingTransactionLog.mySubType) 060 .withInitialSteps(theIncomingTransactionLog.myInitialSteps) 061 .withTransactionId(theIncomingTransactionLog.myTransactionId) 062 .withTransactionGuid(theIncomingTransactionLog.myTransactionGuid) 063 .withModuleId(theIncomingTransactionLog.myModuleId) 064 .withAdditionalJson(theIncomingTransactionLog.myAdditionalJson) 065 .withUserPid(theIncomingTransactionLog.myUserPid) 066 .withUsername(theIncomingTransactionLog.myUsername); 067 } 068 069 private IncomingTransactionLog(IncomingTransactionLogBuilder theIncomingTransactionLogBuilder) { 070 myType = theIncomingTransactionLogBuilder.myType; 071 mySubType = theIncomingTransactionLogBuilder.mySubType; 072 myInitialSteps = theIncomingTransactionLogBuilder.myInitialSteps; 073 myTransactionId = theIncomingTransactionLogBuilder.myTransactionId; 074 myTransactionGuid = theIncomingTransactionLogBuilder.myTransactionGuid; 075 myModuleId = theIncomingTransactionLogBuilder.myModuleId; 076 myAdditionalJson = theIncomingTransactionLogBuilder.myAdditionalJson; 077 myUsername = theIncomingTransactionLogBuilder.myUsername; 078 myUserPid = theIncomingTransactionLogBuilder.myUserPid; 079 } 080 081 public static IncomingTransactionLog from(TransactionLogEventsJson.TransactionLogEventJson theLog) { 082 return builder() 083 .withType(theLog.getType()) 084 .withSubType(theLog.getSubType()) 085 .withInitialSteps(theLog.getEvents()) 086 .withTransactionId(theLog.getRequestId()) 087 .withTransactionGuid(theLog.getTransactionGuid()) 088 .withModuleId(theLog.getEndpointModuleId()) 089 .withAdditionalJson(theLog.getAdditionalJson()) 090 .withUserPid(theLog.getUserId()) 091 .withUsername(theLog.getUsername()) 092 .build(); 093 } 094 095 public TransactionLogEventTypeEnum getType() { 096 return myType; 097 } 098 099 public TransactionLogEventSubTypeEnum getSubType() { 100 return mySubType; 101 } 102 103 public Long getUserPid() { 104 return myUserPid; 105 } 106 107 public String getUsername() { 108 return myUsername; 109 } 110 111 public List<TransactionLogStepJson> getInitialSteps() { 112 return myInitialSteps; 113 } 114 115 public String getTransactionId() { 116 return myTransactionId; 117 } 118 119 public String getTransactionGuid() { 120 return myTransactionGuid; 121 } 122 123 public boolean hasTransactionGuid() { 124 return StringUtils.isNotEmpty(myTransactionGuid); 125 } 126 127 public String getModuleId() { 128 return myModuleId; 129 } 130 131 public String getAdditionalJson() { 132 return myAdditionalJson; 133 } 134 135 public static final class IncomingTransactionLogBuilder { 136 private final ObjectMapper ourObjectMapper = new ObjectMapper(); 137 private TransactionLogEventTypeEnum myType; 138 private TransactionLogEventSubTypeEnum mySubType; 139 private List<TransactionLogStepJson> myInitialSteps; 140 private String myTransactionId; 141 private String myTransactionGuid; 142 private String myModuleId; 143 private String myAdditionalJson; 144 private String myUsername; 145 private Long myUserPid; 146 147 private IncomingTransactionLogBuilder() {} 148 149 public IncomingTransactionLogBuilder withType(TransactionLogEventTypeEnum theType) { 150 myType = theType; 151 return this; 152 } 153 154 public IncomingTransactionLogBuilder withSubType(TransactionLogEventSubTypeEnum theSubType) { 155 mySubType = theSubType; 156 return this; 157 } 158 159 public IncomingTransactionLogBuilder withInitialSteps(List<TransactionLogStepJson> theInitialSteps) { 160 myInitialSteps = theInitialSteps; 161 return this; 162 } 163 164 public IncomingTransactionLogBuilder withTransactionId(String theTransactionId) { 165 myTransactionId = theTransactionId; 166 return this; 167 } 168 169 public IncomingTransactionLogBuilder withTransactionGuid(String theTransactionGuid) { 170 myTransactionGuid = theTransactionGuid; 171 return this; 172 } 173 174 public IncomingTransactionLogBuilder withModuleId(String theModuleId) { 175 myModuleId = theModuleId; 176 return this; 177 } 178 179 public IncomingTransactionLogBuilder withUsername(String theUsername) { 180 myUsername = theUsername; 181 return this; 182 } 183 184 public IncomingTransactionLogBuilder withUserPid(Long theUserPid) { 185 myUserPid = theUserPid; 186 return this; 187 } 188 189 public IncomingTransactionLogBuilder withAdditionalJson(String theAdditionalJson) { 190 myAdditionalJson = theAdditionalJson; 191 return this; 192 } 193 194 /** 195 * NOTE: this method is using vanilla Jackson - FHIR resources can not be serialized. 196 * IllegalArgumentException is thrown if theAdditionalProperties are not Json serializable with vanilla Jackson 197 */ 198 public IncomingTransactionLogBuilder withAdditionalProperties(Map<String, Object> theAdditionalProperties) { 199 if (isEmpty(theAdditionalProperties)) { 200 return this; 201 } 202 try { 203 myAdditionalJson = ourObjectMapper.writeValueAsString(theAdditionalProperties); 204 } catch (JsonProcessingException e) { 205 throw new IllegalArgumentException("Could not serialize the additional properties to json string", e); 206 } 207 return this; 208 } 209 210 public void validate() { 211 Objects.requireNonNull(myType, "Transaction log type cannot be null"); 212 Objects.requireNonNull(mySubType, "Transaction log subType cannot be null"); 213 Objects.requireNonNull(myModuleId, "Transaction log moduleId cannot be null"); 214 Objects.requireNonNull(myInitialSteps, "Transaction log initial steps cannot be null"); 215 } 216 217 public IncomingTransactionLog build() { 218 validate(); 219 return new IncomingTransactionLog(this); 220 } 221 } 222}