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.WorkChunk; 023import ca.uhn.fhir.batch2.model.WorkChunkStatusEnum; 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.ForeignKey; 031import jakarta.persistence.Id; 032import jakarta.persistence.Index; 033import jakarta.persistence.JoinColumn; 034import jakarta.persistence.Lob; 035import jakarta.persistence.ManyToOne; 036import jakarta.persistence.Table; 037import jakarta.persistence.Temporal; 038import jakarta.persistence.TemporalType; 039import jakarta.persistence.Version; 040import org.apache.commons.lang3.builder.ToStringBuilder; 041import org.apache.commons.lang3.builder.ToStringStyle; 042import org.hibernate.Length; 043 044import java.io.Serializable; 045import java.util.Date; 046 047import static ca.uhn.fhir.batch2.model.JobDefinition.ID_MAX_LENGTH; 048import static ca.uhn.fhir.jpa.entity.Batch2JobInstanceEntity.STATUS_MAX_LENGTH; 049import static org.apache.commons.lang3.StringUtils.left; 050 051@Entity 052@Table( 053 name = "BT2_WORK_CHUNK", 054 indexes = { 055 @Index(name = "IDX_BT2WC_II_SEQ", columnList = "INSTANCE_ID,SEQ"), 056 @Index(name = "IDX_BT2WC_II_SI_S_SEQ_ID", columnList = "INSTANCE_ID,TGT_STEP_ID,STAT,SEQ,ID") 057 }) 058public class Batch2WorkChunkEntity implements Serializable { 059 060 public static final int ERROR_MSG_MAX_LENGTH = 500; 061 public static final int WARNING_MSG_MAX_LENGTH = 4000; 062 private static final long serialVersionUID = -6202771941965780558L; 063 064 @Id 065 @Column(name = "ID", length = ID_MAX_LENGTH) 066 private String myId; 067 068 @Column(name = "SEQ", nullable = false) 069 private int mySequence; 070 071 @Column(name = "CREATE_TIME", nullable = false) 072 @Temporal(TemporalType.TIMESTAMP) 073 private Date myCreateTime; 074 075 @Column(name = "START_TIME", nullable = true) 076 @Temporal(TemporalType.TIMESTAMP) 077 private Date myStartTime; 078 079 @Column(name = "END_TIME", nullable = true) 080 @Temporal(TemporalType.TIMESTAMP) 081 private Date myEndTime; 082 083 @Version 084 @Column(name = "UPDATE_TIME", nullable = true) 085 @Temporal(TemporalType.TIMESTAMP) 086 private Date myUpdateTime; 087 088 @Column(name = "RECORDS_PROCESSED", nullable = true) 089 private Integer myRecordsProcessed; 090 091 @Column(name = "DEFINITION_ID", length = ID_MAX_LENGTH, nullable = false) 092 private String myJobDefinitionId; 093 094 @Column(name = "DEFINITION_VER", length = ID_MAX_LENGTH, nullable = false) 095 private int myJobDefinitionVersion; 096 097 @Column(name = "TGT_STEP_ID", length = ID_MAX_LENGTH, nullable = false) 098 private String myTargetStepId; 099 100 @Lob // TODO: VC column added in 7.2.0 - Remove non-VC column later 101 @Basic(fetch = FetchType.LAZY) 102 @Column(name = "CHUNK_DATA", nullable = true, length = Integer.MAX_VALUE - 1) 103 private String mySerializedData; 104 105 @Column(name = "CHUNK_DATA_VC", nullable = true, length = Length.LONG32) 106 private String mySerializedDataVc; 107 108 @Column(name = "STAT", length = STATUS_MAX_LENGTH, nullable = false) 109 @Enumerated(EnumType.STRING) 110 private WorkChunkStatusEnum myStatus; 111 112 @ManyToOne(fetch = FetchType.LAZY) 113 @JoinColumn( 114 name = "INSTANCE_ID", 115 insertable = false, 116 updatable = false, 117 foreignKey = @ForeignKey(name = "FK_BT2WC_INSTANCE")) 118 private Batch2JobInstanceEntity myInstance; 119 120 @Column(name = "INSTANCE_ID", length = ID_MAX_LENGTH, nullable = false) 121 private String myInstanceId; 122 123 @Column(name = "ERROR_MSG", length = ERROR_MSG_MAX_LENGTH, nullable = true) 124 private String myErrorMessage; 125 126 @Column(name = "ERROR_COUNT", nullable = false) 127 private int myErrorCount; 128 129 @Column(name = "WARNING_MSG", length = WARNING_MSG_MAX_LENGTH, nullable = true) 130 private String myWarningMessage; 131 132 /** 133 * The next time the work chunk can attempt to rerun its work step. 134 */ 135 @Column(name = "NEXT_POLL_TIME", nullable = true) 136 @Temporal(TemporalType.TIMESTAMP) 137 private Date myNextPollTime; 138 139 /** 140 * The number of times the work chunk has had its state set back to POLL_WAITING. 141 */ 142 @Column(name = "POLL_ATTEMPTS", nullable = true) 143 private int myPollAttempts; 144 145 /** 146 * Default constructor for Hibernate. 147 */ 148 public Batch2WorkChunkEntity() {} 149 150 /** 151 * Projection constructor for no-data path. 152 */ 153 public Batch2WorkChunkEntity( 154 String theId, 155 int theSequence, 156 String theJobDefinitionId, 157 int theJobDefinitionVersion, 158 String theInstanceId, 159 String theTargetStepId, 160 WorkChunkStatusEnum theStatus, 161 Date theCreateTime, 162 Date theStartTime, 163 Date theUpdateTime, 164 Date theEndTime, 165 String theErrorMessage, 166 int theErrorCount, 167 Integer theRecordsProcessed, 168 String theWarningMessage, 169 Date theNextPollTime, 170 Integer thePollAttempts) { 171 myId = theId; 172 mySequence = theSequence; 173 myJobDefinitionId = theJobDefinitionId; 174 myJobDefinitionVersion = theJobDefinitionVersion; 175 myInstanceId = theInstanceId; 176 myTargetStepId = theTargetStepId; 177 myStatus = theStatus; 178 myCreateTime = theCreateTime; 179 myStartTime = theStartTime; 180 myUpdateTime = theUpdateTime; 181 myEndTime = theEndTime; 182 myErrorMessage = theErrorMessage; 183 myErrorCount = theErrorCount; 184 myRecordsProcessed = theRecordsProcessed; 185 myWarningMessage = theWarningMessage; 186 myNextPollTime = theNextPollTime; 187 myPollAttempts = thePollAttempts; 188 } 189 190 public static Batch2WorkChunkEntity fromWorkChunk(WorkChunk theWorkChunk) { 191 Batch2WorkChunkEntity entity = new Batch2WorkChunkEntity( 192 theWorkChunk.getId(), 193 theWorkChunk.getSequence(), 194 theWorkChunk.getJobDefinitionId(), 195 theWorkChunk.getJobDefinitionVersion(), 196 theWorkChunk.getInstanceId(), 197 theWorkChunk.getTargetStepId(), 198 theWorkChunk.getStatus(), 199 theWorkChunk.getCreateTime(), 200 theWorkChunk.getStartTime(), 201 theWorkChunk.getUpdateTime(), 202 theWorkChunk.getEndTime(), 203 theWorkChunk.getErrorMessage(), 204 theWorkChunk.getErrorCount(), 205 theWorkChunk.getRecordsProcessed(), 206 theWorkChunk.getWarningMessage(), 207 theWorkChunk.getNextPollTime(), 208 theWorkChunk.getPollAttempts()); 209 entity.setSerializedData(theWorkChunk.getData()); 210 211 return entity; 212 } 213 214 public int getErrorCount() { 215 return myErrorCount; 216 } 217 218 public void setErrorCount(int theErrorCount) { 219 myErrorCount = theErrorCount; 220 } 221 222 public String getErrorMessage() { 223 return myErrorMessage; 224 } 225 226 public void setErrorMessage(String theErrorMessage) { 227 myErrorMessage = left(theErrorMessage, ERROR_MSG_MAX_LENGTH); 228 } 229 230 public String getWarningMessage() { 231 return myWarningMessage; 232 } 233 234 public void setWarningMessage(String theWarningMessage) { 235 myWarningMessage = theWarningMessage; 236 } 237 238 public int getSequence() { 239 return mySequence; 240 } 241 242 public void setSequence(int theSequence) { 243 mySequence = theSequence; 244 } 245 246 public Date getCreateTime() { 247 return myCreateTime; 248 } 249 250 public void setCreateTime(Date theCreateTime) { 251 myCreateTime = theCreateTime; 252 } 253 254 public Date getStartTime() { 255 return myStartTime; 256 } 257 258 public void setStartTime(Date theStartTime) { 259 myStartTime = theStartTime; 260 } 261 262 public Date getEndTime() { 263 return myEndTime; 264 } 265 266 public void setEndTime(Date theEndTime) { 267 myEndTime = theEndTime; 268 } 269 270 public Date getUpdateTime() { 271 return myUpdateTime; 272 } 273 274 public Integer getRecordsProcessed() { 275 return myRecordsProcessed; 276 } 277 278 public void setRecordsProcessed(Integer theRecordsProcessed) { 279 myRecordsProcessed = theRecordsProcessed; 280 } 281 282 public Batch2JobInstanceEntity getInstance() { 283 return myInstance; 284 } 285 286 public void setInstance(Batch2JobInstanceEntity theInstance) { 287 myInstance = theInstance; 288 } 289 290 public String getJobDefinitionId() { 291 return myJobDefinitionId; 292 } 293 294 public void setJobDefinitionId(String theJobDefinitionId) { 295 myJobDefinitionId = theJobDefinitionId; 296 } 297 298 public int getJobDefinitionVersion() { 299 return myJobDefinitionVersion; 300 } 301 302 public void setJobDefinitionVersion(int theJobDefinitionVersion) { 303 myJobDefinitionVersion = theJobDefinitionVersion; 304 } 305 306 public String getTargetStepId() { 307 return myTargetStepId; 308 } 309 310 public void setTargetStepId(String theTargetStepId) { 311 myTargetStepId = theTargetStepId; 312 } 313 314 public String getSerializedData() { 315 return mySerializedDataVc != null ? mySerializedDataVc : mySerializedData; 316 } 317 318 public void setSerializedData(String theSerializedData) { 319 mySerializedData = null; 320 mySerializedDataVc = theSerializedData; 321 } 322 323 public WorkChunkStatusEnum getStatus() { 324 return myStatus; 325 } 326 327 public void setStatus(WorkChunkStatusEnum theStatus) { 328 myStatus = theStatus; 329 } 330 331 public String getId() { 332 return myId; 333 } 334 335 public void setId(String theId) { 336 myId = theId; 337 } 338 339 public String getInstanceId() { 340 return myInstanceId; 341 } 342 343 public void setInstanceId(String theInstanceId) { 344 myInstanceId = theInstanceId; 345 } 346 347 public Date getNextPollTime() { 348 return myNextPollTime; 349 } 350 351 public void setNextPollTime(Date theNextPollTime) { 352 myNextPollTime = theNextPollTime; 353 } 354 355 public int getPollAttempts() { 356 return myPollAttempts; 357 } 358 359 public void setPollAttempts(int thePollAttempts) { 360 myPollAttempts = thePollAttempts; 361 } 362 363 @Override 364 public String toString() { 365 return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) 366 .append("id", myId) 367 .append("instanceId", myInstanceId) 368 .append("sequence", mySequence) 369 .append("errorCount", myErrorCount) 370 .append("jobDefinitionId", myJobDefinitionId) 371 .append("jobDefinitionVersion", myJobDefinitionVersion) 372 .append("createTime", myCreateTime) 373 .append("startTime", myStartTime) 374 .append("endTime", myEndTime) 375 .append("updateTime", myUpdateTime) 376 .append("recordsProcessed", myRecordsProcessed) 377 .append("targetStepId", myTargetStepId) 378 .append("serializedData", getSerializedData()) 379 .append("status", myStatus) 380 .append("errorMessage", myErrorMessage) 381 .append("warningMessage", myWarningMessage) 382 .append("nextPollTime", myNextPollTime) 383 .append("pollAttempts", myPollAttempts) 384 .toString(); 385 } 386}