org.dromara.jpom.func.openapi.controller.BuildTriggerApiController Maven / Gradle / Ivy
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Code Technology Studio
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.dromara.jpom.func.openapi.controller;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.SystemClock;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.RegexPool;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.map.SafeConcurrentHashMap;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.ContentType;
import cn.keepbx.jpom.IJsonMessage;
import cn.keepbx.jpom.event.IAsyncLoad;
import cn.keepbx.jpom.model.JsonMessage;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.dromara.jpom.JpomApplication;
import org.dromara.jpom.build.BuildExecuteService;
import org.dromara.jpom.build.BuildUtil;
import org.dromara.jpom.build.ResultDirFileAction;
import org.dromara.jpom.common.BaseJpomController;
import org.dromara.jpom.common.BaseServerController;
import org.dromara.jpom.common.ServerOpenApi;
import org.dromara.jpom.common.interceptor.NotLogin;
import org.dromara.jpom.common.validator.ValidatorItem;
import org.dromara.jpom.common.validator.ValidatorRule;
import org.dromara.jpom.cron.CronUtils;
import org.dromara.jpom.model.BaseEnum;
import org.dromara.jpom.model.data.BuildInfoModel;
import org.dromara.jpom.model.enums.BuildStatus;
import org.dromara.jpom.model.user.UserModel;
import org.dromara.jpom.service.dblog.BuildInfoService;
import org.dromara.jpom.service.user.TriggerTokenLogServer;
import org.dromara.jpom.system.JpomRuntimeException;
import org.springframework.http.MediaType;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* @author bwcx_jzy
* @since 2019/9/4
*/
@RestController
@NotLogin
@Slf4j
public class BuildTriggerApiController extends BaseJpomController implements IAsyncLoad, Runnable {
private final BuildInfoService buildInfoService;
private final BuildExecuteService buildExecuteService;
private final TriggerTokenLogServer triggerTokenLogServer;
/**
* 等待执行构建的队列
*/
private final Map> waitQueue = new SafeConcurrentHashMap<>();
public BuildTriggerApiController(BuildInfoService buildInfoService,
BuildExecuteService buildExecuteService,
TriggerTokenLogServer triggerTokenLogServer) {
this.buildInfoService = buildInfoService;
this.buildExecuteService = buildExecuteService;
this.triggerTokenLogServer = triggerTokenLogServer;
}
private Object[] buildParametersEnv(HttpServletRequest request, String body) {
String contentType = request.getContentType();
Object[] parametersEnv = new Object[4];
parametersEnv[0] = "triggerContentType";
parametersEnv[1] = contentType;
parametersEnv[2] = "triggerBodyData";
if (ContentType.isDefault(contentType)) {
Map paramMap = ServletUtil.getParamMap(request);
parametersEnv[3] = JSONObject.toJSONString(paramMap);
} else {
// github issues 48
parametersEnv[3] = body == null ? ServletUtil.getBody(request) : body;
}
return parametersEnv;
}
/**
* 构建触发器
*
* @param id 构建ID
* @param token 构建的token
* @param delay 延迟时间(单位秒)
* @return json
*/
@RequestMapping(value = ServerOpenApi.BUILD_TRIGGER_BUILD2, produces = MediaType.APPLICATION_JSON_VALUE)
public IJsonMessage trigger2(@PathVariable String id, @PathVariable String token,
HttpServletRequest request,
String delay,
String buildRemark, String useQueue) {
BuildInfoModel item = buildInfoService.getByKey(id);
Assert.notNull(item, "没有对应数据");
UserModel userModel = this.triggerTokenLogServer.getUserByToken(token, buildInfoService.typeName());
//
Assert.notNull(userModel, "触发token错误,或者已经失效:-1");
Assert.state(StrUtil.equals(token, item.getTriggerToken()), "触发token错误,或者已经失效");
// 构建外部参数
Object[] parametersEnv = this.buildParametersEnv(request, null);
Integer delay1 = Convert.toInt(delay, 0);
if (Convert.toBool(useQueue, false)) {
// 提交到队列暂存
BuildCache buildCache = new BuildCache();
buildCache.setId(id);
buildCache.setUserModel(userModel);
buildCache.setDelay(delay1);
buildCache.setBuildRemark(buildRemark);
buildCache.setParametersEnv(parametersEnv);
//
Queue buildCaches = waitQueue.computeIfAbsent(id, s -> new ConcurrentLinkedDeque<>());
buildCaches.add(buildCache);
return JsonMessage.success("提交任务队列成功,当前队列数:" + buildCaches.size());
}
BaseServerController.resetInfo(userModel);
return buildExecuteService.start(id, userModel, delay1, 1, buildRemark, parametersEnv);
}
/**
* 构建触发器
*
* 参数 [
* {
* "id":"1",
* "token":"a",
* "delay":"0"
* }
* ]
*
* 响应 [
* {
* "id":"1",
* "token":"a",
* "delay":"0",
* "msg":"开始构建",
* "data":1
* }
* ]
*
* @return json
*/
@PostMapping(value = ServerOpenApi.BUILD_TRIGGER_BUILD_BATCH, produces = MediaType.APPLICATION_JSON_VALUE)
public IJsonMessage> triggerBatch(HttpServletRequest request) {
String body = ServletUtil.getBody(request);
if (StrUtil.isEmpty(body)) {
return new JsonMessage<>(405, "请传入 body 参数");
}
try {
// 构建外部参数
Object[] parametersEnv = this.buildParametersEnv(request, body);
JSONArray jsonArray = JSONArray.parseArray(body);
List