soft升级优化 #1

Closed
wanjia9506 wants to merge 46 commits from master into gitlink
115 changed files with 932 additions and 634 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/target
.idea

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
</set>
</option>
</component>
</project>

39
pom.xml
View File

@ -45,22 +45,13 @@
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
@ -134,27 +125,35 @@
<!-- <scope>test</scope>-->
<!-- </dependency>-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<!-- 重试相关依赖包 -->
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
</dependencies>

View File

@ -3,9 +3,13 @@ package com.gitlink.softbot;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@MapperScan("com.gitlink.softbot.dao")
@EnableAsync
@EnableRetry
public class SoftBotApplication {
public static void main(String[] args) {

View File

@ -0,0 +1,14 @@
package com.gitlink.softbot.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD) // 作用到方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时有效
public @interface NoRepeatSubmit {
}

View File

@ -0,0 +1,21 @@
package com.gitlink.softbot.annotation;
import java.util.concurrent.TimeUnit;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Description: 内存缓存配置类
*/
@Configuration
public class UrlCache {
@Bean
public Cache<String, Integer> getCache() {
return CacheBuilder.newBuilder().expireAfterWrite(2L, TimeUnit.SECONDS).build();// 缓存有效期为2秒
}
}

View File

@ -0,0 +1,61 @@
package com.gitlink.softbot.annotation.aop;
import javax.servlet.http.HttpServletRequest;
import com.gitlink.softbot.annotation.NoRepeatSubmit;
import com.gitlink.softbot.global.exception.BotException;
import com.gitlink.softbot.global.vo.Result;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.google.common.cache.Cache;
/**
* @Description: aop解析注解-配合google的Cache缓存机制
* @Author: Zoutao
* @Date: 2020/4/14
*/
@Aspect
@Component
public class NoRepeatSubmitAop {
private Log logger = LogFactory.getLog(getClass());
@Autowired
private Cache<String, Integer> cache;
@Pointcut("@annotation(noRepeatSubmit)")
public void pointCut(NoRepeatSubmit noRepeatSubmit) {
}
@Around("pointCut(noRepeatSubmit)")
public Object around(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) {
Result<String> result = new Result<>();
try {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
String sessionId = RequestContextHolder.getRequestAttributes().getSessionId();
HttpServletRequest request = attributes.getRequest();
String key = sessionId + "-" + request.getServletPath();
if (cache.getIfPresent(key) == null) {// 如果缓存中有这个url视为重复提交
Object o = pjp.proceed();
cache.put(key, 0);
return o;
} else {
logger.error("重复请求,请稍后再试!");
return result.build(500).build("重复请求,请稍后再试!");
}
} catch (Throwable e) {
e.printStackTrace();
logger.error("验证重复提交时出现未知异常!");
return result.build(500).build("验证重复提交时出现未知异常!");
}
}
}

View File

@ -0,0 +1,63 @@
package com.gitlink.softbot.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
@EnableAsync
public class MyThreadPoolConfig {
@Bean("addWebhookTaskExecutor")
public Executor addWebhookTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
// 设置队列容量
executor.setQueueCapacity(200);
// 设置线程活跃时间()
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("AddWebhook_Async-Service-");
// 设置拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
@Bean("deleteWebhookTaskExecutor")
public Executor deleteWebhookTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
// 设置队列容量
executor.setQueueCapacity(100);
// 设置线程活跃时间()
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("DELETEWebhook_Async-Service-");
// 设置拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
@Bean("updateWebhookTaskExecutor")
public Executor updateWebhookTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
// 设置队列容量
executor.setQueueCapacity(100);
// 设置线程活跃时间()
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("UpdateWebhook_Async-Service-");
// 设置拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}

View File

@ -24,11 +24,6 @@ public class MarketController {
IMarketService marketService;
@GetMapping("/tt")
public String tt(){
return "asd";
}
/***
* 通过功能类型查询MarketBot
* @param func

View File

@ -1,5 +1,7 @@
package com.gitlink.softbot.controller.user;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.gitlink.softbot.annotation.NoRepeatSubmit;
import com.gitlink.softbot.global.exception.BotException;
import com.gitlink.softbot.global.vo.Response;
import com.gitlink.softbot.global.vo.Result;
@ -8,6 +10,7 @@ import com.gitlink.softbot.utils.AuthOperate;
import com.gitlink.softbot.utils.GitLinkApi;
import com.gitlink.softbot.vo.*;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import com.gitlink.softbot.vo.BotInputVO;
import javax.annotation.Resource;
@ -156,7 +159,7 @@ public class UserController {
* @return
*/
@PostMapping("installMarketBot")
public Result<?> installMarketBot(@RequestBody InstallMarketBotRequest installMarketBotRequest) throws BotException{
public Result<?> installMarketBot(@RequestBody InstallMarketBotRequest installMarketBotRequest) throws BotException, JsonProcessingException {
Result<?> result = new Result<>();
userService.installMarketBot(installMarketBotRequest);
return result.build(200).build("install bot success!");
@ -180,7 +183,8 @@ public class UserController {
* @return
*/
@PostMapping("/updateInstallBot")
public Result<?> updateInstallBot(@Valid @RequestBody UpdateInstallBotRequest updateInstallBotRequest) throws BotException{
@NoRepeatSubmit
public Result<?> updateInstallBot(@Valid @RequestBody UpdateInstallBotRequest updateInstallBotRequest) throws Exception{
Result<?> result = new Result<>();
userService.updateInstallBot(updateInstallBotRequest);
return result.build(200).build("update bot success!");
@ -204,8 +208,8 @@ public class UserController {
* @return
*/
@GetMapping("/getInstallBot")
public Result<?> getInstallBot(@RequestParam("user_id") Integer userId, @RequestParam("bot_id") Integer botId,@RequestParam("login") String login) throws BotException{
GetInstallBotRequest getInstallBotRequest = new GetInstallBotRequest(userId, login,botId);
public Result<?> getInstallBot(@RequestParam("user_id") Integer userId, @RequestParam("bot_id") Integer botId,@RequestParam("login") String login, @RequestParam("repoIds") String repoIds) throws BotException{
GetInstallBotRequest getInstallBotRequest = new GetInstallBotRequest(userId, login, botId , repoIds);
Result<?> result = new Result<>();
GetInstallBotResponse getInstallBotResponse = userService.getInstallBot(getInstallBotRequest);
return result.build(200).build(getInstallBotResponse).build("get installBot success!");
@ -290,16 +294,16 @@ public class UserController {
/**
* 判断是否安装该bot
* @param userId
* @param repoIds
* @param botId
* @return
*/
@GetMapping("/judgeIsIntallBot")
public Result<?> judgeIsInstallBot(@RequestParam("user_id") Integer userId,@RequestParam("bot_id") Integer botId){
public Result<?> judgeIsInstallBot(@RequestParam("repoIds") String repoIds, @RequestParam("bot_id") Integer botId){
Boolean b = userService.judgeIsInstallBot(userId,botId);
Result<Boolean> result = new Result<>();
return result.build(b).build(200).build("success!");
JudgeIsInstallBotResponse judgeIsInstallBotResponse = userService.judgeIsInstallBot(repoIds,botId);
Result<JudgeIsInstallBotResponse> result = new Result<>();
return result.build(judgeIsInstallBotResponse).build(200).build("success!");
}
/**
@ -308,9 +312,12 @@ public class UserController {
* @return
*/
@GetMapping("/getAllInstallBots")
public Result<?> getAllInstallBots(@RequestParam("user_id") Integer userId){
GetAllInstallBotsResponse getAllInstallBotsResponse = userService.getAllInstallBots(userId);
public Result<?> getAllInstallBots(@RequestParam("user_id") Integer userId, @RequestParam(value = "repoIds", required = false) String repoIds){
Result<GetAllInstallBotsResponse> result = new Result<>();
if(userId == null && (repoIds == null || "".equals(repoIds))) {
return result.build("传入参数不能全空").build(500).build("fail!");
}
GetAllInstallBotsResponse getAllInstallBotsResponse = userService.getAllInstallBots(userId, repoIds);
return result.
build(getAllInstallBotsResponse).
build(200).

View File

@ -57,4 +57,6 @@ public class Bot {
@TableField(fill = FieldFill.INSERT)
private Date createTime;
private String oauthCallbackUrl;
}

View File

@ -29,6 +29,8 @@ public class BotLimitEvent {
private Integer readWritePr;
private Integer readWriteIssue;
private Integer authCategory;
private Integer event;

View File

@ -1,6 +1,7 @@
package com.gitlink.softbot.entity.db;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
@ -40,6 +41,12 @@ public class InstallBot {
//添加webhookId
private Integer webhookId;
//仓库拥有者login(组织/个人)
private String repoOwner;
@JsonIgnore
private String webhookResponseMsg;
@TableField(fill = FieldFill.INSERT)
private Date createTime;

View File

@ -14,6 +14,7 @@ import com.gitlink.softbot.dao.db.BotLimitMapper;
import com.gitlink.softbot.entity.db.*;
import com.gitlink.softbot.global.exception.BotException;
import com.gitlink.softbot.service.market.IMarketService;
import com.gitlink.softbot.service.user.impl.UserService;
import com.gitlink.softbot.utils.GitLinkApi;
import com.gitlink.softbot.vo.*;
import lombok.extern.slf4j.Slf4j;
@ -53,6 +54,9 @@ public class MarketService implements IMarketService {
@Autowired
GitLinkApi api;
@Autowired
UserService userService;
@Override
public MarketBotPagesVO getMarketBotByNameLike(String keyword,Integer pageIndex,Integer pageSize){
log.info("执行Bot通过上市名称模糊查询keyword:{},pageIndex:{},pageSize:{}",keyword,pageIndex,pageSize);
@ -217,6 +221,9 @@ public class MarketService implements IMarketService {
public GetBotDetailResponse getBotDetail(Integer userId, Integer botId) {
Bot bot = botMapper.selectOne(Wrappers.<Bot>lambdaQuery()
.eq(Bot::getId,botId));
if(bot == null) {
return new GetBotDetailResponse();
}
MarketBot marketBot = marketBotMapper.selectOne(Wrappers.<MarketBot>lambdaQuery()
.eq(MarketBot::getBotId,botId));
List<BotLimitEvent> botLimitEvents = botLimitMapper.selectList(new QueryWrapper<BotLimitEvent>()
@ -232,7 +239,7 @@ public class MarketService implements IMarketService {
// 设置开发者名称
getBotDetailResponse.setDeveloperName(api.getUserNameByUid(registerBot.getDeveloperId().toString()));
getBotDetailResponse.setDeveloperLogin(registerBot.getDeveloperLogin());
getBotDetailResponse.setLimitAndEvents(getLimitFromLimitEvents(botLimitEvents));
getBotDetailResponse.setLimitAndEvents(userService.getLimitFromLimitEvents(botLimitEvents));
return getBotDetailResponse;
}
@ -290,46 +297,4 @@ public class MarketService implements IMarketService {
marketBotPagesVO1.setPageSize(pageSize);
return marketBotPagesVO1;
}
private LimitVO getLimitFromLimitEvents(List<BotLimitEvent> botLimitEvents){
LimitVO limitVO = new LimitVO();
//无权限情况下
if (botLimitEvents.size()==1&&botLimitEvents.get(0).getEvent()==5){
limitVO.setEventPr("");
limitVO.setEventCode("");
limitVO.setJurisDictionCode(2);
limitVO.setJurisDictionPr(2);
}
StringBuffer codeStr = new StringBuffer();
StringBuffer prStr = new StringBuffer();
botLimitEvents.forEach(botLimitEvent -> {
if (botLimitEvent.getEvent()>=3){
prStr.append(botLimitEvent.getEvent());
prStr.append(",");
limitVO.setJurisDictionPr(botLimitEvent.getReadWritePr());
}else {
codeStr.append(botLimitEvent.getEvent());
codeStr.append(",");
limitVO.setJurisDictionCode(botLimitEvent.getReadWriteCode());
}
});
if (codeStr.length()>1){
codeStr.deleteCharAt(codeStr.length()-1);
}else {
limitVO.setJurisDictionCode(2);
}
if (prStr.length()>1){
prStr.deleteCharAt(prStr.length()-1);
}else {
limitVO.setJurisDictionPr(2);
}
limitVO.setEventPr(prStr.toString());
limitVO.setEventCode(codeStr.toString());
log.info("limitVO:{}",limitVO);
return limitVO;
}
}

View File

@ -1,8 +1,9 @@
package com.gitlink.softbot.service.user;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.gitlink.softbot.global.exception.BotException;
import com.gitlink.softbot.vo.*;
import org.springframework.transaction.annotation.Transactional;
public interface IUserService {
@ -24,11 +25,11 @@ public interface IUserService {
//根据BotId返回Bot信息
MarketBotVO getMarketBotById(Integer botId) throws BotException;
//安装Bot
void installMarketBot(InstallMarketBotRequest installMarketBotRequest) throws BotException;
void installMarketBot(InstallMarketBotRequest installMarketBotRequest) throws BotException, JsonProcessingException;
//安装Bot
void unInstallMarketBot(UnInstallMarketBotRequest unInstallMarketBotRequest) throws BotException;
//用户配置安装的Bot
void updateInstallBot(UpdateInstallBotRequest updateInstallBotRequest) throws BotException;
void updateInstallBot(UpdateInstallBotRequest updateInstallBotRequest) throws Exception;
//删除安装的Bot
void deleteInstallBot(DeleteInstallBotRequest deleteInstallBotRequest) throws BotException;
//修改上市bot
@ -50,9 +51,9 @@ public interface IUserService {
//拒绝接收转让Bot
void refuseTransferBot(RefuseTransferBotRequest refuseTransferBotRequest) throws BotException;
//判断是否安装过此bot
boolean judgeIsInstallBot(Integer userId,Integer botId);
JudgeIsInstallBotResponse judgeIsInstallBot(String repoIds, Integer botId);
GetAllInstallBotsResponse getAllInstallBots(Integer userId);
GetAllInstallBotsResponse getAllInstallBots(Integer userId, String repoIds);
GetStoreAllInstallBotResponse getStoreAllInstallBots(Integer storeId);

View File

@ -0,0 +1,75 @@
package com.gitlink.softbot.service.user.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.gitlink.softbot.dao.db.InstallMapper;
import com.gitlink.softbot.entity.db.BotLimitEvent;
import com.gitlink.softbot.entity.db.InstallBot;
import com.gitlink.softbot.global.vo.Response;
import com.gitlink.softbot.utils.GitLinkApi;
import com.gitlink.softbot.utils.response.AddWebhookResponse;
import com.gitlink.softbot.vo.Webhook;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
@Component
@Slf4j
public class AsyncAddWebhookService {
@Resource
private UserService userService;
@Autowired
private GitLinkApi api;
@Resource
private InstallMapper installMapper;
@Async("addWebhookTaskExecutor")
@Retryable(value = RuntimeException.class, maxAttempts = 3, backoff = @Backoff(delay = 2000,multiplier = 1.5))
public void asyncAddWebhookAndRetry(Integer currentUserId, List<BotLimitEvent> botLimitEvents, InstallBot installBot) throws RuntimeException, JsonProcessingException {
Webhook webhook = userService.getWebhook(botLimitEvents, installBot.getInstallerId());
//先获取webhookId构造webhook
Object[] objects = new Object[]{installBot.getRepoOwner(), installBot.getStoreRepo()};
Response response = api.addWebhook(currentUserId, objects, webhook);
JSONObject object = JSONObject.parseObject(response.getData().toString());
if (response.getCode().equals("error") || (object.get("status")!=null&&!object.get("status").equals(0))) {
installBot.setWebhookId(-1); //添加webhook失败
object.put("webhook_operation_msg", "create webhook fail");
installBot.setWebhookResponseMsg(object.toJSONString());
installMapper.updateById(installBot);
throw new RuntimeException("添加webhook异常");
}
if (response.getCode().equals("ok")) {
//回写WebhookId
AddWebhookResponse addWebhookResponse = JSON.parseObject(response.getData().toString(),AddWebhookResponse.class);
installBot.setWebhookId(addWebhookResponse.getId());
object.put("webhook_operation_msg", "create webhook success");
installBot.setWebhookResponseMsg(object.toJSONString());
int updateNum = installMapper.updateById(installBot);
//bot安装数据更新webhook_id字段失败时删除仓库webhook
if (updateNum == 0) {
api.deleteWebhook(currentUserId, objects, addWebhookResponse.getId());
}
}
}
/**
* 最终重试失败处理
*/
@Recover
public void recover(RuntimeException e){
log.info("调用添加webhook请求重试3次后依旧失败");
}
}

View File

@ -0,0 +1,64 @@
package com.gitlink.softbot.service.user.impl;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.gitlink.softbot.dao.db.InstallMapper;
import com.gitlink.softbot.entity.db.BotLimitEvent;
import com.gitlink.softbot.entity.db.InstallBot;
import com.gitlink.softbot.global.vo.Response;
import com.gitlink.softbot.utils.GitLinkApi;
import com.gitlink.softbot.vo.Webhook;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
@Component
@Slf4j
public class AsyncDeleteWebhookService {
@Resource
private UserService userService;
@Autowired
private GitLinkApi api;
@Resource
private InstallMapper installMapper;
@Async("deleteWebhookTaskExecutor")
@Retryable(value = RuntimeException.class, maxAttempts = 3, backoff = @Backoff(delay = 2000,multiplier = 1.5))
public void asyncDeleteWebhookAndRetry(Integer currentUserId, InstallBot installBot) throws RuntimeException {
Object[] objects = new Object[]{installBot.getRepoOwner(), installBot.getStoreRepo()};
Response response = api.deleteWebhook(currentUserId, objects, installBot.getWebhookId());
JSONObject object = JSONObject.parseObject(response.getData().toString());
if (response.getCode().equals("error") || (object.get("status")!=null&&!object.get("status").equals(0)&&!object.get("status").equals(404))) {
installBot.setWebhookId(-3); //删除webhook失败
object.put("webhook_operation_msg", "delete webhook fail");
installBot.setWebhookResponseMsg(object.toJSONString());
installMapper.updateById(installBot);
throw new RuntimeException("删除webhook异常");
}
if (response.getCode().equals("ok")) {
object.put("webhook_operation_msg", "delete webhook success");
installBot.setWebhookResponseMsg(object.toJSONString());
installMapper.updateById(installBot);
}
}
/**
* 最终重试失败处理
*/
@Recover
public void recover(RuntimeException e){
log.info("调用删除webhook请求重试3次后依旧失败");
}
}

View File

@ -0,0 +1,68 @@
package com.gitlink.softbot.service.user.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.gitlink.softbot.dao.db.InstallMapper;
import com.gitlink.softbot.entity.db.BotLimitEvent;
import com.gitlink.softbot.entity.db.InstallBot;
import com.gitlink.softbot.global.vo.Response;
import com.gitlink.softbot.utils.GitLinkApi;
import com.gitlink.softbot.utils.response.AddWebhookResponse;
import com.gitlink.softbot.vo.Webhook;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
@Component
@Slf4j
public class AsyncUpdateWebhookService {
@Resource
private UserService userService;
@Autowired
private GitLinkApi api;
@Resource
private InstallMapper installMapper;
@Async("updateWebhookTaskExecutor")
@Retryable(value = RuntimeException.class, maxAttempts = 3, backoff = @Backoff(delay = 2000,multiplier = 1.5))
public void asyncUpdateWebhookAndRetry(Integer currentUserId, List<BotLimitEvent> botLimitEvents, InstallBot installBot) throws RuntimeException, JsonProcessingException {
Webhook webhook = userService.getWebhook(botLimitEvents, installBot.getInstallerId());
//先获取webhookId构造webhook
Object[] objects = new Object[]{installBot.getRepoOwner(), installBot.getStoreRepo()};
Response response = api.updateWebhook(currentUserId, objects, installBot.getWebhookId(), webhook);
JSONObject object = JSONObject.parseObject(response.getData().toString());
if (response.getCode().equals("error") || (object.get("status")!=null&&!object.get("status").equals(0))) {
installBot.setWebhookId(-2); //更新webhook失败
object.put("webhook_operation_msg", "update webhook fail");
installBot.setWebhookResponseMsg(object.toJSONString());
installMapper.updateById(installBot);
throw new RuntimeException("更新webhook异常");
}
if (response.getCode().equals("ok")) {
object.put("webhook_operation_msg", "update webhook success");
installBot.setWebhookResponseMsg(object.toJSONString());
installMapper.updateById(installBot);
}
}
/**
* 最终重试失败处理
*/
@Recover
public void recover(RuntimeException e){
log.info("调用更新webhook请求重试3次后依旧失败");
}
}

View File

@ -3,7 +3,9 @@ package com.gitlink.softbot.service.user.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.gitlink.softbot.dao.db.*;
import com.gitlink.softbot.entity.db.*;
import com.gitlink.softbot.global.exception.BotException;
@ -13,7 +15,6 @@ import com.gitlink.softbot.service.user.AbstractUserBot;
import com.gitlink.softbot.service.user.IUserService;
import com.gitlink.softbot.utils.AuthOperate;
import com.gitlink.softbot.utils.GitLinkApi;
import com.gitlink.softbot.utils.response.AddWebhookResponse;
import com.gitlink.softbot.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@ -26,6 +27,7 @@ import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.*;
import java.util.stream.Collectors;
@ -57,11 +59,17 @@ public class UserService extends AbstractUserBot implements IUserService {
@Autowired
GitLinkApi api;
@Autowired
private AsyncAddWebhookService asyncAddWebhookService;
@Autowired
private AsyncUpdateWebhookService asyncUpdateWebhookService;
@Autowired
private AsyncDeleteWebhookService asyncDeleteWebhookService;
/**
* 获取个人注册bot信息
* @param userId
* @param botId
* @return
*/
@Override
public GetRegisterBotResponse getRegisterBot(Integer userId,Integer botId) throws BotException{
@ -87,7 +95,6 @@ public class UserService extends AbstractUserBot implements IUserService {
//增加用户登录名
botOutputVO.setLogin(registerBot.getDeveloperLogin());
BeanUtils.copyProperties(bot,botOutputVO);
getRegisterBotResponse.setBotOutputVO(botOutputVO);
getRegisterBotResponse.setLogin(registerBot.getDeveloperLogin());
botOutputVO.setLimitAndEvents(limitVO);
@ -107,6 +114,7 @@ public class UserService extends AbstractUserBot implements IUserService {
botOutputVO.setIsTransfer(0);
botOutputVO.setIsTransferSuccess(3);
}
getRegisterBotResponse.setBotOutputVO(botOutputVO);
getRegisterBotResponse.setUserId(userId);
return getRegisterBotResponse;
}
@ -119,7 +127,7 @@ public class UserService extends AbstractUserBot implements IUserService {
checkInfo(botVO);
TransactionStatus transactionStatus = null;
DefaultTransactionDefinition transactionDefinition;
Bot insertBot = null;
Bot insertBot;
try {
// 有事务则使用当前事务否则开启新事务
transactionDefinition = new DefaultTransactionDefinition();
@ -164,6 +172,14 @@ public class UserService extends AbstractUserBot implements IUserService {
}
}
private void checkException(Response response, Integer rightCode) throws BotException{
JSONObject object = JSONObject.parseObject(response.getData().toString());
if (object.get("status")!=null&&!object.get("status").equals(0)&&!object.get("status").equals(rightCode)){
log.info("远程接口调用异常:{}",response.getData().toString());
throw new BotException("远程接口调用异常");
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public BotOutputVO updateBot(BotInputVO botInputVO) throws BotException {
@ -196,6 +212,10 @@ public class UserService extends AbstractUserBot implements IUserService {
marketBotMapper.updateById(marketBot);
}
botMapper.updateById(updateBot);
//同步更新回调地址
Response response = api.updateCallbackUrl(botInputVO.getUserId(), updateBot.getId());
//校验异常
checkException(response);
}catch (DuplicateKeyException e){
throw new BotException("Bot更新失败");
}
@ -223,17 +243,14 @@ public class UserService extends AbstractUserBot implements IUserService {
}
//当Webhook发生变化对所有安装此Bot的仓库进行更新webhook
//更新Webhook
Webhook webhook = getWebhook(insetBotLimitEvents);
List<InstallBot> installBotList = installMapper.selectList(Wrappers.<InstallBot>lambdaQuery()
.eq(InstallBot::getBotId,botInputVO.getBotId()));
try {
if (!Objects.isNull(installBotList)) {
for (InstallBot installBot : installBotList) {
Object[] objects = new Object[]{installBot.getInstallerLogin(), installBot.getStoreRepo()};
Response response = api.updateWebhook(installBot.getInstallerId(), objects,installBot.getWebhookId(), webhook);
//异步更新webhook
asyncUpdateWebhookService.asyncUpdateWebhookAndRetry(installBot.getInstallerId(), insetBotLimitEvents, installBot);
//校验异常
checkException(response);
}
}
}catch (Exception e){
@ -247,21 +264,31 @@ public class UserService extends AbstractUserBot implements IUserService {
log.info("权限信息:{}",limitVO);
String eventCode = limitVO.getEventCode();
String eventPr = limitVO.getEventPr();
String eventIssue = limitVO.getEventIssue();
//无权限条件下
if (StringUtils.isBlank(eventCode)&&StringUtils.isBlank(eventPr)){
throw new BotException("事件不能为空!");
if (StringUtils.isBlank(eventCode) && StringUtils.isBlank(eventPr) && StringUtils.isBlank(eventIssue)){
throw new BotException("订阅事件不能为空!");
}
//0只读1读写2:无权限
Integer jurisDictionCode = limitVO.getJurisDictionCode();
//0只读1读写2:无权限
Integer jurisDictionPr = limitVO.getJurisDictionPr();
if ((jurisDictionCode!=2&&StringUtils.isBlank(limitVO.getEventCode()))
||(jurisDictionPr!=2&&StringUtils.isBlank(limitVO.getEventPr()))){
throw new BotException("事件不能为空!");
Integer jurisDictionIssue = limitVO.getJurisDictionIssue();
if ((jurisDictionCode == 2) && (jurisDictionPr == 2) && (jurisDictionIssue == 2)){
throw new BotException("仓库访问权限不能为空!");
}
if (jurisDictionCode == 2 && !StringUtils.isBlank(eventCode)
|| (jurisDictionPr == 2 && !StringUtils.isBlank(eventPr))
|| (jurisDictionIssue == 2 && !StringUtils.isBlank(eventIssue))) {
throw new BotException("权限&订阅设置错误!");
}
String[] codeEvents = eventCode.split(",");
String[] prEvents = eventPr.split(",");
String[] issueEvents = eventIssue.split(",");
List<Integer> eventList = new ArrayList<>();
for (String s : codeEvents){
if (StringUtils.isBlank(s)){
@ -275,24 +302,51 @@ public class UserService extends AbstractUserBot implements IUserService {
}
eventList.add(Integer.valueOf(s));
}
for (String s : issueEvents){
if (StringUtils.isBlank(s)){
break;
}
eventList.add(Integer.valueOf(s));
}
List<Limit> limitList = new ArrayList<>(eventList.size());
eventList.forEach(event ->{
if (event<3){
Limit limit = new Limit();
limit.setEvent(event);
limit.setAuthCategory(0);
//代码和请求字段在一条记录中有一个必须为无权限
limit.setReadWriteCode(jurisDictionCode);
limit.setReadWritePr(2);
limitList.add(limit);
}else {
Limit limit = new Limit();
limit.setEvent(event);
limit.setAuthCategory(1);
limit.setReadWritePr(jurisDictionPr);
limit.setReadWriteCode(2);
limitList.add(limit);
switch (event) {
case 0: //代码库推送
case 1: //代码库创建
case 2: //代码库删除
Limit codeLimit = new Limit();
codeLimit.setEvent(event);
codeLimit.setAuthCategory(0);
//代码和请求字段在一条记录中有一个必须为无权限
codeLimit.setReadWriteCode(jurisDictionCode);
codeLimit.setReadWritePr(2);
codeLimit.setReadWriteIssue(2);
limitList.add(codeLimit);
break;
case 3: //合并请求被打开被关闭被重新打开或被编辑
case 4: //合并请求被分配或取消分配
case 6: //合并请求评论被创建编辑或删除
Limit prLimit = new Limit();
prLimit.setEvent(event);
prLimit.setAuthCategory(1);
prLimit.setReadWritePr(jurisDictionPr);
prLimit.setReadWriteCode(2);
prLimit.setReadWriteIssue(2);
limitList.add(prLimit);
break;
case 7: //疑修已打开已关闭已重新打开或编辑
case 8: //疑修已被指派或取消指派
case 9: //疑修标记被更新或清除
case 10: //疑修评论被创建编辑或删除
Limit issueLimit = new Limit();
issueLimit.setEvent(event);
issueLimit.setAuthCategory(3);
issueLimit.setReadWritePr(2);
issueLimit.setReadWriteCode(2);
issueLimit.setReadWriteIssue(jurisDictionIssue);
limitList.add(issueLimit);
break;
}
});
return limitList;
@ -366,46 +420,59 @@ public class UserService extends AbstractUserBot implements IUserService {
botOutputVO.setIsPublic(bot.getIsPublic());
return botOutputVO;
}
private LimitVO getLimitFromLimitEvents(List<BotLimitEvent> botLimitEvents){
public LimitVO getLimitFromLimitEvents(List<BotLimitEvent> botLimitEvents){
LimitVO limitVO = new LimitVO();
//无权限情况下
if (botLimitEvents.size()==1&&botLimitEvents.get(0).getEvent()==5){
limitVO.setEventPr("");
limitVO.setEventCode("");
limitVO.setEventIssue("");
limitVO.setJurisDictionCode(2);
limitVO.setJurisDictionPr(2);
limitVO.setJurisDictionIssue(2);
}
StringBuffer codeStr = new StringBuffer();
StringBuffer prStr = new StringBuffer();
StringJoiner codeStr = new StringJoiner(",");
StringJoiner prStr = new StringJoiner(",");
StringJoiner issueStr = new StringJoiner(",");
botLimitEvents.forEach(botLimitEvent -> {
if (botLimitEvent.getEvent()>=3){
prStr.append(botLimitEvent.getEvent());
prStr.append(",");
limitVO.setJurisDictionPr(botLimitEvent.getReadWritePr());
}else {
codeStr.append(botLimitEvent.getEvent());
codeStr.append(",");
limitVO.setJurisDictionCode(botLimitEvent.getReadWriteCode());
}
});
botLimitEvents.forEach(botLimitEvent -> {
if (codeStr.length()>1){
codeStr.deleteCharAt(codeStr.length()-1);
}else {
limitVO.setJurisDictionCode(2);
}
if (prStr.length()>1){
prStr.deleteCharAt(prStr.length()-1);
}else {
limitVO.setJurisDictionPr(2);
}
switch (botLimitEvent.getEvent()) {
case 0:
case 1:
case 2:
codeStr.add(botLimitEvent.getEvent().toString());
limitVO.setJurisDictionCode(botLimitEvent.getReadWriteCode());break;
case 3:
case 4:
case 6:
prStr.add(botLimitEvent.getEvent().toString());
limitVO.setJurisDictionPr(botLimitEvent.getReadWritePr());break;
case 7:
case 8:
case 9:
case 10:
issueStr.add(botLimitEvent.getEvent().toString());
limitVO.setJurisDictionIssue(botLimitEvent.getReadWriteIssue());break;
}
});
limitVO.setEventPr(prStr.toString());
limitVO.setEventCode(codeStr.toString());
if (codeStr.length()==0) {
limitVO.setJurisDictionCode(2);
}
if (prStr.length()==0) {
limitVO.setJurisDictionPr(2);
}
if (issueStr.length() == 0) {
limitVO.setJurisDictionIssue(2);
}
log.info("limitVO:{}",limitVO);
return limitVO;
limitVO.setEventPr(prStr.toString());
limitVO.setEventCode(codeStr.toString());
limitVO.setEventIssue(issueStr.toString());
log.info("limitVO:{}",limitVO);
return limitVO;
}
@Override
public Bot shiftObject(BotInputVO botVO) {
@ -417,6 +484,7 @@ public class UserService extends AbstractUserBot implements IUserService {
bot.setWebUrl(botVO.getBotUrl());
bot.setLogo(botVO.getLogo());
bot.setState(0);
bot.setOauthCallbackUrl(botVO.getOauthCallbackUrl());
return bot;
}
public List<BotLimitEvent> shiftBotToLimit(BotInputVO botInputVO,Bot bot) throws BotException{
@ -424,15 +492,16 @@ public class UserService extends AbstractUserBot implements IUserService {
LimitVO limitVO = botInputVO.getLimitAndEvents();
List<Limit> limitList = limitVOToLimit(limitVO);
List<BotLimitEvent> botLimitEvents = new ArrayList<>();
limitList.forEach(limit -> {
BotLimitEvent botLimitEvent = new BotLimitEvent();
botLimitEvent.setBotId(bot.getId());
botLimitEvent.setAuthCategory(limit.getAuthCategory());
botLimitEvent.setReadWriteCode(limit.getReadWriteCode());
botLimitEvent.setReadWritePr(limit.getReadWritePr());
botLimitEvent.setEvent(limit.getEvent());
botLimitEvents.add(botLimitEvent);
});
limitList.forEach(limit -> {
BotLimitEvent botLimitEvent = new BotLimitEvent();
botLimitEvent.setBotId(bot.getId());
botLimitEvent.setAuthCategory(limit.getAuthCategory());
botLimitEvent.setReadWriteCode(limit.getReadWriteCode());
botLimitEvent.setReadWritePr(limit.getReadWritePr());
botLimitEvent.setReadWriteIssue(limit.getReadWriteIssue());
botLimitEvent.setEvent(limit.getEvent());
botLimitEvents.add(botLimitEvent);
});
return botLimitEvents;
}
public RegisterBot shiftBotToRegisterBot(BotInputVO botInputVO,Bot bot){
@ -452,9 +521,10 @@ public class UserService extends AbstractUserBot implements IUserService {
botOutputVO.setIsPublic(bot.getIsPublic());
botOutputVO.setWebhook(bot.getWebhook());
botOutputVO.setUserId(botInputVO.getUserId());
botOutputVO.setWebUrl(bot.getWebUrl());;
botOutputVO.setWebUrl(bot.getWebUrl());
botOutputVO.setLimitAndEvents(botInputVO.getLimitAndEvents());
botOutputVO.setLogo(bot.getLogo());
botOutputVO.setOauthCallbackUrl(bot.getOauthCallbackUrl());
return botOutputVO;
}
@ -462,7 +532,7 @@ public class UserService extends AbstractUserBot implements IUserService {
@Transactional(rollbackFor = Exception.class)
public void deleteBot(DeleteBotRequest deleteBotRequest) throws BotException{
log.info("删除Bot:{}",JSON.toJSONString(deleteBotRequest));
//删除Bot涉及Bot表Limit表register表install表es中数据,Market中数据删除tranfer中数据
//删除Bot涉及Bot表Limit表register表install表es中数据,Market中数据删除transfer中数据
//1.删除Bot中数据
RegisterBot registerBot = registerMapper.selectOne(Wrappers.<RegisterBot>
lambdaQuery().eq(RegisterBot::getBotId,deleteBotRequest.getBotId()));
@ -481,13 +551,9 @@ public class UserService extends AbstractUserBot implements IUserService {
//批量删除webhook
for (InstallBot installBot : installBots) {
//构造接口参数
Object[] objects = new Object[]{installBot.getInstallerLogin(), installBot.getStoreRepo()};
//调用平台api删除所有相关webhook
Response response = api.deleteWebhook(installBot.getInstallerId(),objects,installBot.getWebhookId());
//校验异常
checkException(response);
asyncDeleteWebhookService.asyncDeleteWebhookAndRetry(installBot.getInstallerId(), installBot);
}
}
@ -516,7 +582,7 @@ public class UserService extends AbstractUserBot implements IUserService {
@Transactional(rollbackFor = Exception.class)
public void botToMarket(BotToMarketRequest botToMarketRequest) throws BotException{
log.info("Bot上市{}",botToMarketRequest);
//先校验是否公开不是公开则判断
//先校验是否公开不是公开则判断
Bot bot = botMapper.selectById(botToMarketRequest.getBotId());
if (bot==null){
throw new BotException("该Bot不存在!");
@ -600,9 +666,9 @@ public class UserService extends AbstractUserBot implements IUserService {
System.out.println(registerBot.getBotId());
MarketBot marketBot = marketBotMapper.selectOne(new QueryWrapper<MarketBot>()
.eq("bot_id",registerBot.getBotId()));
if (Objects.isNull(marketBot)){
return;
}
if (Objects.isNull(marketBot)){
return;
}
botList.add(getMarketBotsResponse.getMarketBot(
marketBot
));
@ -638,16 +704,16 @@ public class UserService extends AbstractUserBot implements IUserService {
}
@Override
@Transactional(rollbackFor = Exception.class)
public void installMarketBot(InstallMarketBotRequest installMarketBotRequest) throws BotException {
@Transactional(rollbackFor = BotException.class, noRollbackFor = RuntimeException.class)
public void installMarketBot(InstallMarketBotRequest installMarketBotRequest) throws BotException, JsonProcessingException {
try {
//1.校验有没有安装过此Bot
List<InstallBot> installBots = installMapper.selectList(Wrappers.<InstallBot>lambdaQuery()
.eq(InstallBot::getBotId,installMarketBotRequest.getBotId())
.eq(InstallBot::getInstallerId,installMarketBotRequest.getUserId()));
.in(InstallBot::getStoreId,installMarketBotRequest.getStoreList()));
if (installBots.size()>0){
throw new BotException("已经安装过此Bot");
throw new BotException("存在仓库已经安装过此Bot");
}
//1.插入到installBot表中
List<Integer> storeList = installMarketBotRequest.getStoreList();
@ -660,44 +726,19 @@ public class UserService extends AbstractUserBot implements IUserService {
List<BotLimitEvent> botLimitEvents = botLimitMapper.selectList(Wrappers.<BotLimitEvent>lambdaQuery()
.eq(BotLimitEvent::getBotId, installMarketBotRequest.getBotId()));
assert botLimitEvents != null && botLimitEvents.size() > 0;
Webhook webhook = getWebhook(botLimitEvents);
//批量插入installBot表添加webhook
for (InstallBot installBot : installBotList) {
//插入表
installMapper.insert(installBot);
//先获取webhookId构造webhook
Object[] objects = new Object[]{installMarketBotRequest.getLogin(), installBot.getStoreRepo()};
Response response = api.addWebhook(installMarketBotRequest.getUserId(), objects, webhook);
checkException(response);
AddWebhookResponse addWebhookResponse = JSON.parseObject(response.getData().toString(),AddWebhookResponse.class);
//回写WebhookId
installBot.setWebhookId(addWebhookResponse.getId());
installMapper.updateById(installBot);
asyncAddWebhookService.asyncAddWebhookAndRetry(installMarketBotRequest.getUserId(), botLimitEvents, installBot);
}
//2.对MarketBot表中install_num加1
MarketBot updateMarketBot = marketBotMapper.selectOne(new QueryWrapper<MarketBot>()
.eq("bot_id",installMarketBotRequest.getBotId()));
if (updateMarketBot==null){
//说明是注册者安装的此bot不是从市场安装的通过主页安装
Bot bot = botMapper.selectOne(Wrappers.<Bot>lambdaQuery()
.eq(Bot::getId,installMarketBotRequest.getBotId()));
bot.setInstallNum(bot.getInstallNum()+1);
botMapper.updateById(bot);
return;
}
updateMarketBot.setInstallNum(updateMarketBot.getInstallNum()+1);
marketBotMapper.updateById(updateMarketBot);
//3.对Bot表中install_num加1
Bot updateBot = botMapper.selectOne(new QueryWrapper<Bot>()
.eq("id",installMarketBotRequest.getBotId()));
updateBot.setInstallNum(updateBot.getInstallNum()+1);
botMapper.updateById(updateBot);
}catch (Exception e){
//同步累加安装次数
botInstallNumAdd(installMarketBotRequest.getBotId(), installBotList.size());
marketBotInstallNumAdd(installMarketBotRequest.getBotId(), installBotList.size());
}catch (BotException e){
throw new BotException("安装失败!");
}
@ -706,11 +747,11 @@ public class UserService extends AbstractUserBot implements IUserService {
@Override
@Transactional(rollbackFor = Exception.class)
public void unInstallMarketBot(UnInstallMarketBotRequest unInstallMarketBotRequest) throws BotException {
public void unInstallMarketBot(UnInstallMarketBotRequest unInstallMarketBotRequest){
// 检查该仓库安装的bot
List<InstallBot> installBots = installMapper.selectList(Wrappers.<InstallBot>lambdaQuery()
.eq(InstallBot::getStoreId,unInstallMarketBotRequest.getStoreId())
.eq(InstallBot::getInstallerId,unInstallMarketBotRequest.getUserId()));
.eq(InstallBot::getStoreRepo,unInstallMarketBotRequest.getStoreIdentifier()));
// 如果安装了bot
if(installBots!=null&&installBots.size()>0){
//删除各个webhook
@ -722,33 +763,48 @@ public class UserService extends AbstractUserBot implements IUserService {
// 删除仓库的所有安装记录
installMapper.delete(Wrappers.<InstallBot>lambdaQuery()
.eq(InstallBot::getStoreId,unInstallMarketBotRequest.getStoreId())
.eq(InstallBot::getInstallerId,unInstallMarketBotRequest.getUserId()));
.eq(InstallBot::getStoreRepo,unInstallMarketBotRequest.getStoreIdentifier()));
}
}
private Webhook getWebhook(List<BotLimitEvent> limitEvents){
public Webhook getWebhook(List<BotLimitEvent> limitEvents, Integer installerId){
assert !Objects.isNull(limitEvents);
assert !Objects.isNull(limitEvents);
Webhook webhook = new Webhook();
Object[] objects = new Object[limitEvents.size()];
Integer event;
for (int i = 0; i < limitEvents.size(); i++) {
if (limitEvents.get(i).getEvent()==0){
objects[i]="push";
}else if (limitEvents.get(i).getEvent()==1){
objects[i]="create";
}else if (limitEvents.get(i).getEvent()==2){
objects[i]="delete";
}else if (limitEvents.get(i).getEvent()==3){
objects[i]="pull_request";
}else {
objects[i]="pull_request_assign";
event = limitEvents.get(i).getEvent();
switch (event) {
case 0:
objects[i]="push"; break;
case 1:
objects[i]="create"; break;
case 2:
objects[i]="delete"; break;
case 3:
objects[i]="pull_request_only"; break;
case 4:
objects[i]="pull_request_assign"; break;
case 6:
objects[i]="pull_request_comment"; break;
case 7:
objects[i]="issues_only"; break;
case 8:
objects[i]="issue_assign"; break;
case 9:
objects[i]="issue_label"; break;
case 10:
objects[i]="issue_comment"; break;
}
}
Bot bot = botMapper.selectById(limitEvents.get(0).getBotId());
webhook.setEvents(objects);
webhook.setActive(true);
webhook.setContent_type("json");
webhook.setUrl(bot.getWebhook());
String webhookUri = UriComponentsBuilder.fromUriString(bot.getWebhook()).queryParam("installer_id", installerId).build().toString();
webhook.setUrl(webhookUri);
webhook.setType("softbot");
webhook.setHttp_method("POST");
webhook.setBranch_filter("*");
return webhook;
@ -767,6 +823,7 @@ public class UserService extends AbstractUserBot implements IUserService {
installBot.setInstallerLogin(installMarketBotRequest.getLogin());
installBot.setStoreId(storeId);
installBot.setStoreRepo(installMarketBotRequest.getRepoMap().get(storeId));
installBot.setRepoOwner(installMarketBotRequest.getRepoOwnerMap().get(storeId));
installBot.setState(installMarketBotRequest.getState());
installBots.add(installBot);
});
@ -779,56 +836,63 @@ public class UserService extends AbstractUserBot implements IUserService {
installBot.setStoreId(storeId);
installBot.setInstallerLogin(updateInstallBotRequest.getLogin());
installBot.setStoreRepo(updateInstallBotRequest.getRepoMap().get(storeId));
installBot.setRepoOwner(updateInstallBotRequest.getRepoOwnerMap().get(storeId));
//TODO 如果bot生效通过平台该bot
installBot.setState(updateInstallBotRequest.getState());
return installBot;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void updateInstallBot(UpdateInstallBotRequest updateInstallBotRequest) throws BotException{
@Transactional(rollbackFor = Exception.class, noRollbackFor = RuntimeException.class)
public void updateInstallBot(UpdateInstallBotRequest updateInstallBotRequest) throws Exception {
//1.先删除botId和userId对应的所有installBot
List<InstallBot> installBotList = installMapper.selectList(Wrappers.<InstallBot>lambdaQuery()
.eq(InstallBot::getBotId,updateInstallBotRequest.getBotId())
.eq(InstallBot::getInstallerId,updateInstallBotRequest.getUserId()));
.in(InstallBot::getStoreId,updateInstallBotRequest.getInstalledStoreList()));
if (!Objects.isNull(installBotList)){
for (InstallBot installBot : installBotList){
//先删除webhook
Object[] objects = new Object[]{updateInstallBotRequest.getLogin(),installBot.getStoreRepo()};
Response response = api.deleteWebhook(updateInstallBotRequest.getUserId(),objects,installBot.getWebhookId());
checkException(response);
asyncDeleteWebhookService.asyncDeleteWebhookAndRetry(updateInstallBotRequest.getUserId(), installBot);
}
}
installMapper.delete(new QueryWrapper<InstallBot>()
.eq("bot_id",updateInstallBotRequest.getBotId())
.eq("installer_id",updateInstallBotRequest.getUserId()));
.eq("bot_id", updateInstallBotRequest.getBotId())
.in("store_id", updateInstallBotRequest.getInstalledStoreList()));
List<Integer> storeList = updateInstallBotRequest.getStoreList();
//2.然后重新插入所有storeId; //新增webhook
List<BotLimitEvent> botLimitEvents = botLimitMapper.selectList(Wrappers.<BotLimitEvent>lambdaQuery()
.eq(BotLimitEvent::getBotId,updateInstallBotRequest.getBotId()));
Webhook webhook = getWebhook(botLimitEvents);
for (Integer store : storeList){
InstallBot installBot = getInstallBot(updateInstallBotRequest,store);
installMapper.insert(installBot);
Object[] objects = new Object[]{updateInstallBotRequest.getLogin(),installBot.getStoreRepo()};
try {
Response response = api.addWebhook(updateInstallBotRequest.getUserId(),objects,webhook);
checkException(response);
AddWebhookResponse addWebhookResponse = JSON.parseObject(response.getData().toString(),AddWebhookResponse.class);
installBot.setWebhookId(addWebhookResponse.getId());
installMapper.updateById(installBot);
}catch (Exception e){
throw new BotException("添加webhook失败");
}
asyncAddWebhookService.asyncAddWebhookAndRetry(updateInstallBotRequest.getUserId(), botLimitEvents, installBot);
}
//同步累加安装次数
botInstallNumAdd(updateInstallBotRequest.getBotId(), storeList.size());
marketBotInstallNumAdd(updateInstallBotRequest.getBotId(), storeList.size());
}
private void botInstallNumAdd(Integer botId, int installNum) {
UpdateWrapper<Bot> updateWrapper = new UpdateWrapper<>();
updateWrapper.lambda().eq(Bot::getId, botId)
.setSql("install_num = install_num + " + installNum);
botMapper.update(null, updateWrapper);
}
private void marketBotInstallNumAdd(Integer botId, int installNum) {
UpdateWrapper<MarketBot> updateWrapper = new UpdateWrapper<>();
updateWrapper.lambda().eq(MarketBot::getBotId, botId)
.setSql("install_num = install_num + " + installNum);
marketBotMapper.update(null, updateWrapper);
}
@Override
@ -836,7 +900,7 @@ public class UserService extends AbstractUserBot implements IUserService {
public void deleteInstallBot(DeleteInstallBotRequest deleteInstallBotRequest) throws BotException{
List<InstallBot> installBots = installMapper.selectList(Wrappers.<InstallBot>lambdaQuery()
.eq(InstallBot::getBotId,deleteInstallBotRequest.getBotId())
.eq(InstallBot::getInstallerId,deleteInstallBotRequest.getUserId()));
.in(InstallBot::getStoreId, Arrays.asList(deleteInstallBotRequest.getStoreRepoIds().split(","))));
if (installBots==null||installBots.size()<=0){
throw new BotException("该用户没有要删除的Bot");
}
@ -856,36 +920,40 @@ public class UserService extends AbstractUserBot implements IUserService {
//删除install_bot
installMapper.delete(Wrappers.<InstallBot>lambdaQuery()
.eq(InstallBot::getBotId,deleteInstallBotRequest.getBotId())
.eq(InstallBot::getInstallerId,deleteInstallBotRequest.getUserId()));
.in(InstallBot::getStoreId, Arrays.asList(deleteInstallBotRequest.getStoreRepoIds().split(","))));
//删除webhook
for(InstallBot installBot:installBots){
Object[] objects = new Object[]{deleteInstallBotRequest.getLogin(),installBot.getStoreRepo()};
Response response = api.deleteWebhook(deleteInstallBotRequest.getUserId(),objects,installBot.getWebhookId());
checkException(response);
asyncDeleteWebhookService.asyncDeleteWebhookAndRetry(deleteInstallBotRequest.getUserId(), installBot);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public GetInstallBotResponse getInstallBot(GetInstallBotRequest getInstallBotRequest) throws BotException{
GetInstallBotResponse getInstallBotResponse = new GetInstallBotResponse();
GetInstallBotResponse getInstallBotResponse = new GetInstallBotResponse();
//1.到bot表中查看name
Bot bot = botMapper.selectById(getInstallBotRequest.getBotId());
String name = "";
String logo = "";
int isPublic;
if (bot!=null){
name = bot.getBotName();
logo = bot.getLogo();
isPublic = bot.getIsPublic();
}else {
throw new BotException("不存在该bot");
}
getInstallBotResponse.setLogo(logo);
getInstallBotResponse.setMarketName(name);
getInstallBotResponse.setIsPublic(isPublic);
//2.到install_bot表中查看state
List<InstallBot> installBots = installMapper.selectList(new QueryWrapper<InstallBot>()
.eq("bot_id",getInstallBotRequest.getBotId())
.eq("installer_id",getInstallBotRequest.getUserId()));
.in("store_id", Arrays.asList(getInstallBotRequest.getRepoIds().split(","))));
assert installBots.size()>0;
getInstallBotResponse.setCreateTime(installBots.get(0).getCreateTime());
getInstallBotResponse.setState(installBots.get(0).getState());
@ -952,19 +1020,19 @@ public class UserService extends AbstractUserBot implements IUserService {
@Override
public GetTransferFromBotResponse getTransferBotState(GetTransferFromBotRequest getTransferFromBotRequest) {
List<TransferBot> transferBots = transferBotMapper.selectList(Wrappers.<TransferBot>lambdaQuery()
.eq(TransferBot::getBotId,getTransferFromBotRequest.getBotId())
.eq(TransferBot::getTransferFromId,getTransferFromBotRequest.getUserId())
.orderByDesc(TransferBot::getId));
GetTransferFromBotResponse getTransferFromBotResponse = new GetTransferFromBotResponse();
if(transferBots!=null && transferBots.size()>0){
TransferBot transferBot = transferBots.get(0);
getTransferFromBotResponse.setBotId(getTransferFromBotRequest.getBotId());
getTransferFromBotResponse.setUserId(getTransferFromBotRequest.getUserId());
getTransferFromBotResponse.setState(transferBot.getIsSuccess());
getTransferFromBotResponse.setLogin(transferBot.getFromLogin());
}
return getTransferFromBotResponse;
List<TransferBot> transferBots = transferBotMapper.selectList(Wrappers.<TransferBot>lambdaQuery()
.eq(TransferBot::getBotId,getTransferFromBotRequest.getBotId())
.eq(TransferBot::getTransferFromId,getTransferFromBotRequest.getUserId())
.orderByDesc(TransferBot::getId));
GetTransferFromBotResponse getTransferFromBotResponse = new GetTransferFromBotResponse();
if(transferBots!=null && transferBots.size()>0){
TransferBot transferBot = transferBots.get(0);
getTransferFromBotResponse.setBotId(getTransferFromBotRequest.getBotId());
getTransferFromBotResponse.setUserId(getTransferFromBotRequest.getUserId());
getTransferFromBotResponse.setState(transferBot.getIsSuccess());
getTransferFromBotResponse.setLogin(transferBot.getFromLogin());
}
return getTransferFromBotResponse;
}
@Override
@ -1003,12 +1071,12 @@ public class UserService extends AbstractUserBot implements IUserService {
}
GetTransferToBotResponse getTransferToBotResponse = new GetTransferToBotResponse();
List<GetTransferToBot> getTransferToBots = new ArrayList<>();
if (!Objects.isNull(botList)){
botList.forEach(bot -> {
log.info("bot==:{}",bot);
getTransferToBots.add(getTransferToBot(bot,transferBotMap.get(bot.getId())));
});
}
if (!Objects.isNull(botList)){
botList.forEach(bot -> {
log.info("bot==:{}",bot);
getTransferToBots.add(getTransferToBot(bot,transferBotMap.get(bot.getId())));
});
}
getTransferToBotResponse.setUserId(getTransferToBotRequest.getUserId());
getTransferToBotResponse.setLogin(getTransferToBotRequest.getLogin());
getTransferToBotResponse.setBotList(getTransferToBots);
@ -1031,58 +1099,58 @@ public class UserService extends AbstractUserBot implements IUserService {
// @Transactional(rollbackFor = Exception.class)
public void receiveTransferBot(ReceiveTransferBotRequest receiveTransferBotRequest) throws BotException {
//1.修改transfer_bot表
List<TransferBot> transferBots = transferBotMapper.selectList(Wrappers.<TransferBot>lambdaQuery()
.eq(TransferBot::getTransferFromId,receiveTransferBotRequest.getTransferFromId())
.eq(TransferBot::getTransferToId,receiveTransferBotRequest.getTransferToId())
.eq(TransferBot::getBotId,receiveTransferBotRequest.getBotId())
.eq(TransferBot::getIsSuccess,2)
.orderByDesc(TransferBot::getId));
List<TransferBot> transferBots = transferBotMapper.selectList(Wrappers.<TransferBot>lambdaQuery()
.eq(TransferBot::getTransferFromId,receiveTransferBotRequest.getTransferFromId())
.eq(TransferBot::getTransferToId,receiveTransferBotRequest.getTransferToId())
.eq(TransferBot::getBotId,receiveTransferBotRequest.getBotId())
.eq(TransferBot::getIsSuccess,2)
.orderByDesc(TransferBot::getId));
TransferBot transferBot = null;
TransferBot transferBot = null;
if (transferBots!=null&&transferBots.size()>0){
TransactionStatus transactionStatus = null;
if (transferBots!=null&&transferBots.size()>0){
TransactionStatus transactionStatus = null;
DefaultTransactionDefinition transactionDefinition;
Bot bot = null;
RegisterBot registerBot = null;
try {
// 有事务则使用当前事务否则开启新事务
transactionDefinition = new DefaultTransactionDefinition();
transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
transactionStatus = transactionManager.getTransaction(transactionDefinition);
DefaultTransactionDefinition transactionDefinition;
Bot bot = null;
RegisterBot registerBot = null;
try {
// 有事务则使用当前事务否则开启新事务
transactionDefinition = new DefaultTransactionDefinition();
transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
transactionStatus = transactionManager.getTransaction(transactionDefinition);
transferBot = transferBots.get(0);
//转让成功
transferBot.setIsSuccess(1);
transferBotMapper.updateById(transferBot);
//2.将注册表中修改注册者为bot被转让人
registerBot = registerMapper.selectOne(new QueryWrapper<RegisterBot>()
.eq("bot_id",transferBot.getBotId()));
registerBot.setDeveloperId(receiveTransferBotRequest.getTransferToId());
registerBot.setDeveloperLogin(receiveTransferBotRequest.getTransferToLogin());
registerMapper.updateById(registerBot);
// 3.更改bot表中owner_id字段
bot = botMapper.selectOne(new QueryWrapper<Bot>()
.eq("id",receiveTransferBotRequest.getBotId()));
bot.setOwnerId(receiveTransferBotRequest.getTransferToId());
botMapper.updateById(bot);
// 提交事务
transactionManager.commit(transactionStatus);
} catch (Exception e){
if (transactionStatus != null) {
transactionManager.rollback(transactionStatus);
}
throw new BotException("Bot注册失败" + e);
}
// 4.bot表中更新client_secret和private_key字段
if(registerBot!=null&&bot!=null){
Response response0 = api.activeBotAuth(registerBot.getDeveloperId(), bot.getId(), AuthOperate.UPDATE_SECRET);
checkException(response0);
Response response1 = api.activeBotAuth(registerBot.getDeveloperId(), bot.getId(), AuthOperate.UPDATE_PRIVATE_KEY);
checkException(response1);
}
}
transferBot = transferBots.get(0);
//转让成功
transferBot.setIsSuccess(1);
transferBotMapper.updateById(transferBot);
//2.将注册表中修改注册者为bot被转让人
registerBot = registerMapper.selectOne(new QueryWrapper<RegisterBot>()
.eq("bot_id",transferBot.getBotId()));
registerBot.setDeveloperId(receiveTransferBotRequest.getTransferToId());
registerBot.setDeveloperLogin(receiveTransferBotRequest.getTransferToLogin());
registerMapper.updateById(registerBot);
// 3.更改bot表中owner_id字段
bot = botMapper.selectOne(new QueryWrapper<Bot>()
.eq("id",receiveTransferBotRequest.getBotId()));
bot.setOwnerId(receiveTransferBotRequest.getTransferToId());
botMapper.updateById(bot);
// 提交事务
transactionManager.commit(transactionStatus);
} catch (Exception e){
if (transactionStatus != null) {
transactionManager.rollback(transactionStatus);
}
throw new BotException("Bot注册失败" + e);
}
// 4.bot表中更新client_secret和private_key字段
if(registerBot!=null&&bot!=null){
Response response0 = api.activeBotAuth(registerBot.getDeveloperId(), bot.getId(), AuthOperate.UPDATE_SECRET);
checkException(response0);
Response response1 = api.activeBotAuth(registerBot.getDeveloperId(), bot.getId(), AuthOperate.UPDATE_PRIVATE_KEY);
checkException(response1);
}
}
}
@ -1120,23 +1188,31 @@ public class UserService extends AbstractUserBot implements IUserService {
/**
* 判断该用户是否安装此bot
* @param userId
* @param repoIds
* @param botId
* @return
*/
@Override
public boolean judgeIsInstallBot(Integer userId, Integer botId) {
public JudgeIsInstallBotResponse judgeIsInstallBot(String repoIds, Integer botId) {
JudgeIsInstallBotResponse judgeIsInstallBotResponse = new JudgeIsInstallBotResponse();
List<String> installRepoIdList = new ArrayList<>();
List<String> unInstallRepoIdList = new ArrayList<>();
List<String> repoIdList = Arrays.asList(repoIds.split(","));
for (String repoId : repoIdList) {
//如果公开则判断安装表里面有没有该用户安装的bot
List<InstallBot> installBots = installMapper.selectList(Wrappers.
<InstallBot>lambdaQuery().eq(InstallBot::getBotId, botId)
.eq(InstallBot::getStoreId, repoId));
if (!Objects.isNull(installBots) && installBots.size() > 0) {
installRepoIdList.add(repoId);
} else {
unInstallRepoIdList.add(repoId);
}
//如果公开则判断安装表里面有没有该用户安装的bot
List<InstallBot> installBots = installMapper.selectList(Wrappers.
<InstallBot>lambdaQuery().eq(InstallBot::getBotId,botId)
.eq(InstallBot::getInstallerId,userId));
if (!Objects.isNull(installBots)&&installBots.size()>0){
return true;
}else {
return false;
}
judgeIsInstallBotResponse.setInstallRepoIds(installRepoIdList);
judgeIsInstallBotResponse.setUninstallRepoIds(unInstallRepoIdList);
return judgeIsInstallBotResponse;
}
@ -1150,6 +1226,7 @@ public class UserService extends AbstractUserBot implements IUserService {
stringBuilder.append(botLimitEvent.getEvent());
stringBuilder.append(botLimitEvent.getReadWritePr());
stringBuilder.append(botLimitEvent.getReadWriteCode());
stringBuilder.append(botLimitEvent.getReadWriteIssue());
stringBuilder.append(botLimitEvent.getAuthCategory());
limitEventString.add(stringBuilder.toString());
});
@ -1159,6 +1236,7 @@ public class UserService extends AbstractUserBot implements IUserService {
stringBuilder.append(limit.getEvent());
stringBuilder.append(limit.getReadWritePr());
stringBuilder.append(limit.getReadWriteCode());
stringBuilder.append(limit.getReadWriteIssue());
stringBuilder.append(limit.getAuthCategory());
limitString.add(stringBuilder.toString());
});
@ -1174,13 +1252,37 @@ public class UserService extends AbstractUserBot implements IUserService {
/**
* 获取用户安装所有bot信息
* @param userId
* @param repoIds
* @return
*/
@Override
public GetAllInstallBotsResponse getAllInstallBots(Integer userId) {
public GetAllInstallBotsResponse getAllInstallBots(Integer userId, String repoIds) {
List<InstallBot> installBots = new ArrayList<>();
if(userId != null) {
installBots = installMapper.selectList(Wrappers.<InstallBot>lambdaQuery()
.eq(InstallBot::getInstallerId,userId));
}
if(repoIds != null) {
List<String> repoList = Arrays.asList(repoIds.split(","));
installBots = installMapper.selectList(Wrappers.<InstallBot>lambdaQuery()
.in(InstallBot::getStoreId, repoList));
}
Map<Integer, StringJoiner> botAndAllRepoIdMap = new HashMap<>();
for(InstallBot installBot : installBots) {
StringJoiner s = new StringJoiner(",");
if(botAndAllRepoIdMap.containsKey(installBot.getBotId())){
s = botAndAllRepoIdMap.get(installBot.getBotId());
}
if (installBot.getStoreRepo() == null || (s.length() > 0 && s.toString().contains(installBot.getStoreRepo()))){
continue;
}
botAndAllRepoIdMap.put(installBot.getBotId(), s.add(installBot.getStoreId().toString()));
}
List<InstallBot> installBots = installMapper.selectList(Wrappers.<InstallBot>lambdaQuery()
.eq(InstallBot::getInstallerId,userId));
List<InstallBotInfo> installBotInfos = new ArrayList<>();
installBots.forEach(installBot -> {
Integer botId = installBot.getBotId();
@ -1193,6 +1295,7 @@ public class UserService extends AbstractUserBot implements IUserService {
installBotInfo.setLimitVO(limitVO);
BeanUtils.copyProperties(bot,installBotInfo);
BeanUtils.copyProperties(installBot,installBotInfo);
installBotInfo.setStoreRepoIds(String.valueOf(botAndAllRepoIdMap.get(installBotInfo.getBotId())));
installBotInfos.add(installBotInfo);
});
@ -1247,24 +1350,24 @@ public class UserService extends AbstractUserBot implements IUserService {
@Transactional(rollbackFor = Exception.class)
public void updateMarketBot(BotToMarketRequest botToMarketRequest) throws BotException{
checkBotName(botToMarketRequest.getBotId(),botToMarketRequest.getMarketName());
try {
MarketBot marketBot = marketBotMapper.selectOne(Wrappers
.<MarketBot>lambdaQuery().eq(MarketBot::getBotId,botToMarketRequest.getBotId()));
if (marketBot!=null){
MarketBot updateMarketBot = getDBMarketBot(botToMarketRequest);
updateMarketBot.setId(marketBot.getId());
marketBotMapper.updateById(updateMarketBot);
//同步更新bot表信息
Bot bot = botMapper.selectById(marketBot.getBotId());
bot.setBotDes(updateMarketBot.getMarketIntro());
bot.setLogo(updateMarketBot.getLogo());
bot.setBotName(updateMarketBot.getMarketName());
botMapper.updateById(bot);
}
try {
MarketBot marketBot = marketBotMapper.selectOne(Wrappers
.<MarketBot>lambdaQuery().eq(MarketBot::getBotId,botToMarketRequest.getBotId()));
if (marketBot!=null){
MarketBot updateMarketBot = getDBMarketBot(botToMarketRequest);
updateMarketBot.setId(marketBot.getId());
marketBotMapper.updateById(updateMarketBot);
//同步更新bot表信息
Bot bot = botMapper.selectById(marketBot.getBotId());
bot.setBotDes(updateMarketBot.getMarketIntro());
bot.setLogo(updateMarketBot.getLogo());
bot.setBotName(updateMarketBot.getMarketName());
botMapper.updateById(bot);
}
}catch (Exception e){
throw new BotException("更新失败!");
}
}catch (Exception e){
throw new BotException("更新失败!");
}
}
@ -1276,15 +1379,15 @@ public class UserService extends AbstractUserBot implements IUserService {
@Override
@Transactional(rollbackFor = Exception.class)
public void downMarketBot(Integer botId) throws BotException{
try {
MarketBot marketBot = marketBotMapper.selectOne(Wrappers
.<MarketBot>lambdaQuery()
.eq(MarketBot::getBotId,botId));
if (!Objects.isNull(marketBot)){
marketBotMapper.deleteById(marketBot.getId());
}
}catch (Exception e){
throw new BotException("下架bot失败");
}
try {
MarketBot marketBot = marketBotMapper.selectOne(Wrappers
.<MarketBot>lambdaQuery()
.eq(MarketBot::getBotId,botId));
if (!Objects.isNull(marketBot)){
marketBotMapper.deleteById(marketBot.getId());
}
}catch (Exception e){
throw new BotException("下架bot失败");
}
}
}

View File

@ -121,6 +121,14 @@ public class GitLinkApi {
return response;
}
public Response updateCallbackUrl(Integer uid, Integer botId) {
Map<String, String> inputParams = new HashMap<>();
inputParams.put("uid", uid.toString());
Object[] params = new Object[]{botId.toString()};
Response response = RestTemplateUtil.httpRequest(restTemplate, HttpMethod.POST, URL+"/app", params, "/update_callback_url" , inputParams, null ,getHeader());
return response;
}
// public Response activeBotAuth(Integer uid, Integer botId){
// Map<String, String> inputParams = new HashMap<>();
// inputParams.put("uid", uid.toString());

View File

@ -2,6 +2,8 @@ package com.gitlink.softbot.utils;
import com.gitlink.softbot.global.vo.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@ -16,7 +18,7 @@ import java.util.Objects;
public class RestTemplateUtil {
//private static Logger logger = (Logger) LoggerFactory.getLogger(RestTemplateUtil.class);
private static Logger logger = (Logger) LoggerFactory.getLogger(RestTemplateUtil.class);
/**
* @Description 私有构造函数
*/
@ -83,7 +85,8 @@ public class RestTemplateUtil {
params.setAll(inputParams);
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
URI uri = builder.queryParams(params).build().encode().toUri();
//System.out.println(uri);
logger.info("远程接口调用地址: " + url);
logger.info("entity: " + entity);
ResponseEntity<String> resp = customRestTemplate.exchange(uri, method, entity, String.class);
return handleResult(resp);
}

View File

@ -50,6 +50,10 @@ public class BotInputVO implements Serializable {
//TODO 前端改协议
private String botUrl;
//oauth授权回调地址
@NotNull(message = "oauthCallbackUrl is required")
private String oauthCallbackUrl;
/**
* 权限与事件
*/

View File

@ -42,6 +42,8 @@ public class BotOutputVO implements Serializable {
*/
private Integer state;
private String OauthCallbackUrl;
/**
* 是否转让 0未转让 1转让
*/

View File

@ -26,4 +26,7 @@ public class DeleteInstallBotRequest {
@NotNull(message = "botId is required")
private Integer botId;
private String password;
@NotNull(message = "repoIds is required")
private String storeRepoIds;
}

View File

@ -76,4 +76,9 @@ public class GetBotDetailResponse {
* 权限与事件
*/
LimitVO limitAndEvents;
/**
* 安装次数
*/
private Integer installNum;
}

View File

@ -23,4 +23,6 @@ public class GetInstallBotRequest implements Serializable {
private String login;
@NotNull(message = "botId is required")
private Integer botId;
private String repoIds;
}

View File

@ -25,6 +25,7 @@ public class GetInstallBotResponse implements Serializable {
private String marketName;
private Integer state;
private String logo;
private Integer isPublic;
private Integer registerId;
private String registerLogin;
private String registerName;

View File

@ -31,4 +31,6 @@ public class InstallBotInfo {
Integer state;
LimitVO limitVO;
String storeRepoIds;
}

View File

@ -26,4 +26,5 @@ public class InstallMarketBotRequest implements Serializable {
private List<Integer> storeList;
//TODO 前端修改
private Map<Integer,String> repoMap;
private Map<Integer, String> repoOwnerMap;
}

View File

@ -0,0 +1,24 @@
package com.gitlink.softbot.vo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class JudgeIsInstallBotResponse {
private List<String> installRepoIds;
private List<String> uninstallRepoIds;
}

View File

@ -23,9 +23,14 @@ public class Limit{
//请求读写权限(0:只读1:读写2:无权限)
private Integer readWritePr;
//权限类型(0:代码仓库权限1:合并请求权限)
//请求读写权限(0:只读1:读写2:无权限)
private Integer readWriteIssue;
//权限类型(0:代码仓库权限1:合并请求权限3:疑修事件权限)
private Integer authCategory;
//代码00:git推送到存储库1:创建分支或标签2:删除分支或标签 请求1 3:合并请求被打开4:合并请求被分配
// (代码00:git推送到存储库1:创建分支或标签2:删除分支或标签)
// (请求1 3:合并请求被打开4:合并请求被分配) 5:无权限
// (疑修3: 6:PR评论被创建编辑或删除 7:ISSUE已打开已关闭已重新打开或编辑 8:ISSUE已被指派或取消指派 9:ISSUE标记被更新或清除 10:ISSUE评论被创建编辑或删除)
private Integer event;
}

View File

@ -26,13 +26,23 @@ public class LimitVO {
*/
private Integer jurisDictionPr;
/**
* 请求权限 0只读1读写2:无权限
*/
private Integer jurisDictionIssue;
/**
* 代码事件012
*/
private String eventCode;
/**
* 请求事件3,4
* 请求事件3,4,6
*/
private String eventPr;
/**
* 请求事件7,8,9,10
*/
private String eventIssue;
}

View File

@ -28,7 +28,14 @@ public class UpdateInstallBotRequest implements Serializable {
@NotNull(message = "state is required")
private Integer state;
private String password;
//待安装仓库id列表
private List<Integer> storeList;
//已安装仓库id列表
private List<Integer> installedStoreList;
//前端修改 storeId-repo
private Map<Integer,String> repoMap;
private Map<Integer, String> repoOwnerMap;
}

View File

@ -25,4 +25,10 @@ public class Webhook {
private String branch_filter;
private Object[] events;
private String type;
public String getType() {
return "softbot";
}
}

View File

@ -5,9 +5,14 @@ es-url:
spring:
datasource:
username: root
password: wu180532 #tonglin0711
url: jdbc:mysql://localhost:3306/soft_bot?useUnicode=true&characterEncoding=UTF-8
password: 123456 #tonglin0711
url: jdbc:mysql://localhost:3306/testforgeplus?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
driver-class-name: com.mysql.cj.jdbc.Driver
dbcp2:
test-on-borrow: false
test-while-idle: true
time-between-eviction-runs-millis: 3600000
elasticsearch:
rest:
uris: http://127.0.0.1:9200

View File

@ -0,0 +1,4 @@
-- ----------------------------
-- 表bot中添加字段 oauth_callback_url : oauth回调地址)
-- ----------------------------
ALTER TABLE `bot` ADD COLUMN (`oauth_callback_url` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'oauth回调地址');

View File

@ -0,0 +1,8 @@
-- 表bot_limit_event中添加字段 read_write_issue:疑修读写权限
ALTER TABLE `bot_limit_event` ADD COLUMN `read_write_issue` TINYINT(4) NOT NULL DEFAULT 2 COMMENT '0:只读 1:读写 2:无权限' AFTER read_write_pr;
-- 表bot_limit_event中拓展字段event枚举 6:PR评论被创建、编辑或删除 7:ISSUE已打开、已关闭、已重新打开或编辑 8:ISSUE已被指派或取消指派 9:ISSUE标记被更新或清除 10:ISSUE评论被创建、编辑或删除
ALTER TABLE `bot_limit_event` MODIFY `event` TINYINT(4) NOT NULL COMMENT '0:git推送到存储库 1:创建分支或标签 2:删除分支或标签 3:PR被打开或重新打开 4:PR被分配 5:无权限 6:PR评论被创建、编辑或删除 7:ISSUE已打开、已关闭、已重新打开或编辑 8:ISSUE已被指派或取消指派 9:ISSUE标记被更新或清除 10:ISSUE评论被创建、编辑或删除'
-- 表bot_limit_event中拓展字段auth_category枚举 3:疑修事件权限
ALTER TABLE `bot_limit_event` MODIFY `auth_category` TINYINT(4) NOT NULL COMMENT '0:代码仓库权限 1:合并请求权限 3:疑修事件权限'

View File

@ -0,0 +1,4 @@
-- ----------------------------
-- 表install_bot中添加字段 repo_owner:仓库拥有者login(组织/个人)
-- ----------------------------
ALTER TABLE `install_bot` ADD COLUMN (`repo_owner` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '仓库拥有者login(组织/个人)');

View File

@ -0,0 +1,4 @@
-- ----------------------------
-- 表install_bot中添加字段 webhook_response_msg:webhook请求返回信息
-- ----------------------------
ALTER TABLE `install_bot` ADD COLUMN `webhook_response_msg` TEXT DEFAULT NULL COMMENT 'webhook请求返回信息' AFTER `webhook_id`;

View File

@ -39,7 +39,7 @@ public class GitLinkApiTest {
@Test
public void activeBotAuthTest(){
Response response = api.activeBotAuth(84993,800,"auth_active");
Response response = api.activeBotAuth(84993,802,"auth_active");
System.out.println(response.getData());
}
@ -57,7 +57,7 @@ public class GitLinkApiTest {
@Test
public void addWebhook() throws JsonProcessingException {
webhooks = new Webhook(true, "json", "GET", "123456", "http://localhost:10000", "*", new Object[]{"push"});
webhooks = new Webhook(true, "json", "GET", "123456", "http://localhost:10000", "*", new Object[]{"push"}, "softbot");
Object[] params = new Object[]{"xxq250", "ruoyi-vue-pro"};
Response response = api.addWebhook(85175,params,webhooks);
System.out.println(response.getData());
@ -65,7 +65,7 @@ public class GitLinkApiTest {
@Test
public void updateWebhook() throws JsonProcessingException {
webhooks = new Webhook(false, "json", "GET", "123456", "http://localhost:10000", "*", new Object[]{"push"});
webhooks = new Webhook(false, "json", "GET", "123456", "http://localhost:10000", "*", new Object[]{"push"}, "softbot");
Object[] params = new Object[]{"xxq250", "ruoyi-vue-pro"};
Response response = api.updateWebhook(85175,params,1082,webhooks);
System.out.println(response.getData());

View File

@ -38,7 +38,7 @@ class RestTemplateUtilTests {
@BeforeEach
public void setUp() {
mapper = new ObjectMapper();
webhooks = new Webhook(true, "json", "GET", "123456", "http://localhost:10000", "*", new Object[]{"push"});
webhooks = new Webhook(true, "json", "GET", "123456", "http://localhost:10000", "*", new Object[]{"push"}, "softbot");
headParams = new HashMap<>();
headParams.put("Authorization", "Bearer "+TOKEN);
}

View File

@ -1,65 +0,0 @@
server:
port: 8080
es-url:
127.0.0.1:9200
spring:
datasource:
username: root
password: wu180532 #tonglin0711
url: jdbc:mysql://localhost:3306/soft_bot?useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.cj.jdbc.Driver
elasticsearch:
rest:
uris: http://127.0.0.1:9200
devtools:
restart:
enabled: true
additional-paths: src/main/java
poll-interval: 3000
quiet-period: 1000
mvc:
view:
prefix: /WEB-INF/jsp/
suffix: .jsp
thymeleaf:
prefix: classpath:/templates/
suffix: .html
encoding: UTF-8
redis:
database: 0
host: 101.35.140.79
port: 6379
# password:
# 连接超时时间
timeout: 10000
password: 123456
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:mapper/*.xml
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.gitlink.softbot.entity
configuration:
map-underscore-to-camel-case: true
#showSql
logging:
level:
com:
example:
mapper : debug
elasticsearch:
url: localhost:9200
gitlink:
url: https://testforgeplus.trustie.net
token: eyJraWQiOiJUaEVSLVl3Ukg4TWYwOHM0UnJLUDYzXzZLWmVET2NZckZXcmdzN2VUVWdrIiwiYWxnIjoiSFM1MTIifQ.eyJpc3MiOiJHaXRMaW5rIiwiaWF0IjoxNjc1NzYyMDkwLCJqdGkiOiI0MzA1ZDUwZC01ZGRkLTQ0MzUtODMyNS1iZDczYmVhMWMxYjciLCJ1c2VyIjp7ImlkIjpudWxsLCJsb2dpbiI6bnVsbCwibWFpbCI6bnVsbH19.hpHCJeU4Jyz-DM2NBUdB-tQW_E0-tu9H3LoGhsJ7kPHkSsdXJCII0jxhyPb9gwDsgd8SnlRZF8tZDDjnZSoztQ

Some files were not shown because too many files have changed in this diff Show More