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