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}