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}