init
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.gateway.dynamic;
|
||||
|
||||
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinition;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 动态路由业务类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Service
|
||||
public class DynamicRouteService implements ApplicationEventPublisherAware {
|
||||
|
||||
private final RouteDefinitionWriter routeDefinitionWriter;
|
||||
|
||||
private ApplicationEventPublisher publisher;
|
||||
|
||||
public DynamicRouteService(RouteDefinitionWriter routeDefinitionWriter) {
|
||||
this.routeDefinitionWriter = routeDefinitionWriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
||||
this.publisher = applicationEventPublisher;
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加路由
|
||||
*/
|
||||
public String save(RouteDefinition definition) {
|
||||
try {
|
||||
routeDefinitionWriter.save(Mono.just(definition)).subscribe();
|
||||
this.publisher.publishEvent(new RefreshRoutesEvent(this));
|
||||
return "save success";
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "save failure";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新路由
|
||||
*/
|
||||
public String update(RouteDefinition definition) {
|
||||
try {
|
||||
this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
|
||||
this.routeDefinitionWriter.save(Mono.just(definition)).subscribe();
|
||||
this.publisher.publishEvent(new RefreshRoutesEvent(this));
|
||||
return "update success";
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "update failure";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新路由
|
||||
*/
|
||||
public String updateList(List<RouteDefinition> routeDefinitions) {
|
||||
try {
|
||||
if (!routeDefinitions.isEmpty()) {
|
||||
routeDefinitions.forEach(this::update);
|
||||
}
|
||||
return "update done";
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "update failure";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除路由
|
||||
*/
|
||||
public String delete(String id) {
|
||||
try {
|
||||
this.routeDefinitionWriter.delete(Mono.just(id));
|
||||
return "delete success";
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "delete failure";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.gateway.dynamic;
|
||||
|
||||
import com.alibaba.cloud.nacos.NacosConfigProperties;
|
||||
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.nacos.api.NacosFactory;
|
||||
import com.alibaba.nacos.api.PropertyKeyConst;
|
||||
import com.alibaba.nacos.api.config.ConfigService;
|
||||
import com.alibaba.nacos.api.config.listener.Listener;
|
||||
import com.alibaba.nacos.api.exception.NacosException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.core.launch.constant.NacosConstant;
|
||||
import org.springblade.core.launch.props.BladeProperties;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinition;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* 动态路由监听器
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Order
|
||||
@Slf4j
|
||||
@Component
|
||||
@RefreshScope
|
||||
public class DynamicRouteServiceListener {
|
||||
|
||||
private final DynamicRouteService dynamicRouteService;
|
||||
private final NacosDiscoveryProperties nacosDiscoveryProperties;
|
||||
private final NacosConfigProperties nacosConfigProperties;
|
||||
private final BladeProperties bladeProperties;
|
||||
|
||||
public DynamicRouteServiceListener(DynamicRouteService dynamicRouteService, NacosDiscoveryProperties nacosDiscoveryProperties, NacosConfigProperties nacosConfigProperties, BladeProperties bladeProperties) {
|
||||
this.dynamicRouteService = dynamicRouteService;
|
||||
this.nacosDiscoveryProperties = nacosDiscoveryProperties;
|
||||
this.nacosConfigProperties = nacosConfigProperties;
|
||||
this.bladeProperties = bladeProperties;
|
||||
dynamicRouteServiceListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听Nacos下发的动态路由配置
|
||||
*/
|
||||
private void dynamicRouteServiceListener() {
|
||||
try {
|
||||
String dataId = bladeProperties.getName() + "-" + bladeProperties.getEnv() + "." + NacosConstant.NACOS_CONFIG_JSON_FORMAT;
|
||||
String group = nacosConfigProperties.getGroup();
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty(PropertyKeyConst.SERVER_ADDR, nacosDiscoveryProperties.getServerAddr());
|
||||
properties.setProperty(PropertyKeyConst.NAMESPACE, nacosDiscoveryProperties.getNamespace());
|
||||
properties.setProperty(PropertyKeyConst.USERNAME, nacosDiscoveryProperties.getUsername());
|
||||
properties.setProperty(PropertyKeyConst.PASSWORD, nacosDiscoveryProperties.getPassword());
|
||||
ConfigService configService = NacosFactory.createConfigService(properties);
|
||||
configService.addListener(dataId, group, new Listener() {
|
||||
@Override
|
||||
public void receiveConfigInfo(String configInfo) {
|
||||
List<RouteDefinition> routeDefinitions = JSON.parseArray(configInfo, RouteDefinition.class);
|
||||
if (!routeDefinitions.isEmpty()) {
|
||||
dynamicRouteService.updateList(routeDefinitions);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor getExecutor() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
String configInfo = configService.getConfig(dataId, group, 5000);
|
||||
if (configInfo != null) {
|
||||
List<RouteDefinition> routeDefinitions = JSON.parseArray(configInfo, RouteDefinition.class);
|
||||
dynamicRouteService.updateList(routeDefinitions);
|
||||
}
|
||||
} catch (NacosException ignored) {
|
||||
ignored.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.gateway.dynamic;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 过滤器定义模型
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
public class GatewayFilter {
|
||||
|
||||
/**
|
||||
* 过滤器对应的Name
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 对应的路由规则
|
||||
*/
|
||||
private Map<String, String> args = new LinkedHashMap<>();
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.gateway.dynamic;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 路由断言定义模型
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
public class GatewayPredicate {
|
||||
|
||||
/**
|
||||
* 断言对应的Name
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 配置的断言规则
|
||||
*/
|
||||
private Map<String, String> args = new LinkedHashMap<>();
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* BladeX Commercial License Agreement
|
||||
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
|
||||
* <p>
|
||||
* Use of this software is governed by the Commercial License Agreement
|
||||
* obtained after purchasing a license from BladeX.
|
||||
* <p>
|
||||
* 1. This software is for development use only under a valid license
|
||||
* from BladeX.
|
||||
* <p>
|
||||
* 2. Redistribution of this software's source code to any third party
|
||||
* without a commercial license is strictly prohibited.
|
||||
* <p>
|
||||
* 3. Licensees may copyright their own code but cannot use segments
|
||||
* from this software for such purposes. Copyright of this software
|
||||
* remains with BladeX.
|
||||
* <p>
|
||||
* Using this software signifies agreement to this License, and the software
|
||||
* must not be used for illegal purposes.
|
||||
* <p>
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
|
||||
* not liable for any claims arising from secondary or illegal development.
|
||||
* <p>
|
||||
* Author: Chill Zhuang (bladejava@qq.com)
|
||||
*/
|
||||
package org.springblade.gateway.dynamic;
|
||||
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Gateway的路由定义模型
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
public class GatewayRoute {
|
||||
|
||||
/**
|
||||
* 路由的id
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 路由断言集合配置
|
||||
*/
|
||||
private List<GatewayPredicate> predicates = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 路由过滤器集合配置
|
||||
*/
|
||||
private List<GatewayFilter> filters = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* 路由规则转发的目标uri
|
||||
*/
|
||||
private String uri;
|
||||
|
||||
/**
|
||||
* 路由执行的顺序
|
||||
*/
|
||||
private int order = 0;
|
||||
}
|
||||
Reference in New Issue
Block a user