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}