diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/IscConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/IscConstants.java index bbfe503ea..6ca156762 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/IscConstants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/IscConstants.java @@ -23,5 +23,8 @@ public class IscConstants { /** 申请类型 申请修改 */ public static final String APPLY_TYPE_MODIFY = "2"; - + /** + * Gateway 路由信息Redis Key + */ + public static final String KEY_ROUTES = "ROUTES::"; } diff --git a/ruoyi-isc/src/main/java/com/ruoyi/isc/service/impl/IscAppServiceApplyServiceImpl.java b/ruoyi-isc/src/main/java/com/ruoyi/isc/service/impl/IscAppServiceApplyServiceImpl.java index c1c2f307b..256b18b85 100644 --- a/ruoyi-isc/src/main/java/com/ruoyi/isc/service/impl/IscAppServiceApplyServiceImpl.java +++ b/ruoyi-isc/src/main/java/com/ruoyi/isc/service/impl/IscAppServiceApplyServiceImpl.java @@ -13,7 +13,6 @@ import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.PageUtils; import com.ruoyi.common.utils.StringUtils; -import com.ruoyi.isc.utils.RouteUtils; import com.ruoyi.isc.domain.IscAppService; import com.ruoyi.isc.domain.IscAppServiceApply; import com.ruoyi.isc.domain.IscService; @@ -25,6 +24,8 @@ import com.ruoyi.isc.service.IIscAppServiceApplyService; import com.ruoyi.isc.service.IIscAppServiceService; import com.ruoyi.isc.service.IIscApplicationService; import com.ruoyi.isc.service.IIscServiceService; +import com.ruoyi.isc.utils.RouteUtils; +import com.ruoyi.isc.utils.beans.IscRouteDefinition; import org.springframework.stereotype.Service; import javax.annotation.Resource; @@ -157,8 +158,12 @@ public class IscAppServiceApplyServiceImpl extends ServicePlusImpl new ServiceException("申请信息不存在")); IscAppService updateData = null; + IscRouteDefinition route = null; + IscService service = null; if(IscConstants.AUDIT_PASS.equals(bo.getStatus())) { - updateData = genAuditPassData(apply, appService, bo.getStatus()); + service = serviceService.getById(appService.getServiceId()); + Assert.notNull(service, () -> new ServiceException("服务信息不存在")); + updateData = genAuditPassData(apply, appService, service, bo.getStatus()); updateData.setAuditMind(bo.getRemark()); }else{ //如果 应用服务 状态为不通过 时需要同步状态 @@ -166,6 +171,11 @@ public class IscAppServiceApplyServiceImpl extends ServicePlusImpl new ServiceException("服务信息不存在")); Integer renewalDuration = apply.getRenewalDuration(); //如果 申请时长为空,需要查询审核记录 中的审核时长 if(Objects.isNull(renewalDuration)) { diff --git a/ruoyi-isc/src/main/java/com/ruoyi/isc/utils/RouteUtils.java b/ruoyi-isc/src/main/java/com/ruoyi/isc/utils/RouteUtils.java index fb7124e84..737256c90 100644 --- a/ruoyi-isc/src/main/java/com/ruoyi/isc/utils/RouteUtils.java +++ b/ruoyi-isc/src/main/java/com/ruoyi/isc/utils/RouteUtils.java @@ -1,18 +1,34 @@ package com.ruoyi.isc.utils; -import cn.hutool.crypto.SecureUtil; +import com.ruoyi.common.constant.IscConstants; import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.spring.SpringUtils; +import com.ruoyi.isc.domain.IscAppService; +import com.ruoyi.isc.utils.beans.IscFilterDefinition; +import com.ruoyi.isc.utils.beans.IscPredicateDefinition; +import com.ruoyi.isc.utils.beans.IscRouteDefinition; +import org.redisson.api.RMap; +import org.redisson.api.RedissonClient; +import org.redisson.codec.JsonJacksonCodec; import java.net.URI; import java.net.URISyntaxException; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; /** * @author Wenchao Gong * @date 2021/9/10 14:46 */ -public class RouteUtils -{ +public class RouteUtils { + /** + * Gateway 虚拟路径前缀 + */ public static final String PATH_PREFIX = "/proxy"; + private static RedissonClient client = SpringUtils.getBean(RedissonClient.class); /** * 获取虚拟URL Path 部分 @@ -20,17 +36,142 @@ public class RouteUtils * @param applicationId 应用ID * @param serviceId 服务Id * @param serviceAddr 服务地址 - * @return + * @return 虚拟地址Path */ public static String genVirtualAddrPath(Long applicationId, Long serviceId, String serviceAddr) { - URI uri = null; - try { - uri = new URI(serviceAddr); - return PATH_PREFIX + uri.getPath(); - } catch (URISyntaxException e) { + return PATH_PREFIX + getPathUri(serviceAddr); + } + + /** + * 返回URI 的Path部分 + * + * @param uri URI + * @return path + */ + public static String getPathUri(String uri) + { + return getURI(uri).getPath(); + } + + /** + * 通过 URI字符串 生成URI对象 + * + * @param uri URI字符串 + * @return URI + */ + public static URI getURI(String uri) + { + try + { + return new URI(uri); + } catch (URISyntaxException e) + { throw new ServiceException("URL格式异常"); } } + /** + * 刷新路由信息 先清空再批量新增 + * + * @param routes 路由信息 + * @return 是否成功 + */ + public static boolean refreshRoute(List routes) + { + Map routeMap = routes.stream().collect(Collectors.toMap(IscRouteDefinition::getId, + Function.identity(), (o1, o2) -> o2)); + final RMap map = client.getMap(IscConstants.KEY_ROUTES); + map.clear(); + map.putAll(routeMap); + return true; + } + + /** + * 保存路由信息 + * + * @param route 路由信息 + * @return 是否成功 + */ + public static boolean saveRoute(IscRouteDefinition route) + { + final RMap map = client.getMap(IscConstants.KEY_ROUTES); + map.put(route.getId(), route); + return true; + } + + /** + * 删除路由信息 + * + * @param routeId 路由ID + * @return 是否成功 + */ + public static boolean deleteRoute(String routeId) + { + final RMap map = client.getMap(IscConstants.KEY_ROUTES); + map.remove(routeId); + return true; + } + + /** + * 更新路由信息 + * + * @param route 路由信息 + * @return 是否成功 + */ + public static boolean updateRoute(IscRouteDefinition route) + { + return saveRoute(route); + } + + /** + * 生成 路由信息 + * + * @param appService 应用服务信息 + * @param serviceAddr 服务地址 + * @return 路由信息 + */ + public static IscRouteDefinition generateRoute(IscAppService appService, String serviceAddr) + { + IscRouteDefinition route = new IscRouteDefinition(); + route.setId(String.valueOf(appService.getAppServiceId())); + route.setUri(getURI(serviceAddr.substring(0, serviceAddr.length() - getPathUri(serviceAddr).length()))); + + //断言 + IscPredicateDefinition pathPredicate = new IscPredicateDefinition(); + pathPredicate.setName("Path"); + pathPredicate.getArgs().put("pattern", appService.getVirtualAddr()); + route.setPredicates(Arrays.asList(pathPredicate)); + + //过滤器 + IscFilterDefinition stripPrefixFilter = new IscFilterDefinition(); + stripPrefixFilter.setName("StripPrefix"); + stripPrefixFilter.getArgs().put("parts", "1"); + + IscFilterDefinition retryFilter = new IscFilterDefinition(); + retryFilter.setName("Retry"); + retryFilter.getArgs().put("retries", "1"); + route.setFilters(Arrays.asList(stripPrefixFilter, retryFilter)); + + //其他信息 + Map metadata = route.getMetadata(); + metadata.put("secondsLimit", toString(appService.getQuotaSeconds())); + metadata.put("minutesLimit", toString(appService.getQuotaMinutes())); + metadata.put("hoursLimit", toString(appService.getQuotaHours())); + metadata.put("daysLimit", toString(appService.getQuotaDays())); + metadata.put("expire", toString(appService.getEndTime())); + return route; + } + + /** + * 对象转字符串 + * + * @param obj 具体属性 + * @return + */ + public static String toString(Object obj) + { + return Objects.isNull(obj) ? StringUtils.EMPTY : obj instanceof Date ? + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, (Date) obj) : String.valueOf(obj); + } } diff --git a/ruoyi-isc/src/main/java/com/ruoyi/isc/utils/beans/IscFilterDefinition.java b/ruoyi-isc/src/main/java/com/ruoyi/isc/utils/beans/IscFilterDefinition.java new file mode 100644 index 000000000..ffee7ab81 --- /dev/null +++ b/ruoyi-isc/src/main/java/com/ruoyi/isc/utils/beans/IscFilterDefinition.java @@ -0,0 +1,22 @@ +package com.ruoyi.isc.utils.beans; + +import lombok.Data; +import org.springframework.validation.annotation.Validated; + +import javax.validation.constraints.NotNull; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author Wenchao Gong + * @date 2021-09-28 + */ +@Data +@Validated +public class IscFilterDefinition { + + @NotNull + private String name; + + private Map args = new LinkedHashMap<>(); +} diff --git a/ruoyi-isc/src/main/java/com/ruoyi/isc/utils/beans/IscPredicateDefinition.java b/ruoyi-isc/src/main/java/com/ruoyi/isc/utils/beans/IscPredicateDefinition.java new file mode 100644 index 000000000..efcee83c1 --- /dev/null +++ b/ruoyi-isc/src/main/java/com/ruoyi/isc/utils/beans/IscPredicateDefinition.java @@ -0,0 +1,22 @@ +package com.ruoyi.isc.utils.beans; + +import lombok.Data; +import org.springframework.validation.annotation.Validated; + +import javax.validation.constraints.NotNull; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author Wenchao Gong + * @date 2021-09-28 + */ +@Data +@Validated +public class IscPredicateDefinition { + + @NotNull + private String name; + + private Map args = new LinkedHashMap<>(); +} diff --git a/ruoyi-isc/src/main/java/com/ruoyi/isc/utils/beans/IscRouteDefinition.java b/ruoyi-isc/src/main/java/com/ruoyi/isc/utils/beans/IscRouteDefinition.java new file mode 100644 index 000000000..f5cbb42d2 --- /dev/null +++ b/ruoyi-isc/src/main/java/com/ruoyi/isc/utils/beans/IscRouteDefinition.java @@ -0,0 +1,38 @@ +package com.ruoyi.isc.utils.beans; + +import lombok.Data; +import org.springframework.validation.annotation.Validated; + +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Wenchao Gong + * @date 2021-09-28 + */ +@Data +@Validated +public class IscRouteDefinition { + + private String id; + + @NotEmpty + @Valid + private List predicates = new ArrayList<>(); + + @Valid + private List filters = new ArrayList<>(); + + @NotNull + private URI uri; + + private Map metadata = new HashMap<>(); + + private int order = 0; +}