001/*- 002 * #%L 003 * HAPI FHIR JPA Server 004 * %% 005 * Copyright (C) 2014 - 2024 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.jpa.entity; 021 022import ca.uhn.fhir.batch2.model.JobDefinition; 023import ca.uhn.fhir.batch2.model.StatusEnum; 024import jakarta.persistence.Basic; 025import jakarta.persistence.Column; 026import jakarta.persistence.Entity; 027import jakarta.persistence.EnumType; 028import jakarta.persistence.Enumerated; 029import jakarta.persistence.FetchType; 030import jakarta.persistence.Id; 031import jakarta.persistence.Index; 032import jakarta.persistence.Lob; 033import jakarta.persistence.Table; 034import jakarta.persistence.Temporal; 035import jakarta.persistence.TemporalType; 036import jakarta.persistence.Version; 037import org.apache.commons.lang3.builder.ToStringBuilder; 038import org.apache.commons.lang3.builder.ToStringStyle; 039import org.hibernate.Length; 040 041import java.io.Serializable; 042import java.util.Date; 043 044import static ca.uhn.fhir.batch2.model.JobDefinition.ID_MAX_LENGTH; 045import static ca.uhn.fhir.jpa.entity.Batch2WorkChunkEntity.ERROR_MSG_MAX_LENGTH; 046import static ca.uhn.fhir.jpa.entity.Batch2WorkChunkEntity.WARNING_MSG_MAX_LENGTH; 047import static org.apache.commons.lang3.StringUtils.left; 048 049@Entity 050@Table( 051 name = "BT2_JOB_INSTANCE", 052 indexes = {@Index(name = "IDX_BT2JI_CT", columnList = "CREATE_TIME")}) 053public class Batch2JobInstanceEntity implements Serializable { 054 055 public static final int STATUS_MAX_LENGTH = 20; 056 public static final int TIME_REMAINING_LENGTH = 100; 057 public static final int PARAMS_JSON_MAX_LENGTH = 2000; 058 private static final long serialVersionUID = 8187134261799095422L; 059 public static final int INITIATING_USER_NAME_MAX_LENGTH = 200; 060 public static final int INITIATING_CLIENT_ID_MAX_LENGTH = 200; 061 062 @Id 063 @Column(name = "ID", length = JobDefinition.ID_MAX_LENGTH, nullable = false) 064 private String myId; 065 066 @Column(name = "CREATE_TIME", nullable = false) 067 @Temporal(TemporalType.TIMESTAMP) 068 private Date myCreateTime; 069 070 @Column(name = "START_TIME", nullable = true) 071 @Temporal(TemporalType.TIMESTAMP) 072 private Date myStartTime; 073 074 @Column(name = "END_TIME", nullable = true) 075 @Temporal(TemporalType.TIMESTAMP) 076 private Date myEndTime; 077 078 @Version 079 @Column(name = "UPDATE_TIME", nullable = true) 080 @Temporal(TemporalType.TIMESTAMP) 081 private Date myUpdateTime; 082 083 @Column(name = "DEFINITION_ID", length = JobDefinition.ID_MAX_LENGTH, nullable = false) 084 private String myDefinitionId; 085 086 @Column(name = "DEFINITION_VER", nullable = false) 087 private int myDefinitionVersion; 088 089 @Column(name = "STAT", length = STATUS_MAX_LENGTH, nullable = false) 090 @Enumerated(EnumType.STRING) 091 private StatusEnum myStatus; 092 093 @Column(name = "JOB_CANCELLED", nullable = false) 094 private boolean myCancelled; 095 096 @Column(name = "FAST_TRACKING", nullable = true) 097 private Boolean myFastTracking; 098 099 // TODO: VC column added in 7.2.0 - Remove non-VC column later 100 @Column(name = "PARAMS_JSON", length = PARAMS_JSON_MAX_LENGTH, nullable = true) 101 private String myParamsJson; 102 103 @Lob // TODO: VC column added in 7.2.0 - Remove non-VC column later 104 @Column(name = "PARAMS_JSON_LOB", nullable = true) 105 private String myParamsJsonLob; 106 107 @Column(name = "PARAMS_JSON_VC", nullable = true, length = Length.LONG32) 108 private String myParamsJsonVc; 109 110 @Column(name = "CMB_RECS_PROCESSED", nullable = true) 111 private Integer myCombinedRecordsProcessed; 112 113 @Column(name = "CMB_RECS_PER_SEC", nullable = true) 114 private Double myCombinedRecordsProcessedPerSecond; 115 116 @Column(name = "TOT_ELAPSED_MILLIS", nullable = true) 117 private Integer myTotalElapsedMillis; 118 119 @Column(name = "WORK_CHUNKS_PURGED", nullable = false) 120 private boolean myWorkChunksPurged; 121 122 @Column(name = "PROGRESS_PCT", nullable = false) 123 private double myProgress; 124 125 @Column(name = "ERROR_MSG", length = ERROR_MSG_MAX_LENGTH, nullable = true) 126 private String myErrorMessage; 127 128 @Column(name = "ERROR_COUNT", nullable = false) 129 private int myErrorCount; 130 131 @Column(name = "EST_REMAINING", length = TIME_REMAINING_LENGTH, nullable = true) 132 private String myEstimatedTimeRemaining; 133 134 @Column(name = "CUR_GATED_STEP_ID", length = ID_MAX_LENGTH, nullable = true) 135 private String myCurrentGatedStepId; 136 137 @Column(name = "WARNING_MSG", length = WARNING_MSG_MAX_LENGTH, nullable = true) 138 private String myWarningMessages; 139 140 @Column(name = "USER_NAME", length = INITIATING_USER_NAME_MAX_LENGTH, nullable = true) 141 private String myTriggeringUsername; 142 143 @Column(name = "CLIENT_ID", length = INITIATING_CLIENT_ID_MAX_LENGTH, nullable = true) 144 private String myTriggeringClientId; 145 146 /** 147 * Any output from the job can be held in this column 148 * Even serialized json 149 */ 150 @Lob // TODO: VC column added in 7.2.0 - Remove non-VC column later 151 @Basic(fetch = FetchType.LAZY) 152 @Column(name = "REPORT", nullable = true, length = Integer.MAX_VALUE - 1) 153 private String myReport; 154 155 @Column(name = "REPORT_VC", nullable = true, length = Length.LONG32) 156 private String myReportVc; 157 158 public String getCurrentGatedStepId() { 159 return myCurrentGatedStepId; 160 } 161 162 public void setCurrentGatedStepId(String theCurrentGatedStepId) { 163 myCurrentGatedStepId = theCurrentGatedStepId; 164 } 165 166 public boolean isCancelled() { 167 return myCancelled; 168 } 169 170 public void setCancelled(boolean theCancelled) { 171 myCancelled = theCancelled; 172 } 173 174 public int getErrorCount() { 175 return myErrorCount; 176 } 177 178 public void setErrorCount(int theErrorCount) { 179 myErrorCount = theErrorCount; 180 } 181 182 public Integer getTotalElapsedMillis() { 183 return myTotalElapsedMillis; 184 } 185 186 public void setTotalElapsedMillis(Integer theTotalElapsedMillis) { 187 myTotalElapsedMillis = theTotalElapsedMillis; 188 } 189 190 public Integer getCombinedRecordsProcessed() { 191 return myCombinedRecordsProcessed; 192 } 193 194 public void setCombinedRecordsProcessed(Integer theCombinedRecordsProcessed) { 195 myCombinedRecordsProcessed = theCombinedRecordsProcessed; 196 } 197 198 public Double getCombinedRecordsProcessedPerSecond() { 199 return myCombinedRecordsProcessedPerSecond; 200 } 201 202 public void setCombinedRecordsProcessedPerSecond(Double theCombinedRecordsProcessedPerSecond) { 203 myCombinedRecordsProcessedPerSecond = theCombinedRecordsProcessedPerSecond; 204 } 205 206 public Date getCreateTime() { 207 return myCreateTime; 208 } 209 210 public void setCreateTime(Date theCreateTime) { 211 myCreateTime = theCreateTime; 212 } 213 214 public Date getStartTime() { 215 return myStartTime; 216 } 217 218 public void setStartTime(Date theStartTime) { 219 myStartTime = theStartTime; 220 } 221 222 public Date getEndTime() { 223 return myEndTime; 224 } 225 226 public void setEndTime(Date theEndTime) { 227 myEndTime = theEndTime; 228 } 229 230 public void setUpdateTime(Date theTime) { 231 myUpdateTime = theTime; 232 } 233 234 public Date getUpdateTime() { 235 return myUpdateTime; 236 } 237 238 public String getId() { 239 return myId; 240 } 241 242 public void setId(String theId) { 243 myId = theId; 244 } 245 246 public String getDefinitionId() { 247 return myDefinitionId; 248 } 249 250 public void setDefinitionId(String theDefinitionId) { 251 myDefinitionId = theDefinitionId; 252 } 253 254 public int getDefinitionVersion() { 255 return myDefinitionVersion; 256 } 257 258 public void setDefinitionVersion(int theDefinitionVersion) { 259 myDefinitionVersion = theDefinitionVersion; 260 } 261 262 public StatusEnum getStatus() { 263 return myStatus; 264 } 265 266 public void setStatus(StatusEnum theStatus) { 267 myStatus = theStatus; 268 } 269 270 public String getParams() { 271 if (myParamsJsonVc != null) { 272 return myParamsJsonVc; 273 } 274 if (myParamsJsonLob != null) { 275 return myParamsJsonLob; 276 } 277 return myParamsJson; 278 } 279 280 public void setParams(String theParams) { 281 myParamsJsonVc = theParams; 282 myParamsJsonLob = null; 283 myParamsJson = null; 284 } 285 286 public boolean getWorkChunksPurged() { 287 return myWorkChunksPurged; 288 } 289 290 public void setWorkChunksPurged(boolean theWorkChunksPurged) { 291 myWorkChunksPurged = theWorkChunksPurged; 292 } 293 294 public double getProgress() { 295 return myProgress; 296 } 297 298 public void setProgress(double theProgress) { 299 myProgress = theProgress; 300 } 301 302 public String getErrorMessage() { 303 return myErrorMessage; 304 } 305 306 public void setErrorMessage(String theErrorMessage) { 307 myErrorMessage = left(theErrorMessage, ERROR_MSG_MAX_LENGTH); 308 } 309 310 public String getEstimatedTimeRemaining() { 311 return myEstimatedTimeRemaining; 312 } 313 314 public void setEstimatedTimeRemaining(String theEstimatedTimeRemaining) { 315 myEstimatedTimeRemaining = left(theEstimatedTimeRemaining, TIME_REMAINING_LENGTH); 316 } 317 318 public String getReport() { 319 return myReportVc != null ? myReportVc : myReport; 320 } 321 322 public void setReport(String theReport) { 323 myReportVc = theReport; 324 myReport = null; 325 } 326 327 public String getWarningMessages() { 328 return myWarningMessages; 329 } 330 331 public void setWarningMessages(String theWarningMessages) { 332 myWarningMessages = theWarningMessages; 333 } 334 335 public String getTriggeringUsername() { 336 return myTriggeringUsername; 337 } 338 339 public Batch2JobInstanceEntity setTriggeringUsername(String theTriggeringUsername) { 340 myTriggeringUsername = theTriggeringUsername; 341 return this; 342 } 343 344 public String getTriggeringClientId() { 345 return myTriggeringClientId; 346 } 347 348 public Batch2JobInstanceEntity setTriggeringClientId(String theTriggeringClientId) { 349 myTriggeringClientId = theTriggeringClientId; 350 return this; 351 } 352 353 @Override 354 public String toString() { 355 return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) 356 .append("id", myId) 357 .append("definitionId", myDefinitionId) 358 .append("definitionVersion", myDefinitionVersion) 359 .append("errorCount", myErrorCount) 360 .append("createTime", myCreateTime) 361 .append("startTime", myStartTime) 362 .append("endTime", myEndTime) 363 .append("updateTime", myUpdateTime) 364 .append("status", myStatus) 365 .append("cancelled", myCancelled) 366 .append("combinedRecordsProcessed", myCombinedRecordsProcessed) 367 .append("combinedRecordsProcessedPerSecond", myCombinedRecordsProcessedPerSecond) 368 .append("totalElapsedMillis", myTotalElapsedMillis) 369 .append("workChunksPurged", myWorkChunksPurged) 370 .append("progress", myProgress) 371 .append("errorMessage", myErrorMessage) 372 .append("estimatedTimeRemaining", myEstimatedTimeRemaining) 373 .append("report", getReport()) 374 .append("warningMessages", myWarningMessages) 375 .append("initiatingUsername", myTriggeringUsername) 376 .append("initiatingclientId", myTriggeringClientId) 377 .toString(); 378 } 379 380 /** 381 * @return true if every step of the job has produced exactly 1 chunk. 382 */ 383 public boolean isFastTracking() { 384 if (myFastTracking == null) { 385 myFastTracking = false; 386 } 387 return myFastTracking; 388 } 389 390 public void setFastTracking(boolean theFastTracking) { 391 myFastTracking = theFastTracking; 392 } 393}