001package ca.cdr.api.model.json;
002
003/*
004 * #%L
005 * Smile CDR - CDR
006 * %%
007 * Copyright (C) 2016 - 2024 Smile CDR, Inc.
008 * %%
009 * All rights reserved.
010 * #L%
011 */
012
013import ca.cdr.api.model.enm.TransactionLogBodyTypeEnum;
014import ca.cdr.api.model.enm.TransactionLogEventSubTypeEnum;
015import ca.cdr.api.model.enm.TransactionLogOutcomeEnum;
016import ca.cdr.api.model.enm.TransactionLogStepTypeEnum;
017import ca.cdr.api.pub.hl7v2.model.MappingMessage;
018import ca.cdr.api.util.MappingMessageUtil;
019import ca.cdr.api.validator.enm.RequestValidatingResultEnum;
020import com.fasterxml.jackson.annotation.JsonProperty;
021import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
022import com.fasterxml.jackson.databind.annotation.JsonSerialize;
023import io.swagger.v3.oas.annotations.media.Schema;
024import jakarta.annotation.Nullable;
025import jakarta.servlet.http.HttpServletRequest;
026
027import java.sql.Timestamp;
028import java.util.Date;
029import java.util.List;
030
031import static java.util.Objects.nonNull;
032import static org.apache.commons.lang3.StringUtils.isNotBlank;
033
034public class TransactionLogStepJson implements IModelJson {
035
036        @JsonProperty(value = "body")
037        private StringWrapper myBody;
038
039        @JsonProperty(value = "bodyType")
040        private TransactionLogBodyTypeEnum myBodyType;
041
042        @JsonProperty(value = "endpointLocalHost")
043        private String myEndpointLocalHost;
044
045        @JsonProperty(value = "endpointLocalPort")
046        private Integer myEndpointLocalPort;
047
048        @JsonProperty(value = "endpointRemoteHost")
049        private String myEndpointRemoteHost;
050
051        @JsonProperty(value = "endpointRemotePort")
052        private Integer myEndpointRemotePort;
053
054        @JsonProperty("id")
055        private Long myId;
056
057        @JsonProperty("initialTimestamp")
058        @JsonSerialize(using = JsonDateSerializer.class)
059        @JsonDeserialize(using = JsonDateDeserializer.class)
060        private Date myInitialTimestamp;
061
062        @JsonProperty("outcome")
063        private TransactionLogOutcomeEnum myOutcome;
064
065        @JsonProperty(value = "processingTime")
066        private Long myProcessingTime;
067
068        @JsonProperty("requestUrl")
069        private String myRequestUrl;
070
071        @JsonProperty("requestVerb")
072        private String myRequestVerb;
073
074        @JsonProperty("subType")
075        private TransactionLogEventSubTypeEnum mySubType;
076
077        @JsonProperty("type")
078        private TransactionLogStepTypeEnum myType;
079
080        @Schema(description = "The HTTP response status, e.g. 200 or 404")
081        @JsonProperty("responseStatus")
082        private Short myResponseStatus;
083
084        @JsonProperty("requestValidatingResult")
085        private RequestValidatingResultEnum myRequestValidatingResult;
086
087        @JsonProperty("subscriptionId")
088        private String mySubscriptionId;
089
090        private Long userId;
091
092        private String userModuleId;
093
094        private String userNodeId;
095
096        private String username;
097
098        private String userFamilyName;
099
100        private String userGivenName;
101        private Long myPid;
102
103        private String clientId;
104
105        private String clientNodeId;
106
107        private String clientModuleId;
108
109        private String clientPid;
110
111        private String clientName;
112
113        public Long getUserId() {
114                return userId;
115        }
116
117        public void setUserId(Long userId) {
118                this.userId = userId;
119        }
120
121        public String getUserModuleId() {
122                return userModuleId;
123        }
124
125        public void setUserModuleId(String userModuleId) {
126                this.userModuleId = userModuleId;
127        }
128
129        public String getUserNodeId() {
130                return userNodeId;
131        }
132
133        public void setUserNodeId(String userNodeId) {
134                this.userNodeId = userNodeId;
135        }
136
137        public String getUsername() {
138                return username;
139        }
140
141        public void setUsername(String username) {
142                this.username = username;
143        }
144
145        public String getUserFamilyName() {
146                return userFamilyName;
147        }
148
149        public void setUserFamilyName(String userFamilyName) {
150                this.userFamilyName = userFamilyName;
151        }
152
153        public String getUserGivenName() {
154                return userGivenName;
155        }
156
157        public void setUserGivenName(String userGivenName) {
158                this.userGivenName = userGivenName;
159        }
160
161        public String getBody() {
162                return nonNull(this.myBody) ? this.myBody.getStringValue() : null;
163        }
164
165        public void setBody(String theBody) {
166                this.myBody = nonNull(theBody) ? new StringWrapper(theBody) : null;
167        }
168
169        public TransactionLogBodyTypeEnum getBodyType() {
170                return myBodyType;
171        }
172
173        public void setBodyType(TransactionLogBodyTypeEnum theBodyType) {
174                myBodyType = theBodyType;
175        }
176
177        public String getEndpointLocalHost() {
178                return myEndpointLocalHost;
179        }
180
181        public void setEndpointLocalHost(String theEndpointLocalHost) {
182                myEndpointLocalHost = theEndpointLocalHost;
183        }
184
185        public Integer getEndpointLocalPort() {
186                return myEndpointLocalPort;
187        }
188
189        public void setEndpointLocalPort(Integer theEndpointLocalPort) {
190                myEndpointLocalPort = theEndpointLocalPort;
191        }
192
193        public String getEndpointRemoteHost() {
194                return myEndpointRemoteHost;
195        }
196
197        public void setEndpointRemoteHost(String theEndpointRemoteHost) {
198                myEndpointRemoteHost = theEndpointRemoteHost;
199        }
200
201        public Integer getEndpointRemotePort() {
202                return myEndpointRemotePort;
203        }
204
205        public void setEndpointRemotePort(Integer theEndpointRemotePort) {
206                myEndpointRemotePort = theEndpointRemotePort;
207        }
208
209        public Long getId() {
210                return myId;
211        }
212
213        public void setId(Long thePid) {
214                myId = thePid;
215        }
216
217        public Date getInitialTimestamp() {
218                return myInitialTimestamp;
219        }
220
221        public void setInitialTimestamp(Date theTimestamp) {
222                myInitialTimestamp = theTimestamp;
223                if (myInitialTimestamp instanceof Timestamp) {
224                        myInitialTimestamp = new Date(myInitialTimestamp.getTime());
225                }
226        }
227
228        public TransactionLogOutcomeEnum getOutcome() {
229                return myOutcome;
230        }
231
232        public void setOutcome(TransactionLogOutcomeEnum theOutcome) {
233                myOutcome = theOutcome;
234        }
235
236        public Long getProcessingTime() {
237                return myProcessingTime;
238        }
239
240        public void setProcessingTime(Long theProcessingTime) {
241                myProcessingTime = theProcessingTime;
242        }
243
244        public String getRequestUrl() {
245                return myRequestUrl;
246        }
247
248        public void setRequestUrl(String theRequestUrl) {
249                myRequestUrl = theRequestUrl;
250        }
251
252        public String getRequestVerb() {
253                return myRequestVerb;
254        }
255
256        public void setRequestVerb(String theRequestVerb) {
257                myRequestVerb = theRequestVerb;
258        }
259
260        public TransactionLogEventSubTypeEnum getSubType() {
261                return mySubType;
262        }
263
264        public void setSubType(TransactionLogEventSubTypeEnum theSubType) {
265                mySubType = theSubType;
266        }
267
268        public TransactionLogStepTypeEnum getType() {
269                return myType;
270        }
271
272        public void setType(TransactionLogStepTypeEnum theType) {
273                myType = theType;
274        }
275
276        public Short getResponseStatus() {
277                return myResponseStatus;
278        }
279
280        public void setResponseStatus(Short theResponseStatus) {
281                myResponseStatus = theResponseStatus;
282        }
283
284        public RequestValidatingResultEnum getRequestValidatingResult() {
285                return myRequestValidatingResult;
286        }
287
288        public void setRequestValidatingResult(RequestValidatingResultEnum theRequestValidatingResult) {
289                myRequestValidatingResult = theRequestValidatingResult;
290        }
291
292        public String getSubscriptionId() {
293                return mySubscriptionId;
294        }
295
296        public void setSubscriptionId(String theSubscriptionId) {
297                mySubscriptionId = theSubscriptionId;
298        }
299
300        public Long getPid() {
301                return myPid;
302        }
303
304        public void setPid(Long thePid) {
305                myPid = thePid;
306        }
307
308        public String getClientId() {
309                return this.clientId;
310        }
311
312        public void setClientId(String theClientId) {
313                this.clientId = theClientId;
314        }
315
316        public String getClientModuleId() {
317                return clientModuleId;
318        }
319
320        public void setClientModuleId(String clientModuleId) {
321                this.clientModuleId = clientModuleId;
322        }
323
324        public String getClientNodeId() {
325                return clientNodeId;
326        }
327
328        public void setClientNodeId(String clientNodeId) {
329                this.clientNodeId = clientNodeId;
330        }
331
332        public String getClientPid() {
333                return clientPid;
334        }
335
336        public void setClientPid(String clientPid) {
337                this.clientPid = clientPid;
338        }
339
340        public String getClientName() {
341                return clientName;
342        }
343
344        public void setClientName(String clientName) {
345                this.clientName = clientName;
346        }
347
348        @Override
349        public String toString() {
350                String retval = null;
351                if (getType() != null) {
352                        retval = getType().toString();
353                        if (getSubType() != null) {
354                                retval += "/" + getSubType();
355                        }
356                }
357                return retval;
358        }
359
360        /**
361         * Given a set of mapping issues (if any), generate a {@link TransactionLogStepJson}
362         * that can be sent to the transaction log service. Will only return
363         * an object if any issues are actually present, otherwise returns null.
364         *
365         * @return Returns null if no issues detected
366         */
367        @Nullable
368        public static TransactionLogStepJson createTransactionLogStepForProcessing(List<MappingMessage> theIssues) {
369                boolean haveErrors = MappingMessageUtil.haveErrors(theIssues);
370
371                // Construct a markdown message containing any processing
372                // messages
373                StringBuilder messageMarkdown = new StringBuilder();
374                for (MappingMessage nextIssue : theIssues) {
375                        if (messageMarkdown.length() > 0) {
376                                messageMarkdown.append("\n");
377                        }
378                        messageMarkdown.append("* ");
379                        messageMarkdown.append("[**").append(nextIssue.getLevel().name()).append("**] ");
380                        if (isNotBlank(nextIssue.getPath())) {
381                                messageMarkdown.append(" `").append(nextIssue.getPath()).append("` - ");
382                        }
383                        messageMarkdown.append(nextIssue.getMessage());
384                }
385
386                // Add a processing step if there were any messages
387                // generated during conversion
388                String messageMarkdownString = messageMarkdown.toString();
389                TransactionLogStepJson mapStep = null;
390                if (messageMarkdownString.length() > 0) {
391                        TransactionLogOutcomeEnum outcome = TransactionLogOutcomeEnum.SUCCESS;
392                        if (haveErrors) {
393                                outcome = TransactionLogOutcomeEnum.FAIL;
394                        }
395
396                        mapStep = new TransactionLogStepJson();
397                        mapStep.setOutcome(outcome);
398                        mapStep.setType(TransactionLogStepTypeEnum.PROCESSING);
399                        mapStep.setBody(messageMarkdownString);
400                        mapStep.setBodyType(TransactionLogBodyTypeEnum.MESSAGE_MARKDOWN);
401                        mapStep.setInitialTimestamp(new Date());
402                }
403                return mapStep;
404        }
405
406        public static class StringWrapper {
407
408                private String myValue;
409
410                public StringWrapper(String theValue) {
411                        this.myValue = theValue;
412                }
413
414                public String getStringValue() {
415                        return myValue;
416                }
417        }
418
419        public void setRequestUrlFromServletRequest(HttpServletRequest theRequest) {
420                StringBuffer requestURL = theRequest.getRequestURL();
421                String queryString = theRequest.getQueryString();
422
423                if (queryString == null) {
424                        setRequestUrl(requestURL.toString());
425                } else {
426                        setRequestUrl(requestURL.append('?').append(queryString).toString());
427                }
428        }
429
430        public void populateRequestAddresses(HttpServletRequest theRequest) {
431                setEndpointRemoteHost(theRequest.getRemoteAddr());
432                setEndpointRemotePort(theRequest.getRemotePort());
433                setEndpointLocalHost(theRequest.getLocalAddr());
434                setEndpointLocalPort(theRequest.getLocalPort());
435        }
436}