001/*-
002 * #%L
003 * HAPI FHIR JPA Server
004 * %%
005 * Copyright (C) 2014 - 2023 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 org.apache.commons.lang3.builder.ToStringBuilder;
025import org.apache.commons.lang3.builder.ToStringStyle;
026
027import java.io.Serializable;
028import java.util.Date;
029import javax.persistence.Basic;
030import javax.persistence.Column;
031import javax.persistence.Entity;
032import javax.persistence.EnumType;
033import javax.persistence.Enumerated;
034import javax.persistence.FetchType;
035import javax.persistence.Id;
036import javax.persistence.Index;
037import javax.persistence.Lob;
038import javax.persistence.Table;
039import javax.persistence.Temporal;
040import javax.persistence.TemporalType;
041import javax.persistence.Version;
042
043import static ca.uhn.fhir.batch2.model.JobDefinition.ID_MAX_LENGTH;
044import static ca.uhn.fhir.jpa.entity.Batch2WorkChunkEntity.ERROR_MSG_MAX_LENGTH;
045import static ca.uhn.fhir.jpa.entity.Batch2WorkChunkEntity.WARNING_MSG_MAX_LENGTH;
046import static org.apache.commons.lang3.StringUtils.left;
047
048@Entity
049@Table(
050                name = "BT2_JOB_INSTANCE",
051                indexes = {@Index(name = "IDX_BT2JI_CT", columnList = "CREATE_TIME")})
052public class Batch2JobInstanceEntity implements Serializable {
053
054        public static final int STATUS_MAX_LENGTH = 20;
055        public static final int TIME_REMAINING_LENGTH = 100;
056        public static final int PARAMS_JSON_MAX_LENGTH = 2000;
057        private static final long serialVersionUID = 8187134261799095422L;
058
059        @Id
060        @Column(name = "ID", length = JobDefinition.ID_MAX_LENGTH, nullable = false)
061        private String myId;
062
063        @Column(name = "CREATE_TIME", nullable = false)
064        @Temporal(TemporalType.TIMESTAMP)
065        private Date myCreateTime;
066
067        @Column(name = "START_TIME", nullable = true)
068        @Temporal(TemporalType.TIMESTAMP)
069        private Date myStartTime;
070
071        @Column(name = "END_TIME", nullable = true)
072        @Temporal(TemporalType.TIMESTAMP)
073        private Date myEndTime;
074
075        @Version
076        @Column(name = "UPDATE_TIME", nullable = true)
077        @Temporal(TemporalType.TIMESTAMP)
078        private Date myUpdateTime;
079
080        @Column(name = "DEFINITION_ID", length = JobDefinition.ID_MAX_LENGTH, nullable = false)
081        private String myDefinitionId;
082
083        @Column(name = "DEFINITION_VER", nullable = false)
084        private int myDefinitionVersion;
085
086        @Column(name = "STAT", length = STATUS_MAX_LENGTH, nullable = false)
087        @Enumerated(EnumType.STRING)
088        private StatusEnum myStatus;
089
090        @Column(name = "JOB_CANCELLED", nullable = false)
091        private boolean myCancelled;
092
093        @Column(name = "FAST_TRACKING", nullable = true)
094        private Boolean myFastTracking;
095
096        @Column(name = "PARAMS_JSON", length = PARAMS_JSON_MAX_LENGTH, nullable = true)
097        private String myParamsJson;
098
099        @Lob
100        @Column(name = "PARAMS_JSON_LOB", nullable = true)
101        private String myParamsJsonLob;
102
103        @Column(name = "CMB_RECS_PROCESSED", nullable = true)
104        private Integer myCombinedRecordsProcessed;
105
106        @Column(name = "CMB_RECS_PER_SEC", nullable = true)
107        private Double myCombinedRecordsProcessedPerSecond;
108
109        @Column(name = "TOT_ELAPSED_MILLIS", nullable = true)
110        private Integer myTotalElapsedMillis;
111
112        @Column(name = "WORK_CHUNKS_PURGED", nullable = false)
113        private boolean myWorkChunksPurged;
114
115        @Column(name = "PROGRESS_PCT")
116        private double myProgress;
117
118        @Column(name = "ERROR_MSG", length = ERROR_MSG_MAX_LENGTH, nullable = true)
119        private String myErrorMessage;
120
121        @Column(name = "ERROR_COUNT")
122        private int myErrorCount;
123
124        @Column(name = "EST_REMAINING", length = TIME_REMAINING_LENGTH, nullable = true)
125        private String myEstimatedTimeRemaining;
126
127        @Column(name = "CUR_GATED_STEP_ID", length = ID_MAX_LENGTH, nullable = true)
128        private String myCurrentGatedStepId;
129
130        @Column(name = "WARNING_MSG", length = WARNING_MSG_MAX_LENGTH, nullable = true)
131        private String myWarningMessages;
132
133        /**
134         * Any output from the job can be held in this column
135         * Even serialized json
136         */
137        @Lob
138        @Basic(fetch = FetchType.LAZY)
139        @Column(name = "REPORT", nullable = true, length = Integer.MAX_VALUE - 1)
140        private String myReport;
141
142        public String getCurrentGatedStepId() {
143                return myCurrentGatedStepId;
144        }
145
146        public void setCurrentGatedStepId(String theCurrentGatedStepId) {
147                myCurrentGatedStepId = theCurrentGatedStepId;
148        }
149
150        public boolean isCancelled() {
151                return myCancelled;
152        }
153
154        public void setCancelled(boolean theCancelled) {
155                myCancelled = theCancelled;
156        }
157
158        public int getErrorCount() {
159                return myErrorCount;
160        }
161
162        public void setErrorCount(int theErrorCount) {
163                myErrorCount = theErrorCount;
164        }
165
166        public Integer getTotalElapsedMillis() {
167                return myTotalElapsedMillis;
168        }
169
170        public void setTotalElapsedMillis(Integer theTotalElapsedMillis) {
171                myTotalElapsedMillis = theTotalElapsedMillis;
172        }
173
174        public Integer getCombinedRecordsProcessed() {
175                return myCombinedRecordsProcessed;
176        }
177
178        public void setCombinedRecordsProcessed(Integer theCombinedRecordsProcessed) {
179                myCombinedRecordsProcessed = theCombinedRecordsProcessed;
180        }
181
182        public Double getCombinedRecordsProcessedPerSecond() {
183                return myCombinedRecordsProcessedPerSecond;
184        }
185
186        public void setCombinedRecordsProcessedPerSecond(Double theCombinedRecordsProcessedPerSecond) {
187                myCombinedRecordsProcessedPerSecond = theCombinedRecordsProcessedPerSecond;
188        }
189
190        public Date getCreateTime() {
191                return myCreateTime;
192        }
193
194        public void setCreateTime(Date theCreateTime) {
195                myCreateTime = theCreateTime;
196        }
197
198        public Date getStartTime() {
199                return myStartTime;
200        }
201
202        public void setStartTime(Date theStartTime) {
203                myStartTime = theStartTime;
204        }
205
206        public Date getEndTime() {
207                return myEndTime;
208        }
209
210        public void setEndTime(Date theEndTime) {
211                myEndTime = theEndTime;
212        }
213
214        public void setUpdateTime(Date theTime) {
215                myUpdateTime = theTime;
216        }
217
218        public Date getUpdateTime() {
219                return myUpdateTime;
220        }
221
222        public String getId() {
223                return myId;
224        }
225
226        public void setId(String theId) {
227                myId = theId;
228        }
229
230        public String getDefinitionId() {
231                return myDefinitionId;
232        }
233
234        public void setDefinitionId(String theDefinitionId) {
235                myDefinitionId = theDefinitionId;
236        }
237
238        public int getDefinitionVersion() {
239                return myDefinitionVersion;
240        }
241
242        public void setDefinitionVersion(int theDefinitionVersion) {
243                myDefinitionVersion = theDefinitionVersion;
244        }
245
246        public StatusEnum getStatus() {
247                return myStatus;
248        }
249
250        public void setStatus(StatusEnum theStatus) {
251                myStatus = theStatus;
252        }
253
254        public String getParams() {
255                if (myParamsJsonLob != null) {
256                        return myParamsJsonLob;
257                }
258                return myParamsJson;
259        }
260
261        public void setParams(String theParams) {
262                myParamsJsonLob = null;
263                myParamsJson = null;
264                if (theParams != null && theParams.length() > PARAMS_JSON_MAX_LENGTH) {
265                        myParamsJsonLob = theParams;
266                } else {
267                        myParamsJson = theParams;
268                }
269        }
270
271        public boolean getWorkChunksPurged() {
272                return myWorkChunksPurged;
273        }
274
275        public void setWorkChunksPurged(boolean theWorkChunksPurged) {
276                myWorkChunksPurged = theWorkChunksPurged;
277        }
278
279        public double getProgress() {
280                return myProgress;
281        }
282
283        public void setProgress(double theProgress) {
284                myProgress = theProgress;
285        }
286
287        public String getErrorMessage() {
288                return myErrorMessage;
289        }
290
291        public void setErrorMessage(String theErrorMessage) {
292                myErrorMessage = left(theErrorMessage, ERROR_MSG_MAX_LENGTH);
293        }
294
295        public String getEstimatedTimeRemaining() {
296                return myEstimatedTimeRemaining;
297        }
298
299        public void setEstimatedTimeRemaining(String theEstimatedTimeRemaining) {
300                myEstimatedTimeRemaining = left(theEstimatedTimeRemaining, TIME_REMAINING_LENGTH);
301        }
302
303        public String getReport() {
304                return myReport;
305        }
306
307        public void setReport(String theReport) {
308                myReport = theReport;
309        }
310
311        public String getWarningMessages() {
312                return myWarningMessages;
313        }
314
315        public void setWarningMessages(String theWarningMessages) {
316                myWarningMessages = theWarningMessages;
317        }
318
319        @Override
320        public String toString() {
321                return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
322                                .append("id", myId)
323                                .append("definitionId", myDefinitionId)
324                                .append("definitionVersion", myDefinitionVersion)
325                                .append("errorCount", myErrorCount)
326                                .append("createTime", myCreateTime)
327                                .append("startTime", myStartTime)
328                                .append("endTime", myEndTime)
329                                .append("updateTime", myUpdateTime)
330                                .append("status", myStatus)
331                                .append("cancelled", myCancelled)
332                                .append("combinedRecordsProcessed", myCombinedRecordsProcessed)
333                                .append("combinedRecordsProcessedPerSecond", myCombinedRecordsProcessedPerSecond)
334                                .append("totalElapsedMillis", myTotalElapsedMillis)
335                                .append("workChunksPurged", myWorkChunksPurged)
336                                .append("progress", myProgress)
337                                .append("errorMessage", myErrorMessage)
338                                .append("estimatedTimeRemaining", myEstimatedTimeRemaining)
339                                .append("report", myReport)
340                                .append("warningMessages", myWarningMessages)
341                                .toString();
342        }
343
344        /**
345         * @return true if every step of the job has produced exactly 1 chunk.
346         */
347        public boolean isFastTracking() {
348                if (myFastTracking == null) {
349                        myFastTracking = false;
350                }
351                return myFastTracking;
352        }
353
354        public void setFastTracking(boolean theFastTracking) {
355                myFastTracking = theFastTracking;
356        }
357}