/* * Copyright 2016-2018 the original author or authors. * * Licensed 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 com.creactiviti.piper.core.task; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Collections; import java.util.List; import java.util.Map; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.transaction.annotation.Transactional; import com.creactiviti.piper.core.json.Json; import com.fasterxml.jackson.databind.ObjectMapper; public class JdbcTaskExecutionRepository implements TaskExecutionRepository { private NamedParameterJdbcOperations jdbc; private ObjectMapper json = new ObjectMapper(); @Override public TaskExecution findOne (String aTaskExecutionId) { List<TaskExecution> query = jdbc.query("select * from task_execution where id = :id", Collections.singletonMap("id", aTaskExecutionId),this::jobTaskRowMappper); if(query.size() == 1) { return query.get(0); } return null; } @Override public List<TaskExecution> findByParentId(String aParentId) { return jdbc.query("select * from task_execution where parent_id = :parentId order by task_number", Collections.singletonMap("parentId", aParentId),this::jobTaskRowMappper); } @Override public void create (TaskExecution aTaskExecution) { SqlParameterSource sqlParameterSource = createSqlParameterSource(aTaskExecution); String sql = "insert into task_execution " + " (id,parent_id,job_id,serialized_execution,status,progress,create_time,priority,task_number) " + "values " + " (:id,:parentId,:jobId,(:serializedExecution)::jsonb,:status,:progress,:createTime,:priority,:taskNumber)"; jdbc.update(sql, sqlParameterSource); } @Override @Transactional public TaskExecution merge (TaskExecution aTaskExecution) { TaskExecution current = jdbc.queryForObject("select * from task_execution where id = :id for update", Collections.singletonMap("id", aTaskExecution.getId()),this::jobTaskRowMappper); SimpleTaskExecution merged = SimpleTaskExecution.of(aTaskExecution); if(current.getStatus().isTerminated() && aTaskExecution.getStatus() == TaskStatus.STARTED) { merged = SimpleTaskExecution.of(current); merged.setStartTime(aTaskExecution.getStartTime()); } else if (aTaskExecution.getStatus().isTerminated() && current.getStatus() == TaskStatus.STARTED) { merged.setStartTime(current.getStartTime()); } SqlParameterSource sqlParameterSource = createSqlParameterSource(merged); String sql = "update task_execution set " + " serialized_execution=(:serializedExecution)::jsonb,status=:status,progress=:progress,start_time=:startTime,end_time=:endTime where id = :id "; jdbc.update(sql, sqlParameterSource); return merged; } @Override public List<TaskExecution> getExecution (String aJobId) { return jdbc.query("select * From task_execution where job_id = :jobId order by create_time asc", Collections.singletonMap("jobId", aJobId),this::jobTaskRowMappper); } @SuppressWarnings("unchecked") private TaskExecution jobTaskRowMappper (ResultSet aRs, int aIndex) throws SQLException { return SimpleTaskExecution.of(Json.deserialize(json, aRs.getString("serialized_execution"), Map.class)); } private SqlParameterSource createSqlParameterSource (TaskExecution aTaskExecution) { MapSqlParameterSource sqlParameterSource = new MapSqlParameterSource(); sqlParameterSource.addValue("id", aTaskExecution.getId()); sqlParameterSource.addValue("parentId", aTaskExecution.getParentId()); sqlParameterSource.addValue("jobId", aTaskExecution.getJobId()); sqlParameterSource.addValue("status", aTaskExecution.getStatus().toString()); sqlParameterSource.addValue("progress", aTaskExecution.getProgress()); sqlParameterSource.addValue("createTime", aTaskExecution.getCreateTime()); sqlParameterSource.addValue("startTime", aTaskExecution.getStartTime()); sqlParameterSource.addValue("endTime", aTaskExecution.getEndTime()); sqlParameterSource.addValue("serializedExecution", Json.serialize(json, aTaskExecution)); sqlParameterSource.addValue("priority", aTaskExecution.getPriority()); sqlParameterSource.addValue("taskNumber", aTaskExecution.getTaskNumber()); return sqlParameterSource; } public void setJdbcOperations (NamedParameterJdbcOperations aJdbcOperations) { jdbc = aJdbcOperations; } public void setObjectMapper (ObjectMapper aJson) { json = aJson; } }