/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.ode.dao.jpa.scheduler; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Map; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table; import javax.persistence.Transient; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.ode.bpel.common.CorrelationKeySet; import org.apache.ode.bpel.iapi.Scheduler; import org.apache.ode.bpel.iapi.Scheduler.JobDetails; import org.apache.ode.dao.scheduler.JobDAO; /** * @author jeffyu * */ @Entity @Table(name = "ODE_JOB") @NamedQueries ({ @NamedQuery (name = "deleteJobs", query = "DELETE FROM JobDAOImpl AS j WHERE j.jobId = :job AND j.nodeId = :node"), @NamedQuery(name = "nodeIds", query = "SELECT DISTINCT j.nodeId FROM JobDAOImpl AS j WHERE j.nodeId IS NOT NULL"), @NamedQuery(name = "dequeueImmediate", query = "SELECT j FROM JobDAOImpl AS j WHERE j.nodeId = :node AND j.scheduled = false AND j.timestamp < :time ORDER BY j.timestamp"), @NamedQuery(name = "updateScheduled", query = "UPDATE JobDAOImpl AS j SET j.scheduled = true WHERE j.jobId in (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)"), @NamedQuery(name = "updateAssignToNode", query = "UPDATE JobDAOImpl AS j SET j.nodeId = :node WHERE j.nodeId IS NULL AND j.scheduled = false AND mod(j.timestamp,:numNode) = :i AND j.timestamp < :maxTime"), @NamedQuery(name = "updateReassign", query = "UPDATE JobDAOImpl AS j SET j.nodeId = :newNode, j.scheduled = false WHERE j.nodeId = :oldNode") }) public class JobDAOImpl implements JobDAO, Serializable { private static final Log __log = LogFactory.getLog(JobDAOImpl.class); private String _jobId; private long _ts; private String _nodeId; private boolean _scheduled; private boolean _transacted; private boolean _persisted = true; private JobDetails _details = new Scheduler.JobDetails(); @Transient public JobDetails getDetails() { return _details; } @Id @Column(name="jobid", length = 64) public String getJobId() { return _jobId; } public void setJobId(String jobId) { _jobId = jobId; } @Transient public long getScheduledDate() { return getTimestamp(); } public void setScheduledDate(long scheduledDate) { this.setTimestamp(scheduledDate); } @Transient public boolean isPersisted() { return _persisted; } @Column(name = "transacted", nullable=false) public boolean isTransacted() { return _transacted; } @Column(name = "ts", nullable = false) public long getTimestamp() { return _ts; } public void setTimestamp(long ts) { _ts = ts; } @Column(name = "nodeid", length = 64) public String getNodeId() { return _nodeId; } public void setNodeId(String nodeId) { _nodeId = nodeId; } @Column(name = "scheduled", nullable = false) public boolean isScheduled() { return _scheduled; } public void setScheduled(boolean scheduled) { this._scheduled = scheduled; } public void setTransacted(boolean transacted) { this._transacted = transacted; } public void setPersisted(boolean persisted) { this._persisted = persisted; } public void setDetails(JobDetails details) { _details = details; } //JPA JobDetails getters/setters @Column(name = "instanceId") public long getInstanceId() { return _details.instanceId == null ? 0L : _details.instanceId.longValue(); } public void setInstanceId(long instanceId) { _details.instanceId = instanceId; } @Column(name = "mexId") public String getMexId() { return _details.mexId; } public void setMexId(String mexId) { _details.mexId = mexId; } @Column(name = "processId") public String getProcessId() { return _details.processId; } public void setProcessId(String processId) { _details.processId = processId; } @Column(name = "type") public String getType() { return _details.type; } public void setType(String type) { _details.type = type!=null?type:""; } @Column(name = "channel") public String getChannel() { return _details.channel; } public void setChannel(String channel) { _details.channel = channel; } @Column(name = "correlatorId") public String getCorrelatorId() { return _details.correlatorId; } public void setCorrelatorId(String correlatorId) { _details.correlatorId = correlatorId; } @Column(name = "correlationKeySet") public String getCorrelationKeySet() { return _details.getCorrelationKeySet().toCanonicalString(); } public void setCorrelationKeySet(String correlationKey) { _details.setCorrelationKeySet(new CorrelationKeySet(correlationKey)); } @Column(name = "retryCount") public int getRetryCount() { return _details.retryCount == null ? 0 : _details.retryCount.intValue(); } public void setRetryCount(int retryCount) { _details.retryCount = retryCount; } @Column(name = "inMem") public boolean isInMem() { return _details.inMem == null ? false : _details.inMem.booleanValue(); } public void setInMem(boolean inMem) { _details.inMem = inMem; } //should not lazy load, it is possible getDetails() called before this @Lob @Column(name = "detailsExt") public byte[] getDetailsExt() { if (_details.detailsExt != null && _details.detailsExt.size() > 0) { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream os = new ObjectOutputStream(bos); os.writeObject(_details.detailsExt); os.close(); return bos.toByteArray(); } catch (Exception e) { __log.error("Error in getDetailsExt ", e); } } return null; } public void setDetailsExt(byte[] detailsExt) { if (detailsExt != null && detailsExt.length > 0) { try { ByteArrayInputStream bis = new ByteArrayInputStream(detailsExt); ObjectInputStream is = new ObjectInputStream(bis); _details.detailsExt = (Map<String, Object>) is.readObject(); is.close(); } catch (Exception e) { __log.error("Error in setDetailsExt ", e); } } } @Override public String toString() { StringBuilder builder = new StringBuilder(); builder.append("["); builder.append("JobId: " + _jobId); builder.append(",nodeId: " + _nodeId); builder.append(",scheduled: " + _scheduled); builder.append(",transacted: " + _transacted); builder.append(",ts: " + _ts); builder.append(",channel: " + _details.getChannel()); builder.append(",instaceId : " + _details.getInstanceId()); builder.append(",type: " + _details.getType()); builder.append(",retrycount: " + _details.getRetryCount()); builder.append("]"); return builder.toString(); } }