package com.hujiang.juice.rest.utils;
import com.google.gson.Gson;
import com.hujiang.jooq.juice.tables.pojos.JuiceTask;
import com.hujiang.juice.common.error.ErrorCode;
import com.hujiang.juice.common.exception.CacheException;
import com.hujiang.juice.common.exception.DataBaseException;
import com.hujiang.juice.common.exception.RestException;
import com.hujiang.juice.common.utils.cache.CacheUtils;
import com.hujiang.juice.common.utils.db.DaoUtils;
import com.hujiang.juice.common.utils.rest.Restty;
import com.hujiang.juice.common.vo.TaskResult;
import com.hujiang.juice.rest.config.CachesBizConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Created by xujia on 16/12/8.
*/
@Slf4j
public class SubscriberUtils {
@Autowired
private DaoUtils daoUtils;
@Autowired
private CacheUtils cacheUtils;
@Autowired
private CachesBizConfig cachesBizConfig;
private ExecutorService fixedThreadPool;
private Gson gson = new Gson();
public SubscriberUtils() {
fixedThreadPool = Executors.newFixedThreadPool(10);
log.info("init SubscriberUtils success!");
}
public void handleResult() {
while (true) {
TaskResult taskResult = getTaskResult();
if (null == taskResult) {
break;
}
log.debug("taskResult : " + taskResult.toString());
fixedThreadPool.execute(() -> {
String callbackUrl = "";
try {
JuiceTask task = daoUtils.queryTask(taskResult.getTaskId());
if(null != task) {
callbackUrl = task.getCallbackUrl();
if(StringUtils.isNotBlank(callbackUrl)) {
boolean isUpdate;
if (taskResult.getResult().getType() > TaskResult.Result.RUNNING.getType()) {
isUpdate = daoUtils.finishTaskWithCallBack(taskResult.getTaskId(), taskResult.getResult().getType(), taskResult.getMessage());
} else {
isUpdate = daoUtils.updateTask(taskResult.getTaskId(), taskResult.getResult().getType(), taskResult.getMessage());
}
if(isUpdate) {
log.debug("url --> " + callbackUrl);
log.debug("taskResult --> " + gson.toJson(taskResult));
Restty.create(task.getCallbackUrl())
.addHeader("X-Tenant-ID", task.getTenantId())
.addMediaType(Restty.jsonBody())
.requestBody(taskResult)
.postNoResponse();
}
} else {
log.debug("not call back due to url is null, taskId : " + task.getTaskId());
if(taskResult.getResult().getType() > TaskResult.Result.RUNNING.getType()) {
daoUtils.finishTask(taskResult.getTaskId(), taskResult.getResult().getType(), taskResult.getMessage());
} else {
daoUtils.updateTask(taskResult.getTaskId(), taskResult.getResult().getType(), taskResult.getMessage());
}
}
} else {
log.warn("scheduler service --> task : " + taskResult.getTaskId() + " not exist, can't update task status");
}
} catch (Exception ex) {
if (ex instanceof DataBaseException) {
log.error("db operating error, cause : " + ex);
log.error("notice & check, taskResult : " + taskResult.toString());
} else if (ex instanceof IOException) {
log.error("call back failed, url : " + callbackUrl);
throw new RestException(ErrorCode.HTTP_REQUEST_ERROR.getCode(), ex.getMessage());
} else {
log.warn("handle subscriber error, : " + ex);
}
try {
throw ex;
} catch (IOException ex1) {
ex1.printStackTrace();
}
}
});
}
}
private TaskResult getTaskResult() {
String message = "";
try {
message = cacheUtils.popFromQueue(cachesBizConfig.getResultQueue());
if (StringUtils.isBlank(message)) {
return null;
}
log.debug(String.format("Message: %s", message));
return gson.fromJson(message, TaskResult.class);
} catch (Exception e) {
if (e instanceof CacheException) {
log.warn("get message from cache exception!");
try {
Thread.sleep(10 * 1000L);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
} else {
log.warn("serialize TaskResult error, message : " + message);
}
return null;
}
}
}