mirror of
https://gitee.com/durcframework/SOP.git
synced 2025-08-11 12:56:28 +08:00
init
This commit is contained in:
@@ -20,6 +20,11 @@
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-service-common</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-book-api</artifactId>
|
||||
|
@@ -0,0 +1,22 @@
|
||||
package com.gitee.sop.bookweb.config;
|
||||
|
||||
import com.gitee.sop.servercommon.configuration.AlipayServiceConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 使用支付宝开放平台功能
|
||||
* @author tanghc
|
||||
*/
|
||||
@Configuration
|
||||
public class OpenServiceConfig extends AlipayServiceConfiguration {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用淘宝开放平台功能
|
||||
* @author tanghc
|
||||
*/
|
||||
//@Configuration
|
||||
//public class OpenServiceConfig extends TaobaoServiceConfiguration {
|
||||
//
|
||||
//}
|
@@ -0,0 +1,40 @@
|
||||
package com.gitee.sop.bookweb.controller;
|
||||
|
||||
import com.gitee.sop.bookweb.consumer.StoryServiceConsumer;
|
||||
import com.gitee.sop.servercommon.annotation.ApiMapping;
|
||||
import com.gitee.sop.story.api.domain.Story;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* 支付宝服务端,假设签名验证通过后,到达这里进行具体的业务处理。
|
||||
* 这里演示如何接受业务参数。
|
||||
* @author tanghc
|
||||
*/
|
||||
@RestController
|
||||
public class AlipayBookController {
|
||||
|
||||
@Autowired
|
||||
StoryServiceConsumer storyServiceConsumer;
|
||||
|
||||
@ApiMapping(value = "alipay.book.get")
|
||||
public Story getBook() {
|
||||
Story story = new Story();
|
||||
story.setId(1);
|
||||
story.setName("白雪公主(alipay.book.get)");
|
||||
return story;
|
||||
}
|
||||
|
||||
// 调用story服务
|
||||
@ApiMapping(value = "alipay.book.story.get")
|
||||
public Object getBook2() {
|
||||
Story story = new Story();
|
||||
story.setId(1);
|
||||
story.setName("白雪公主(alipay.book.story.get)");
|
||||
Story story2 = storyServiceConsumer.getStory(1);
|
||||
return Arrays.asList(story, story2);
|
||||
}
|
||||
|
||||
}
|
@@ -1,6 +0,0 @@
|
||||
server.port=3333
|
||||
spring.application.name=book-service
|
||||
eureka.host=localhost
|
||||
eureka.port=1111
|
||||
eureka.client.serviceUrl.defaultZone=http://${eureka.host}:${eureka.port}/eureka/
|
||||
|
9
sop-book/sop-book-web/src/main/resources/application.yml
Normal file
9
sop-book/sop-book-web/src/main/resources/application.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
server:
|
||||
port: 3333
|
||||
|
||||
eureka:
|
||||
port: 1111
|
||||
host: localhost
|
||||
client:
|
||||
serviceUrl:
|
||||
defaultZone: http://${eureka.host}:${eureka.port}/eureka/
|
7
sop-book/sop-book-web/src/main/resources/bootstrap.yml
Normal file
7
sop-book/sop-book-web/src/main/resources/bootstrap.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
spring:
|
||||
application:
|
||||
name: book-service
|
||||
|
||||
cloud:
|
||||
zookeeper:
|
||||
connect-string: localhost:2181
|
@@ -4,6 +4,9 @@ import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author thc
|
||||
*/
|
||||
@Data
|
||||
public class BaseServiceRouteInfo<T extends BaseRouteDefinition> {
|
||||
private String appName;
|
||||
|
@@ -0,0 +1,38 @@
|
||||
package com.gitee.sop.gatewaycommon.bean;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public abstract class ServiceRouteRepository<R, E> {
|
||||
/**
|
||||
* key:serviceId
|
||||
*/
|
||||
private Map<String, Set<E>> serviceRouteMap = new ConcurrentHashMap<>();
|
||||
|
||||
public abstract String getServiceId(R r);
|
||||
|
||||
public void saveRouteDefinition(R serviceRouteInfo, E definition) {
|
||||
String serverId = getServiceId(serviceRouteInfo);
|
||||
Set<E> routeDefinitionSet = serviceRouteMap.putIfAbsent(serverId, new HashSet<>(16));
|
||||
if (routeDefinitionSet == null) {
|
||||
routeDefinitionSet = serviceRouteMap.get(serverId);
|
||||
}
|
||||
routeDefinitionSet.add(definition);
|
||||
}
|
||||
|
||||
public synchronized void deleteAll(R serviceRouteInfo, Consumer<E> consumer) {
|
||||
String serverId = getServiceId(serviceRouteInfo);
|
||||
Set<E> definitionSet = serviceRouteMap.getOrDefault(serverId, Collections.emptySet());
|
||||
for (E routeDefinition : definitionSet) {
|
||||
consumer.accept(routeDefinition);
|
||||
}
|
||||
definitionSet.clear();
|
||||
}
|
||||
}
|
@@ -26,6 +26,10 @@ import reactor.core.publisher.Mono;
|
||||
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR;
|
||||
|
||||
/**
|
||||
* 修改返回结果
|
||||
* @author thc
|
||||
*/
|
||||
public class GatewayModifyResponseGatewayFilter implements GlobalFilter, Ordered {
|
||||
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package com.gitee.sop.gatewaycommon.gateway.filter;
|
||||
|
||||
import com.gitee.sop.gatewaycommon.util.RoutePathUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
|
||||
import org.springframework.cloud.gateway.filter.GlobalFilter;
|
||||
@@ -15,10 +16,9 @@ import java.net.URI;
|
||||
import static org.springframework.cloud.gateway.filter.LoadBalancerClientFilter.LOAD_BALANCER_CLIENT_FILTER_ORDER;
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR;
|
||||
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.containsEncodedParts;
|
||||
|
||||
/**
|
||||
* 在LoadBalancerClientFilter后面处理,处理成我们想要的uri
|
||||
* 在LoadBalancerClientFilter后面处理,从Route中找到具体的path,然后插入到uri的path中
|
||||
*
|
||||
* @author tanghc
|
||||
*/
|
||||
@@ -32,25 +32,22 @@ public class LoadBalancerClientExtFilter implements GlobalFilter, Ordered {
|
||||
|
||||
@Override
|
||||
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
|
||||
URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
|
||||
Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
|
||||
URI routeUri = route.getUri();
|
||||
|
||||
URI requestUrl = url;
|
||||
|
||||
String uriStr = routeUri.toString();
|
||||
String[] uriArr = uriStr.split("\\#");
|
||||
if (uriArr.length == 2) {
|
||||
String path = uriArr[1];
|
||||
String path = this.findPath(route);
|
||||
if (StringUtils.hasLength(path)) {
|
||||
URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
|
||||
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromUri(url);
|
||||
if (StringUtils.hasLength(path)) {
|
||||
uriComponentsBuilder.path(path);
|
||||
}
|
||||
requestUrl = uriComponentsBuilder.build(true).toUri();
|
||||
uriComponentsBuilder.path(path);
|
||||
URI requestUrl = uriComponentsBuilder.build(true).toUri();
|
||||
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
|
||||
}
|
||||
|
||||
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
|
||||
protected String findPath(Route route) {
|
||||
URI routeUri = route.getUri();
|
||||
String uriStr = routeUri.toString();
|
||||
return RoutePathUtil.findPath(uriStr);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -39,7 +39,7 @@ public class GatewayExceptionHandler implements ErrorWebExceptionHandler {
|
||||
* 错误记录
|
||||
*/
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
log.error("[全局异常处理]异常请求路径:{},记录异常信息:{}", request.getPath(), ex.getMessage());
|
||||
log.error("[全局异常处理]异常请求路径:{}, msg:{}", request.getPath(), ex.getMessage(), ex);
|
||||
/**
|
||||
* 参考AbstractErrorWebExceptionHandler
|
||||
*/
|
||||
|
@@ -1,74 +1,123 @@
|
||||
package com.gitee.sop.gatewaycommon.gateway.route;
|
||||
|
||||
import com.gitee.sop.gatewaycommon.bean.ServiceRouteRepository;
|
||||
import com.gitee.sop.gatewaycommon.manager.RouteRepository;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.gateway.event.PredicateArgsEvent;
|
||||
import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
|
||||
import org.springframework.cloud.gateway.handler.predicate.PredicateDefinition;
|
||||
import org.springframework.cloud.gateway.handler.predicate.RoutePredicateFactory;
|
||||
import org.springframework.cloud.gateway.route.InMemoryRouteDefinitionRepository;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinition;
|
||||
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
|
||||
import org.springframework.cloud.gateway.support.NotFoundException;
|
||||
import org.springframework.cloud.gateway.support.ConfigurationUtils;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.ApplicationEventPublisherAware;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.validation.Validator;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 动态更新路由
|
||||
* 路由存储管理,负责动态更新路由
|
||||
*
|
||||
* @author thc
|
||||
*/
|
||||
@Slf4j
|
||||
public class GatewayRouteRepository implements ApplicationEventPublisherAware, RouteRepository<RouteDefinition> {
|
||||
public class GatewayRouteRepository extends InMemoryRouteDefinitionRepository
|
||||
implements ApplicationEventPublisherAware,
|
||||
BeanFactoryAware,
|
||||
RouteRepository<GatewayServiceRouteInfo, RouteDefinition> {
|
||||
|
||||
private final SpelExpressionParser parser = new SpelExpressionParser();
|
||||
|
||||
private ServiceRouteRepository<GatewayServiceRouteInfo, RouteDefinition> serviceRouteRepository = new ServiceRouteRepository<GatewayServiceRouteInfo, RouteDefinition>() {
|
||||
@Override
|
||||
public String getServiceId(GatewayServiceRouteInfo serviceRouteInfo) {
|
||||
return serviceRouteInfo.getAppName();
|
||||
}
|
||||
};
|
||||
|
||||
@Autowired
|
||||
private RouteDefinitionRepository routeDefinitionRepository;
|
||||
private ConversionService conversionService;
|
||||
|
||||
@Autowired
|
||||
private Validator validator;
|
||||
|
||||
private ApplicationEventPublisher publisher;
|
||||
|
||||
/** 根据ID获取路由 */
|
||||
private BeanFactory beanFactory;
|
||||
|
||||
/**
|
||||
* 根据ID获取路由
|
||||
*/
|
||||
@Override
|
||||
public RouteDefinition get(String id) {
|
||||
return routeDefinitionRepository.getRouteDefinitions()
|
||||
return getRouteDefinitions()
|
||||
.filter(routeDefinition -> {
|
||||
return routeDefinition.getId().equals(id);
|
||||
}).blockFirst();
|
||||
}
|
||||
|
||||
/** 增加路由 */
|
||||
/**
|
||||
* 增加路由
|
||||
*/
|
||||
@Override
|
||||
public String add(RouteDefinition definition) {
|
||||
routeDefinitionRepository.save(Mono.just(definition)).subscribe();
|
||||
public String add(GatewayServiceRouteInfo serviceRouteInfo, RouteDefinition definition) {
|
||||
super.save(Mono.just(definition)).subscribe();
|
||||
serviceRouteRepository.saveRouteDefinition(serviceRouteInfo, definition);
|
||||
this.initPredicateDefinition(definition);
|
||||
this.publisher.publishEvent(new RefreshRoutesEvent(this));
|
||||
return "success";
|
||||
}
|
||||
|
||||
/** 更新路由 */
|
||||
@Override
|
||||
public String update(RouteDefinition definition) {
|
||||
log.info("更新route,id:{}", definition.getId());
|
||||
try {
|
||||
this.routeDefinitionRepository.delete(Mono.just(definition.getId()));
|
||||
} catch (Exception e) {
|
||||
return "update fail,not find route routeId: " + definition.getId();
|
||||
}
|
||||
try {
|
||||
routeDefinitionRepository.save(Mono.just(definition)).subscribe();
|
||||
this.publisher.publishEvent(new RefreshRoutesEvent(this));
|
||||
return "success";
|
||||
} catch (Exception e) {
|
||||
return "update route fail";
|
||||
protected void initPredicateDefinition(RouteDefinition definition) {
|
||||
for (PredicateDefinition predicate : definition.getPredicates()) {
|
||||
Map<String, String> args = predicate.getArgs();
|
||||
if (!args.isEmpty()) {
|
||||
RoutePredicateFactory<NameVersionRoutePredicateFactory.Config> factory = new NameVersionRoutePredicateFactory();
|
||||
Map<String, Object> properties = factory.shortcutType().normalize(args, factory, this.parser, this.beanFactory);
|
||||
Object config = factory.newConfig();
|
||||
ConfigurationUtils.bind(config, properties, factory.shortcutFieldPrefix(), predicate.getName(),
|
||||
validator, conversionService);
|
||||
this.publisher.publishEvent(new PredicateArgsEvent(this, definition.getId(), properties));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** 删除路由 */
|
||||
/**
|
||||
* 删除路由
|
||||
*/
|
||||
@Override
|
||||
public void delete(String id) {
|
||||
this.routeDefinitionRepository.delete(Mono.just(id))
|
||||
.then(Mono.defer(() -> Mono.just(ResponseEntity.ok().build())))
|
||||
.onErrorResume(t -> t instanceof NotFoundException, t -> Mono.just(ResponseEntity.notFound().build()));
|
||||
super.delete(Mono.just(id));
|
||||
this.publisher.publishEvent(new PredicateArgsEvent(this, id, Collections.emptyMap()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteAll(GatewayServiceRouteInfo serviceRouteInfo) {
|
||||
serviceRouteRepository.deleteAll(serviceRouteInfo, routeDefinition -> {
|
||||
this.delete(routeDefinition.getId());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
||||
this.publisher = applicationEventPublisher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
}
|
@@ -21,9 +21,9 @@ import java.util.List;
|
||||
*/
|
||||
@Getter
|
||||
@Slf4j
|
||||
public class GatewayZookeeperRouteManager extends BaseRouteManager<GatewayRouteDefinition, GatewayServiceRouteInfo, RouteDefinition> {
|
||||
public class GatewayZookeeperRouteManager extends BaseRouteManager<GatewayServiceRouteInfo, GatewayRouteDefinition, RouteDefinition> {
|
||||
|
||||
public GatewayZookeeperRouteManager(Environment environment, RouteRepository<RouteDefinition> routeRepository) {
|
||||
public GatewayZookeeperRouteManager(Environment environment, RouteRepository<GatewayServiceRouteInfo, RouteDefinition> routeRepository) {
|
||||
super(environment, routeRepository);
|
||||
}
|
||||
|
||||
@@ -32,11 +32,6 @@ public class GatewayZookeeperRouteManager extends BaseRouteManager<GatewayRouteD
|
||||
return GatewayServiceRouteInfo.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<GatewayRouteDefinition> getRouteDefinitionClass() {
|
||||
return GatewayRouteDefinition.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RouteDefinition buildRouteDefinition(GatewayServiceRouteInfo serviceRouteInfo,GatewayRouteDefinition gatewayRouteDefinition) {
|
||||
RouteDefinition routeDefinition = new RouteDefinition();
|
||||
|
@@ -18,25 +18,29 @@ import java.util.List;
|
||||
|
||||
import static com.gitee.sop.gatewaycommon.bean.SopConstants.SOP_SERVICE_API_PATH;
|
||||
|
||||
|
||||
/**
|
||||
* 路由管理
|
||||
*
|
||||
* @param <R> 路由根对象,可以理解为最外面的大json:{....,routeDefinitionList:[]}
|
||||
* @param <E> 路由Item对象,对应大json里面的具体路由信息,routeDefinitionList:[]
|
||||
* @param <T> 目标路由对象,返回最终的路由对象
|
||||
* @author tanghc
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class BaseRouteManager<E extends BaseRouteDefinition,R extends BaseServiceRouteInfo<E>, T> implements RouteManager {
|
||||
public abstract class BaseRouteManager<R extends BaseServiceRouteInfo<E>, E extends BaseRouteDefinition, T> implements RouteManager {
|
||||
|
||||
protected String sopServiceApiPath = SOP_SERVICE_API_PATH;
|
||||
|
||||
protected Environment environment;
|
||||
|
||||
protected RouteRepository<T> routeRepository;
|
||||
protected RouteRepository<R, T> routeRepository;
|
||||
|
||||
protected abstract Class<R> getServiceRouteInfoClass();
|
||||
|
||||
protected abstract Class<E> getRouteDefinitionClass();
|
||||
|
||||
protected abstract T buildRouteDefinition(R serviceRouteInfo, E routeDefinition);
|
||||
|
||||
public BaseRouteManager(Environment environment, RouteRepository<T> routeRepository) {
|
||||
public BaseRouteManager(Environment environment, RouteRepository<R, T> routeRepository) {
|
||||
this.environment = environment;
|
||||
this.routeRepository = routeRepository;
|
||||
}
|
||||
@@ -91,7 +95,7 @@ public abstract class BaseRouteManager<E extends BaseRouteDefinition,R extends B
|
||||
R serviceRouteInfo = JSON.parseObject(nodeData, getServiceRouteInfoClass());
|
||||
for (E routeDefinitionItem : serviceRouteInfo.getRouteDefinitionList()) {
|
||||
T routeDefinition = buildRouteDefinition(serviceRouteInfo, routeDefinitionItem);
|
||||
routeRepository.add(routeDefinition);
|
||||
routeRepository.add(serviceRouteInfo, routeDefinition);
|
||||
}
|
||||
}
|
||||
// 添加事件监听器
|
||||
@@ -99,32 +103,34 @@ public abstract class BaseRouteManager<E extends BaseRouteDefinition,R extends B
|
||||
@Override
|
||||
public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent event) throws Exception {
|
||||
PathChildrenCacheEvent.Type type = event.getType();
|
||||
// 通过判断event type的方式来实现不同事件的触发
|
||||
if (PathChildrenCacheEvent.Type.CHILD_ADDED.equals(type)) {
|
||||
String nodeData = new String(event.getData().getData());
|
||||
R serviceRouteInfo = JSON.parseObject(nodeData, getServiceRouteInfoClass());
|
||||
// 添加子节点时触发
|
||||
log.info("子节点:{}添加,数据为:{}", event.getData().getPath(), nodeData);
|
||||
for (E routeDefinitionItem : serviceRouteInfo.getRouteDefinitionList()) {
|
||||
T routeDefinition = buildRouteDefinition(serviceRouteInfo, routeDefinitionItem);
|
||||
routeRepository.add(routeDefinition);
|
||||
}
|
||||
} else if (PathChildrenCacheEvent.Type.CHILD_UPDATED.equals(type)) {
|
||||
String nodeData = new String(event.getData().getData());
|
||||
R serviceRouteInfo = JSON.parseObject(nodeData, getServiceRouteInfoClass());
|
||||
// 修改子节点数据时触发
|
||||
log.info("子节点:{}修改,数据为:{}", event.getData().getPath(), nodeData);
|
||||
for (E routeDefinitionItem : serviceRouteInfo.getRouteDefinitionList()) {
|
||||
T routeDefinition = buildRouteDefinition(serviceRouteInfo, routeDefinitionItem);
|
||||
routeRepository.update(routeDefinition);
|
||||
}
|
||||
} else if (PathChildrenCacheEvent.Type.CHILD_REMOVED.equals(type)) {
|
||||
String nodeData = new String(event.getData().getData());
|
||||
R serviceRouteInfo = JSON.parseObject(nodeData, getServiceRouteInfoClass());
|
||||
// 删除子节点时触发
|
||||
log.info("子节点:{}删除,数据为:{}", event.getData().getPath(), nodeData);
|
||||
for (E routeDefinitionItem : serviceRouteInfo.getRouteDefinitionList()) {
|
||||
routeRepository.delete(routeDefinitionItem.getId());
|
||||
synchronized (type) {
|
||||
// 通过判断event type的方式来实现不同事件的触发
|
||||
if (PathChildrenCacheEvent.Type.CHILD_ADDED.equals(type)) {
|
||||
String nodeData = new String(event.getData().getData());
|
||||
R serviceRouteInfo = JSON.parseObject(nodeData, getServiceRouteInfoClass());
|
||||
// 添加子节点时触发
|
||||
log.info("子节点:{}添加,数据为:{}", event.getData().getPath(), nodeData);
|
||||
for (E routeDefinitionItem : serviceRouteInfo.getRouteDefinitionList()) {
|
||||
T routeDefinition = buildRouteDefinition(serviceRouteInfo, routeDefinitionItem);
|
||||
routeRepository.add(serviceRouteInfo, routeDefinition);
|
||||
}
|
||||
} else if (PathChildrenCacheEvent.Type.CHILD_UPDATED.equals(type)) {
|
||||
String nodeData = new String(event.getData().getData());
|
||||
R serviceRouteInfo = JSON.parseObject(nodeData, getServiceRouteInfoClass());
|
||||
// 修改子节点数据时触发
|
||||
log.info("子节点:{}修改,数据为:{}", event.getData().getPath(), nodeData);
|
||||
// 删除下面所有节点
|
||||
routeRepository.deleteAll(serviceRouteInfo);
|
||||
// 添加新节点
|
||||
for (E routeDefinitionItem : serviceRouteInfo.getRouteDefinitionList()) {
|
||||
T routeDefinition = buildRouteDefinition(serviceRouteInfo, routeDefinitionItem);
|
||||
routeRepository.add(serviceRouteInfo, routeDefinition);
|
||||
}
|
||||
} else if (PathChildrenCacheEvent.Type.CHILD_REMOVED.equals(type)) {
|
||||
String nodeData = new String(event.getData().getData());
|
||||
log.info("子节点:{}删除,数据为:{}", event.getData().getPath(), nodeData);
|
||||
R serviceRouteInfo = JSON.parseObject(nodeData, getServiceRouteInfoClass());
|
||||
routeRepository.deleteAll(serviceRouteInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,12 +3,12 @@ package com.gitee.sop.gatewaycommon.manager;
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public interface RouteRepository<T> {
|
||||
public interface RouteRepository<R, T> {
|
||||
T get(String id);
|
||||
|
||||
String add(T route);
|
||||
|
||||
String update(T route);
|
||||
String add(R serviceRouteInfo, T route);
|
||||
|
||||
void delete(String id);
|
||||
|
||||
void deleteAll(R serviceRouteInfo);
|
||||
}
|
||||
|
@@ -2,8 +2,11 @@ package com.gitee.sop.gatewaycommon.message;
|
||||
|
||||
import com.gitee.sop.gatewaycommon.bean.ApiContext;
|
||||
import com.gitee.sop.gatewaycommon.exception.ApiException;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import lombok.Getter;
|
||||
import sun.plugin.cache.CacheUpdateHelper;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
@@ -37,7 +40,7 @@ public class ErrorMeta {
|
||||
* @return 返回exception
|
||||
*/
|
||||
public ApiException getException(Object... params) {
|
||||
Locale locale = ZH_CN;
|
||||
Locale locale = getLocale();
|
||||
if (params != null && params.length == 1) {
|
||||
Object param = params[0];
|
||||
if (param instanceof Throwable) {
|
||||
@@ -52,4 +55,13 @@ public class ErrorMeta {
|
||||
return new ApiException(error);
|
||||
}
|
||||
|
||||
protected Locale getLocale() {
|
||||
RequestContext currentContext = RequestContext.getCurrentContext();
|
||||
if (currentContext == null) {
|
||||
return ZH_CN;
|
||||
}
|
||||
HttpServletRequest request = currentContext.getRequest();
|
||||
return request == null ? ZH_CN : request.getLocale();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ import com.gitee.sop.gatewaycommon.message.ErrorEnum;
|
||||
import com.gitee.sop.gatewaycommon.message.ErrorMeta;
|
||||
import com.gitee.sop.gatewaycommon.param.ParamNames;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -23,6 +24,10 @@ public abstract class BaseExecutorAdapter<T, R> implements ResultExecutor<T, R>
|
||||
public static final String GATEWAY_CODE_NAME = "code";
|
||||
public static final String GATEWAY_MSG_NAME = "msg";
|
||||
public static final String DATA_SUFFIX = "_response";
|
||||
public static final String ARRAY_START = "[";
|
||||
public static final String ARRAY_END = "]";
|
||||
public static final String ROOT_JSON = "{'items':%s}".replace("'", "\"");
|
||||
|
||||
|
||||
/**
|
||||
* 获取业务方约定的返回码
|
||||
@@ -40,6 +45,7 @@ public abstract class BaseExecutorAdapter<T, R> implements ResultExecutor<T, R>
|
||||
|
||||
@Override
|
||||
public String mergeResult(T request, String serviceResult) {
|
||||
serviceResult = wrapResult(serviceResult);
|
||||
int responseStatus = this.getBizHeaderCode(request);
|
||||
JSONObject jsonObjectService;
|
||||
if (responseStatus == HttpStatus.OK.value()) {
|
||||
@@ -62,6 +68,20 @@ public abstract class BaseExecutorAdapter<T, R> implements ResultExecutor<T, R>
|
||||
return this.merge(request, jsonObjectService);
|
||||
}
|
||||
|
||||
protected String wrapResult(String serviceResult) {
|
||||
if (serviceResult == null) {
|
||||
serviceResult = "";
|
||||
}
|
||||
serviceResult = serviceResult.trim();
|
||||
if (StringUtils.isEmpty(serviceResult)) {
|
||||
return SopConstants.EMPTY_JSON;
|
||||
}
|
||||
if (serviceResult.startsWith(ARRAY_START) && serviceResult.endsWith(ARRAY_END)) {
|
||||
return String.format(ROOT_JSON, serviceResult);
|
||||
}
|
||||
return serviceResult;
|
||||
}
|
||||
|
||||
public String merge(T exchange, JSONObject jsonObjectService) {
|
||||
JSONObject ret = new JSONObject();
|
||||
// 点换成下划线
|
||||
|
@@ -0,0 +1,23 @@
|
||||
package com.gitee.sop.gatewaycommon.util;
|
||||
|
||||
import org.springframework.cloud.gateway.route.Route;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public class RoutePathUtil {
|
||||
|
||||
public static final String REGEX = "\\#";
|
||||
|
||||
public static String findPath(String uri) {
|
||||
// #后面是对应的path
|
||||
String[] uriArr = uri.split(REGEX);
|
||||
if (uriArr.length == 2) {
|
||||
return uriArr[1];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -36,6 +36,11 @@ public class BaseZuulConfiguration {
|
||||
@Autowired
|
||||
protected RouteManager apiMetaManager;
|
||||
|
||||
@Bean
|
||||
SopRouteLocator sopRouteLocator(ZuulRouteRepository zuulRouteRepository) {
|
||||
return new SopRouteLocator(zuulRouteRepository);
|
||||
}
|
||||
|
||||
@Bean
|
||||
ZuulZookeeperRouteManager zuulZookeeperRouteManager(Environment environment, ZuulRouteRepository zuulRouteRepository) {
|
||||
return new ZuulZookeeperRouteManager(environment, zuulRouteRepository);
|
||||
|
@@ -1,41 +0,0 @@
|
||||
package com.gitee.sop.gatewaycommon.zuul.filter;
|
||||
|
||||
import com.gitee.sop.gatewaycommon.message.ErrorEnum;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import com.netflix.zuul.exception.ZuulException;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public class PreTokenFilter extends BaseZuulFilter {
|
||||
|
||||
@Override
|
||||
protected FilterType getFilterType() {
|
||||
return FilterType.PRE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getFilterOrder() {
|
||||
return FilterConstants.PRE_DECORATION_FILTER_ORDER + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object doRun(RequestContext ctx) throws ZuulException {
|
||||
Object serviceId = ctx.get(FilterConstants.SERVICE_ID_KEY);
|
||||
log.info("serviceId:{}", serviceId);
|
||||
HttpServletRequest request = ctx.getRequest();
|
||||
|
||||
log.info("send {} request to {}", request.getMethod(), request.getRequestURL().toString());
|
||||
|
||||
String accessToken = request.getParameter("access_token");
|
||||
if (StringUtils.isBlank(accessToken)) {
|
||||
throw ErrorEnum.AOP_INVALID_APP_AUTH_TOKEN.getErrorMeta().getException();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -7,6 +7,7 @@ import com.gitee.sop.gatewaycommon.exception.ApiException;
|
||||
import com.gitee.sop.gatewaycommon.message.Error;
|
||||
import com.gitee.sop.gatewaycommon.message.ErrorEnum;
|
||||
import com.gitee.sop.gatewaycommon.result.BaseExecutorAdapter;
|
||||
import com.gitee.sop.gatewaycommon.zuul.ZuulContext;
|
||||
import com.netflix.zuul.context.RequestContext;
|
||||
import com.netflix.zuul.exception.ZuulException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -34,7 +35,7 @@ public class ZuulResultExecutor extends BaseExecutorAdapter<RequestContext, Stri
|
||||
|
||||
@Override
|
||||
public Map<String, ?> getApiParam(RequestContext requestContext) {
|
||||
return (Map<String, ?>) requestContext.get(SopConstants.CACHE_API_PARAM);
|
||||
return ZuulContext.getApiParam();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -16,10 +16,10 @@ import java.util.List;
|
||||
*/
|
||||
public class SopRouteLocator implements RouteLocator, Ordered {
|
||||
|
||||
private RouteRepository<Route> routeRepository;
|
||||
private ZuulRouteRepository zuulRouteRepository;
|
||||
|
||||
public SopRouteLocator(RouteRepository<Route> routeRepository) {
|
||||
this.routeRepository = routeRepository;
|
||||
public SopRouteLocator(ZuulRouteRepository zuulRouteRepository) {
|
||||
this.zuulRouteRepository = zuulRouteRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -29,14 +29,14 @@ public class SopRouteLocator implements RouteLocator, Ordered {
|
||||
|
||||
@Override
|
||||
public List<Route> getRoutes() {
|
||||
return null;
|
||||
return zuulRouteRepository.listAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Route getMatchingRoute(String path) {
|
||||
ApiParam param = ZuulContext.getApiParam();
|
||||
String nameVersion = param.fetchNameVersion();
|
||||
return routeRepository.get(nameVersion);
|
||||
return zuulRouteRepository.get(nameVersion);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -1,18 +1,34 @@
|
||||
package com.gitee.sop.gatewaycommon.zuul.route;
|
||||
|
||||
import com.gitee.sop.gatewaycommon.bean.ServiceRouteRepository;
|
||||
import com.gitee.sop.gatewaycommon.manager.RouteRepository;
|
||||
import com.gitee.sop.gatewaycommon.message.ErrorEnum;
|
||||
import org.springframework.cloud.netflix.zuul.filters.Route;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @author tanghc
|
||||
*/
|
||||
public class ZuulRouteRepository implements RouteRepository<Route> {
|
||||
/** key:nameVersion */
|
||||
private Map<String, Route> nameVersionServiceIdMap = new HashMap<>(128);
|
||||
public class ZuulRouteRepository implements RouteRepository<ZuulServiceRouteInfo, Route> {
|
||||
/**
|
||||
* key:nameVersion
|
||||
*/
|
||||
private Map<String, Route> nameVersionServiceIdMap = new ConcurrentHashMap<>(128);
|
||||
|
||||
private ServiceRouteRepository<ZuulServiceRouteInfo, Route> serviceRouteRepository = new ServiceRouteRepository<ZuulServiceRouteInfo, Route>() {
|
||||
@Override
|
||||
public String getServiceId(ZuulServiceRouteInfo serviceRouteInfo) {
|
||||
return serviceRouteInfo.getAppName();
|
||||
}
|
||||
};
|
||||
|
||||
public List<Route> listAll() {
|
||||
return new ArrayList<>(nameVersionServiceIdMap.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Route get(String id) {
|
||||
@@ -24,14 +40,17 @@ public class ZuulRouteRepository implements RouteRepository<Route> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String add(Route route) {
|
||||
return this.update(route);
|
||||
public String add(ZuulServiceRouteInfo serviceRouteInfo, Route route) {
|
||||
nameVersionServiceIdMap.put(route.getId(), route);
|
||||
serviceRouteRepository.saveRouteDefinition(serviceRouteInfo, route);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String update(Route route) {
|
||||
nameVersionServiceIdMap.put(route.getId(), route);
|
||||
return null;
|
||||
public void deleteAll(ZuulServiceRouteInfo serviceRouteInfo) {
|
||||
serviceRouteRepository.deleteAll(serviceRouteInfo, route -> {
|
||||
this.delete(route.getId());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -2,6 +2,7 @@ package com.gitee.sop.gatewaycommon.zuul.route;
|
||||
|
||||
import com.gitee.sop.gatewaycommon.manager.BaseRouteManager;
|
||||
import com.gitee.sop.gatewaycommon.manager.RouteRepository;
|
||||
import com.gitee.sop.gatewaycommon.util.RoutePathUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cloud.netflix.zuul.filters.Route;
|
||||
import org.springframework.core.env.Environment;
|
||||
@@ -10,9 +11,9 @@ import org.springframework.core.env.Environment;
|
||||
* @author tanghc
|
||||
*/
|
||||
@Slf4j
|
||||
public class ZuulZookeeperRouteManager extends BaseRouteManager<ZuulRouteDefinition, ZuulServiceRouteInfo, Route> {
|
||||
public class ZuulZookeeperRouteManager extends BaseRouteManager<ZuulServiceRouteInfo, ZuulRouteDefinition, Route> {
|
||||
|
||||
public ZuulZookeeperRouteManager(Environment environment, RouteRepository<Route> routeRepository) {
|
||||
public ZuulZookeeperRouteManager(Environment environment, RouteRepository<ZuulServiceRouteInfo, Route> routeRepository) {
|
||||
super(environment, routeRepository);
|
||||
}
|
||||
|
||||
@@ -21,13 +22,8 @@ public class ZuulZookeeperRouteManager extends BaseRouteManager<ZuulRouteDefinit
|
||||
return ZuulServiceRouteInfo.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<ZuulRouteDefinition> getRouteDefinitionClass() {
|
||||
return ZuulRouteDefinition.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Route buildRouteDefinition(ZuulServiceRouteInfo serviceRouteInfo, ZuulRouteDefinition routeDefinition) {
|
||||
return new Route(routeDefinition.getId(), routeDefinition.getPath(), serviceRouteInfo.getAppName(), null, false, null);
|
||||
return new Route(routeDefinition.getId(), RoutePathUtil.findPath(routeDefinition.getUri()), serviceRouteInfo.getAppName(), null, false, null);
|
||||
}
|
||||
}
|
||||
|
@@ -26,19 +26,15 @@
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- ↓↓↓ 使用spring cloud zuul ↓↓↓
|
||||
如果要使用gateway需要注释掉
|
||||
|
||||
<!-- ↓↓↓ 使用spring cloud zuul ↓↓↓ -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
|
||||
</dependency>
|
||||
-->
|
||||
<!-- ↑↑↑ 使用spring cloud zuul ↑↑↑ -->
|
||||
|
||||
<!-- ↓↓↓ 使用spring cloud gateway ↓↓↓
|
||||
如果要使用zuul需要注释掉
|
||||
-->
|
||||
|
||||
<!-- ↓↓↓ 使用spring cloud gateway,处于beta阶段,推荐使用zuul ↓↓↓
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||||
@@ -47,6 +43,7 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
-->
|
||||
<!-- ↑↑↑ 使用spring cloud gateway ↑↑↑ -->
|
||||
|
||||
<dependency>
|
||||
|
@@ -2,10 +2,10 @@ package com.gitee.sop.gateway;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
//import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
|
||||
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
|
||||
|
||||
// 开启网关功能
|
||||
//@EnableZuulProxy
|
||||
@EnableZuulProxy
|
||||
@SpringBootApplication
|
||||
public class SopGatewayApplication {
|
||||
|
||||
|
@@ -2,16 +2,27 @@ package com.gitee.sop.gateway.config;
|
||||
|
||||
import com.gitee.sop.gatewaycommon.bean.ApiContext;
|
||||
import com.gitee.sop.gatewaycommon.gateway.configuration.AlipayGatewayConfiguration;
|
||||
import com.gitee.sop.gatewaycommon.zuul.configuration.AlipayZuulConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* 使用Spring Cloud Gateway
|
||||
*
|
||||
* 注意:下面两个只能使用一个。
|
||||
*
|
||||
* 使用前,前往启动类SopGatewayApplication.java 注释掉@EnableZuulProxy
|
||||
*/
|
||||
|
||||
/**
|
||||
* 开通支付宝开放平台能力
|
||||
* @author tanghc
|
||||
*/
|
||||
@Configuration
|
||||
|
||||
//@Configuration
|
||||
public class GatewayConfig extends AlipayGatewayConfiguration {
|
||||
|
||||
{
|
||||
@@ -33,3 +44,4 @@ public class GatewayConfig extends AlipayGatewayConfiguration {
|
||||
// ApiContext.getApiConfig().addAppSecret(appSecretStore);
|
||||
// }
|
||||
//}
|
||||
|
||||
|
@@ -0,0 +1,45 @@
|
||||
package com.gitee.sop.gateway.config;
|
||||
|
||||
import com.gitee.sop.gatewaycommon.bean.ApiContext;
|
||||
import com.gitee.sop.gatewaycommon.zuul.configuration.AlipayZuulConfiguration;
|
||||
import com.gitee.sop.gatewaycommon.zuul.configuration.TaobaoZuulConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 使用Spring Cloud Zuul,推荐使用
|
||||
*
|
||||
* 注意:下面两个只能使用一个
|
||||
*/
|
||||
|
||||
/**
|
||||
* 开通支付宝开放平台能力
|
||||
* @author tanghc
|
||||
*/
|
||||
@Configuration
|
||||
public class ZuulConfig extends AlipayZuulConfiguration {
|
||||
|
||||
{
|
||||
Map<String, String> appSecretStore = new HashMap();
|
||||
appSecretStore.put("alipay_test", "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlyb9aUBaljQP/vjmBFe1mF8HsWSvyfC2NTlpT/V9E+sBxTr8TSkbzJCeeeOEm4LCaVXL0Qz63MZoT24v7AIXTuMdj4jyiM/WJ4tjrWAgnmohNOegfntTto16C3l234vXz4ryWZMR/7W+MXy5B92wPGQEJ0LKFwNEoLspDEWZ7RdE53VH7w6y6sIZUfK+YkXWSwehfKPKlx+lDw3zRJ3/yvMF+U+BAdW/MfECe1GuBnCFKnlMRh3UKczWyXWkL6ItOpYHHJi/jx85op5BWDje2pY9QowzfN94+0DB3T7UvZeweu3zlP6diwAJDzLaFQX8ULfWhY+wfKxIRgs9NoiSAQIDAQAB");
|
||||
ApiContext.getApiConfig().addAppSecret(appSecretStore);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开通支付宝开放平台能力
|
||||
* @author tanghc
|
||||
*/
|
||||
//@Configuration
|
||||
//public class ZuulConfig extends TaobaoZuulConfiguration {
|
||||
//
|
||||
// {
|
||||
// Map<String, String> appSecretStore = new HashMap();
|
||||
// appSecretStore.put("taobao_test", "G9w0BAQEFAAOCAQ8AMIIBCgKCA");
|
||||
// ApiContext.getApiConfig().addAppSecret(appSecretStore);
|
||||
// }
|
||||
//}
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
server:
|
||||
port: 8081
|
||||
|
||||
|
||||
eureka:
|
||||
serverAddr: localhost:1111
|
||||
client:
|
||||
@@ -14,3 +15,4 @@ spring:
|
||||
locator:
|
||||
lower-case-service-id: true
|
||||
enabled: true
|
||||
|
||||
|
@@ -5,4 +5,7 @@ spring:
|
||||
|
||||
cloud:
|
||||
zookeeper:
|
||||
connect-string: localhost:2181
|
||||
connect-string: localhost:2181
|
||||
|
||||
zuul:
|
||||
servlet-path: /api # 入口地址,默认是/zuul
|
||||
|
@@ -22,7 +22,7 @@
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.gitee.sop</groupId>
|
||||
<artifactId>sop-server-common</artifactId>
|
||||
<artifactId>sop-service-common</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@@ -1,7 +0,0 @@
|
||||
server.port=2222
|
||||
spring.application.name=story-service
|
||||
|
||||
eureka.host=localhost
|
||||
eureka.port=1111
|
||||
eureka.client.serviceUrl.defaultZone=http://${eureka.host}:${eureka.port}/eureka/
|
||||
|
@@ -0,0 +1,9 @@
|
||||
server:
|
||||
port: 2222
|
||||
|
||||
eureka:
|
||||
port: 1111
|
||||
host: localhost
|
||||
client:
|
||||
serviceUrl:
|
||||
defaultZone: http://${eureka.host}:${eureka.port}/eureka/
|
@@ -22,7 +22,7 @@ import java.util.Set;
|
||||
public class AlipayClientPostTest extends TestBase {
|
||||
|
||||
|
||||
String url = "http://localhost:8081/";
|
||||
String url = "http://localhost:8081/api";
|
||||
String appId = "alipay_test";
|
||||
// 支付宝私钥
|
||||
String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCXJv1pQFqWNA/++OYEV7WYXwexZK/J8LY1OWlP9X0T6wHFOvxNKRvMkJ5544SbgsJpVcvRDPrcxmhPbi/sAhdO4x2PiPKIz9Yni2OtYCCeaiE056B+e1O2jXoLeXbfi9fPivJZkxH/tb4xfLkH3bA8ZAQnQsoXA0SguykMRZntF0TndUfvDrLqwhlR8r5iRdZLB6F8o8qXH6UPDfNEnf/K8wX5T4EB1b8x8QJ7Ua4GcIUqeUxGHdQpzNbJdaQvoi06lgccmL+PHzminkFYON7alj1CjDN833j7QMHdPtS9l7B67fOU/p2LAAkPMtoVBfxQt9aFj7B8rEhGCz02iJIBAgMBAAECggEARqOuIpY0v6WtJBfmR3lGIOOokLrhfJrGTLF8CiZMQha+SRJ7/wOLPlsH9SbjPlopyViTXCuYwbzn2tdABigkBHYXxpDV6CJZjzmRZ+FY3S/0POlTFElGojYUJ3CooWiVfyUMhdg5vSuOq0oCny53woFrf32zPHYGiKdvU5Djku1onbDU0Lw8w+5tguuEZ76kZ/lUcccGy5978FFmYpzY/65RHCpvLiLqYyWTtaNT1aQ/9pw4jX9HO9NfdJ9gYFK8r/2f36ZE4hxluAfeOXQfRC/WhPmiw/ReUhxPznG/WgKaa/OaRtAx3inbQ+JuCND7uuKeRe4osP2jLPHPP6AUwQKBgQDUNu3BkLoKaimjGOjCTAwtp71g1oo+k5/uEInAo7lyEwpV0EuUMwLA/HCqUgR4K9pyYV+Oyb8d6f0+Hz0BMD92I2pqlXrD7xV2WzDvyXM3s63NvorRooKcyfd9i6ccMjAyTR2qfLkxv0hlbBbsPHz4BbU63xhTJp3Ghi0/ey/1HQKBgQC2VsgqC6ykfSidZUNLmQZe3J0p/Qf9VLkfrQ+xaHapOs6AzDU2H2osuysqXTLJHsGfrwVaTs00ER2z8ljTJPBUtNtOLrwNRlvgdnzyVAKHfOgDBGwJgiwpeE9voB1oAV/mXqSaUWNnuwlOIhvQEBwekqNyWvhLqC7nCAIhj3yvNQKBgQCqYbeec56LAhWP903Zwcj9VvG7sESqXUhIkUqoOkuIBTWFFIm54QLTA1tJxDQGb98heoCIWf5x/A3xNI98RsqNBX5JON6qNWjb7/dobitti3t99v/ptDp9u8JTMC7penoryLKK0Ty3bkan95Kn9SC42YxaSghzqkt+uvfVQgiNGQKBgGxU6P2aDAt6VNwWosHSe+d2WWXt8IZBhO9d6dn0f7ORvcjmCqNKTNGgrkewMZEuVcliueJquR47IROdY8qmwqcBAN7Vg2K7r7CPlTKAWTRYMJxCT1Hi5gwJb+CZF3+IeYqsJk2NF2s0w5WJTE70k1BSvQsfIzAIDz2yE1oPHvwVAoGAA6e+xQkVH4fMEph55RJIZ5goI4Y76BSvt2N5OKZKd4HtaV+eIhM3SDsVYRLIm9ZquJHMiZQGyUGnsvrKL6AAVNK7eQZCRDk9KQz+0GKOGqku0nOZjUbAu6A2/vtXAaAuFSFx1rUQVVjFulLexkXR3KcztL1Qu2k5pB6Si0K/uwQ=";
|
||||
@@ -40,6 +40,7 @@ version String 是 3 调用的接口版本,固定为:1.0 1.0
|
||||
app_auth_token String 否 40 详见应用授权概述
|
||||
biz_content String 是 请求参数的集合,最大长度不限,除公共参数外所有请求参数都必须放在这个参数中传递,具体参照各产品快速接入文档
|
||||
*/
|
||||
// 这个请求会路由到story服务
|
||||
@Test
|
||||
public void testPost() throws Exception {
|
||||
|
||||
@@ -51,7 +52,82 @@ biz_content String 是 请求参数的集合,最大长度不限,除公共
|
||||
params.put("charset", "utf-8");
|
||||
params.put("sign_type", "RSA2");
|
||||
params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
params.put("version", "1.2");
|
||||
params.put("version", "1.0");
|
||||
|
||||
// 业务参数
|
||||
Map<String, String> bizContent = new HashMap<>();
|
||||
bizContent.put("id", "1");
|
||||
bizContent.put("name", "葫芦娃");
|
||||
// bizContent.put("name", "葫芦娃1234567890葫芦娃1234567890"); // 超出长度
|
||||
|
||||
params.put("biz_content", JSON.toJSONString(bizContent));
|
||||
|
||||
System.out.println("----------- 请求信息 -----------");
|
||||
System.out.println("请求参数:" + buildParamQuery(params));
|
||||
System.out.println("商户秘钥:" + privateKey);
|
||||
String content = AlipaySignature.getSignContent(params);
|
||||
System.out.println("待签名内容:" + content);
|
||||
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
|
||||
System.out.println("签名(sign):" + sign);
|
||||
|
||||
params.put("sign", sign);
|
||||
|
||||
System.out.println("----------- 返回结果 -----------");
|
||||
String responseData = post(url, params);// 发送请求
|
||||
System.out.println(responseData);
|
||||
}
|
||||
|
||||
// 这个请求会路由到book服务
|
||||
@Test
|
||||
public void testPostBook() throws Exception {
|
||||
|
||||
// 公共请求参数
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("app_id", appId);
|
||||
params.put("method", "alipay.book.get");
|
||||
params.put("format", "json");
|
||||
params.put("charset", "utf-8");
|
||||
params.put("sign_type", "RSA2");
|
||||
params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
params.put("version", "1.0");
|
||||
|
||||
// 业务参数
|
||||
Map<String, String> bizContent = new HashMap<>();
|
||||
bizContent.put("id", "1");
|
||||
bizContent.put("name", "葫芦娃");
|
||||
// bizContent.put("name", "葫芦娃1234567890葫芦娃1234567890"); // 超出长度
|
||||
|
||||
params.put("biz_content", JSON.toJSONString(bizContent));
|
||||
|
||||
System.out.println("----------- 请求信息 -----------");
|
||||
System.out.println("请求参数:" + buildParamQuery(params));
|
||||
System.out.println("商户秘钥:" + privateKey);
|
||||
String content = AlipaySignature.getSignContent(params);
|
||||
System.out.println("待签名内容:" + content);
|
||||
String sign = AlipaySignature.rsa256Sign(content, privateKey, "utf-8");
|
||||
System.out.println("签名(sign):" + sign);
|
||||
|
||||
params.put("sign", sign);
|
||||
|
||||
System.out.println("----------- 返回结果 -----------");
|
||||
String responseData = post(url, params);// 发送请求
|
||||
System.out.println(responseData);
|
||||
}
|
||||
|
||||
// 这个请求会路由到book服务,然后再调用story服务
|
||||
// gateway -> book-service -> story-service
|
||||
@Test
|
||||
public void testPostBook2() throws Exception {
|
||||
|
||||
// 公共请求参数
|
||||
Map<String, String> params = new HashMap<String, String>();
|
||||
params.put("app_id", appId);
|
||||
params.put("method", "alipay.book.story.get");
|
||||
params.put("format", "json");
|
||||
params.put("charset", "utf-8");
|
||||
params.put("sign_type", "RSA2");
|
||||
params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
|
||||
params.put("version", "1.0");
|
||||
|
||||
// 业务参数
|
||||
Map<String, String> bizContent = new HashMap<>();
|
||||
|
@@ -15,9 +15,9 @@ import java.util.Map;
|
||||
public class TaobaoClientPostTest extends TestBase {
|
||||
|
||||
|
||||
String url = "http://localhost:8081";
|
||||
String url = "http://localhost:8081/api";
|
||||
String appId = "taobao_test";
|
||||
// 支付宝私钥
|
||||
// 淘宝私钥
|
||||
String secret = "G9w0BAQEFAAOCAQ8AMIIBCgKCA";
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user