[WIP] [OSPP] [2.2.x] feat: Add regional affinity routing and adapt clients and gateways (#3449)
feat: Add regional affinity routing and adapt clients and gateways2.2.x-ospp2023
parent
f42f8b8915
commit
7da2ae9eec
@ -0,0 +1,24 @@
|
||||
# app home
|
||||
APP_HOME=/sca-service/sca-routing
|
||||
|
||||
# image and container prefix
|
||||
DOCKER_PREFIX=sca-label-routing
|
||||
|
||||
# Routing service provider port
|
||||
PROVIDER_PORT_A1 = 19091
|
||||
PROVIDER_PORT_A2 = 19092
|
||||
PROVIDER_PORT_A3 = 19093
|
||||
PROVIDER_PORT_A4 = 19094
|
||||
|
||||
# Routing web client consumer port
|
||||
FEIGN_CONSUMER_PORT=19095
|
||||
REACTIVE_CONSUMER_PORT=19096
|
||||
REST_CONSUMER_PORT=19097
|
||||
|
||||
# Routing gateway consumer port
|
||||
GATEWAY_CONSUMER_PORT=19098
|
||||
ZUUL_CONSUMER_PORT=19099
|
||||
|
||||
# Nacos server port
|
||||
NACOS_PORT=8848
|
||||
NACOS_GRPC_PORT=9848
|
@ -0,0 +1 @@
|
||||
**/*.jar
|
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
After Width: | Height: | Size: 36 KiB |
Binary file not shown.
After Width: | Height: | Size: 89 KiB |
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
@ -0,0 +1,46 @@
|
||||
version: "3"
|
||||
services:
|
||||
|
||||
# routing gateway consumer example
|
||||
routing-gateway-consumer:
|
||||
image: ${DOCKER_PREFIX}-gateway-consumer
|
||||
env_file:
|
||||
- .env
|
||||
build:
|
||||
dockerfile: label-routing-gateway-consumer-example/DockerFile
|
||||
context: .
|
||||
args:
|
||||
APP_HOME: ${APP_HOME}
|
||||
container_name: ${DOCKER_PREFIX}-gateway-consumer
|
||||
restart: on-failure
|
||||
environment:
|
||||
- SERVER_PORT=${GATEWAY_CONSUMER_PORT}
|
||||
volumes:
|
||||
- ./label-routing-gateway-consumer-example/label-routing-gateway-consumer-example:${APP_HOME}
|
||||
- /etc/localtime:/etc/localtime
|
||||
expose:
|
||||
- ${GATEWAY_CONSUMER_PORT}
|
||||
ports:
|
||||
- ${GATEWAY_CONSUMER_PORT}:${GATEWAY_CONSUMER_PORT}
|
||||
|
||||
# routing provider example
|
||||
routing-zuul-consumer:
|
||||
image: ${DOCKER_PREFIX}-zuul-consumer
|
||||
env_file:
|
||||
- .env
|
||||
build:
|
||||
dockerfile: label-routing-gateway-consumer-example/DockerFile
|
||||
context: .
|
||||
args:
|
||||
APP_HOME: ${APP_HOME}
|
||||
container_name: ${DOCKER_PREFIX}-zuul-consumer
|
||||
restart: on-failure
|
||||
environment:
|
||||
- SERVER_PORT=${ZUUL_CONSUMER_PORT}
|
||||
volumes:
|
||||
- ./label-routing-gateway-consumer-example/label-routing-zuul-consumer-example:${APP_HOME}
|
||||
- /etc/localtime:/etc/localtime
|
||||
expose:
|
||||
- ${ZUUL_CONSUMER_PORT}
|
||||
ports:
|
||||
- ${ZUUL_CONSUMER_PORT}:${ZUUL_CONSUMER_PORT}
|
@ -0,0 +1,43 @@
|
||||
version: "3"
|
||||
services:
|
||||
|
||||
# nacos
|
||||
label-routing-service-nacos:
|
||||
image: nacos/nacos-server:v2.1.0
|
||||
restart: always
|
||||
container_name: ${DOCKER_PREFIX}-nacos-server
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- MODE=standalone
|
||||
ports:
|
||||
- ${NACOS_PORT}:${NACOS_PORT}
|
||||
- ${NACOS_GRPC_PORT}:${NACOS_GRPC_PORT}
|
||||
|
||||
# routing provider example
|
||||
label-routing-service-provider:
|
||||
image: ${DOCKER_PREFIX}-service-provider
|
||||
env_file:
|
||||
- .env
|
||||
build:
|
||||
dockerfile: label-routing-service-provider-example/DockerFile
|
||||
context: .
|
||||
args:
|
||||
APP_HOME: ${APP_HOME}
|
||||
container_name: ${DOCKER_PREFIX}-service-provider
|
||||
restart: on-failure
|
||||
volumes:
|
||||
- ./label-routing-service-provider-example:${APP_HOME}
|
||||
- /etc/localtime:/etc/localtime
|
||||
expose:
|
||||
- ${PROVIDER_PORT_A1}
|
||||
- ${PROVIDER_PORT_A2}
|
||||
- ${PROVIDER_PORT_A3}
|
||||
- ${PROVIDER_PORT_A4}
|
||||
ports:
|
||||
- ${PROVIDER_PORT_A1}:${PROVIDER_PORT_A1}
|
||||
- ${PROVIDER_PORT_A2}:${PROVIDER_PORT_A3}
|
||||
- ${PROVIDER_PORT_A3}:${PROVIDER_PORT_A3}
|
||||
- ${PROVIDER_PORT_A4}:${PROVIDER_PORT_A4}
|
||||
depends_on:
|
||||
- label-routing-service-nacos
|
@ -0,0 +1,62 @@
|
||||
version: "3"
|
||||
services:
|
||||
|
||||
# routing web client consumer example
|
||||
routing-feign-consumer:
|
||||
image: ${DOCKER_PREFIX}-feign-consumer
|
||||
env_file:
|
||||
- .env
|
||||
build:
|
||||
dockerfile: label-routing-webClient-consumer-example/DockerFile
|
||||
context: .
|
||||
args:
|
||||
APP_HOME: ${APP_HOME}
|
||||
container_name: ${DOCKER_PREFIX}-feign-consumer
|
||||
restart: on-failure
|
||||
volumes:
|
||||
- ./label-routing-webClient-consumer-example/label-routing-feign-consumer-example:${APP_HOME}
|
||||
- /etc/localtime:/etc/localtime
|
||||
expose:
|
||||
- ${FEIGN_CONSUMER_PORT}
|
||||
ports:
|
||||
- ${FEIGN_CONSUMER_PORT}:${FEIGN_CONSUMER_PORT}
|
||||
|
||||
# routing provider example
|
||||
routing-rest-consumer:
|
||||
image: ${DOCKER_PREFIX}-rest-consumer
|
||||
env_file:
|
||||
- .env
|
||||
build:
|
||||
dockerfile: label-routing-webClient-consumer-example/DockerFile
|
||||
context: .
|
||||
args:
|
||||
APP_HOME: ${APP_HOME}
|
||||
container_name: ${DOCKER_PREFIX}-rest-consumer
|
||||
restart: on-failure
|
||||
volumes:
|
||||
- ./label-routing-webClient-consumer-example/label-routing-rest-consumer-example:${APP_HOME}
|
||||
- /etc/localtime:/etc/localtime
|
||||
expose:
|
||||
- ${REST_CONSUMER_PORT}
|
||||
ports:
|
||||
- ${REST_CONSUMER_PORT}:${REST_CONSUMER_PORT}
|
||||
|
||||
# routing provider example
|
||||
routing-reactive-consumer:
|
||||
image: ${DOCKER_PREFIX}-reactive-consumer
|
||||
env_file:
|
||||
- .env
|
||||
build:
|
||||
dockerfile: label-routing-webClient-consumer-example/DockerFile
|
||||
context: .
|
||||
args:
|
||||
APP_HOME: ${APP_HOME}
|
||||
container_name: ${DOCKER_PREFIX}-reactive-consumer
|
||||
restart: on-failure
|
||||
volumes:
|
||||
- ./label-routing-webClient-consumer-example/label-routing-reactive-consumer-example:${APP_HOME}
|
||||
- /etc/localtime:/etc/localtime
|
||||
expose:
|
||||
- ${REACTIVE_CONSUMER_PORT}
|
||||
ports:
|
||||
- ${REACTIVE_CONSUMER_PORT}:${REACTIVE_CONSUMER_PORT}
|
@ -0,0 +1,12 @@
|
||||
FROM openjdk:8-jdk-alpine as builder
|
||||
|
||||
LABEL author="yuluo" \
|
||||
email="1481556636@qq.com"
|
||||
|
||||
ARG APP_HOME
|
||||
|
||||
VOLUME ${APP_HOME}
|
||||
|
||||
WORKDIR ${APP_HOME}
|
||||
|
||||
ENTRYPOINT ["java", "-jar", "app.jar", "-Dspring.profiles.active=docker"]
|
@ -0,0 +1,28 @@
|
||||
server:
|
||||
port: 19098
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: gateway-consumer-example
|
||||
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: sca-label-routing-nacos-server:8848
|
||||
|
||||
# Regional affinity routing configuration
|
||||
governance:
|
||||
routing:
|
||||
region: dev
|
||||
zone: zone1
|
||||
# rule: RandomRule
|
||||
|
||||
# Gateway route config
|
||||
gateway:
|
||||
routes:
|
||||
- id: label-routing-test-route
|
||||
uri: lb://routing-service-provider
|
||||
predicates:
|
||||
- Path=/routing-service-provider/**
|
||||
filters:
|
||||
- StripPrefix=1
|
@ -0,0 +1,25 @@
|
||||
server:
|
||||
port: 19099
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: zuul-consumer-example
|
||||
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: sca-label-routing-nacos-server:8848
|
||||
|
||||
# Regional affinity routing configuration
|
||||
governance:
|
||||
routing:
|
||||
region: dev
|
||||
zone: zone1
|
||||
# rule: RandomRule
|
||||
|
||||
# Zuul route config
|
||||
zuul:
|
||||
routes:
|
||||
my-service:
|
||||
serviceId: routing-service-provider
|
||||
path: /routing-service-provider/**
|
@ -0,0 +1,12 @@
|
||||
FROM openjdk:8-jdk-alpine as builder
|
||||
|
||||
LABEL author="yuluo" \
|
||||
email="1481556636@qq.com"
|
||||
|
||||
ARG APP_HOME
|
||||
|
||||
VOLUME ${APP_HOME}
|
||||
|
||||
WORKDIR ${APP_HOME}
|
||||
|
||||
ENTRYPOINT ["sh", "start-label-routing-service-provider.sh"]
|
@ -0,0 +1,17 @@
|
||||
server:
|
||||
port: 19091
|
||||
|
||||
spring:
|
||||
# spring application configuration
|
||||
application:
|
||||
name: routing-service-provider
|
||||
|
||||
# register center configuration
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: sca-label-routing-nacos-server:8848
|
||||
metadata:
|
||||
version: v1
|
||||
region: qa
|
||||
zone: zone1
|
@ -0,0 +1,18 @@
|
||||
server:
|
||||
port: 19092
|
||||
|
||||
spring:
|
||||
# spring application configuration
|
||||
application:
|
||||
name: routing-service-provider
|
||||
|
||||
# register center configuration
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: sca-label-routing-nacos-server:8848
|
||||
metadata:
|
||||
version: v2
|
||||
region: qa
|
||||
zone: zone2
|
||||
|
@ -0,0 +1,17 @@
|
||||
server:
|
||||
port: 19093
|
||||
|
||||
spring:
|
||||
# spring application configuration
|
||||
application:
|
||||
name: routing-service-provider
|
||||
|
||||
# register center configuration
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: sca-label-routing-nacos-server:8848
|
||||
metadata:
|
||||
version: v1
|
||||
region: dev
|
||||
zone: zone1
|
@ -0,0 +1,17 @@
|
||||
server:
|
||||
port: 19094
|
||||
|
||||
spring:
|
||||
# spring application configuration
|
||||
application:
|
||||
name: routing-service-provider
|
||||
|
||||
# register center configuration
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: sca-label-routing-nacos-server:8848
|
||||
metadata:
|
||||
version: v2
|
||||
region: dev
|
||||
zone: zone2
|
@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
java -jar app.jar --spring.profiles.active=dockerA1 &
|
||||
|
||||
java -jar app.jar --spring.profiles.active=dockerA2 &
|
||||
|
||||
java -jar app.jar --spring.profiles.active=dockerA3 &
|
||||
|
||||
java -jar app.jar --spring.profiles.active=dockerA4
|
@ -0,0 +1,12 @@
|
||||
FROM openjdk:8-jdk-alpine as builder
|
||||
|
||||
LABEL author="yuluo" \
|
||||
email="1481556636@qq.com"
|
||||
|
||||
ARG APP_HOME
|
||||
|
||||
VOLUME ${APP_HOME}
|
||||
|
||||
WORKDIR ${APP_HOME}
|
||||
|
||||
ENTRYPOINT ["java", "-jar", "app.jar", "--spring.profiles.active=docker"]
|
@ -0,0 +1,21 @@
|
||||
server:
|
||||
port: 19095
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: openfeign-service-consumer
|
||||
|
||||
cloud:
|
||||
|
||||
# register center configuration
|
||||
nacos:
|
||||
discovery:
|
||||
fail-fast: true
|
||||
server-addr: sca-label-routing-nacos-server:8848
|
||||
|
||||
# label routing configuration
|
||||
governance:
|
||||
routing:
|
||||
region: dev
|
||||
zone: zone1
|
||||
# rule: RandomRule
|
@ -0,0 +1,18 @@
|
||||
server:
|
||||
port: 19096
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: webClient-service-consumer
|
||||
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: sca-label-routing-nacos-server:8848
|
||||
|
||||
# label routing configuration
|
||||
governance:
|
||||
routing:
|
||||
region: dev
|
||||
zone: zone1
|
||||
# rule: RandomRule
|
@ -0,0 +1,17 @@
|
||||
server:
|
||||
port: 19097
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: restTemplate-service-consumer
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: sca-label-routing-nacos-server:8848
|
||||
|
||||
# label routing configuration
|
||||
governance:
|
||||
routing:
|
||||
region: dev
|
||||
zone: zone1
|
||||
# rule: RandomRule
|
@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
|
||||
gateway_example_project_path="label-routing-example/gateway-consumer-example/gateway-consumer-example/target"
|
||||
gateway_example_docker_path="label-routing-gateway-consumer-example/label-routing-gateway-consumer-example"
|
||||
zuul_example_project_path="label-routing-example/gateway-consumer-example/zuul-consumer-example/target"
|
||||
zuul_example_docker_path="label-routing-gateway-consumer-example/label-routing-zuul-consumer-example"
|
||||
feign_example_project_path="label-routing-example/web-client-consumer-example/openfeign-consumer-example/target"
|
||||
feign_example_docker_path="label-routing-webClient-consumer-example/label-routing-feign-consumer-example"
|
||||
rest_example_project_path="label-routing-example/web-client-consumer-example/restTemplate-consumer-example/target"
|
||||
rest_example_docker_path="label-routing-webClient-consumer-example/label-routing-rest-consumer-example"
|
||||
reactive_example_project_path="label-routing-example/web-client-consumer-example/webClient-consumer-example/target"
|
||||
reactive_example_docker_path="label-routing-webClient-consumer-example/label-routing-reactive-consumer-example"
|
||||
provider_example_project_path="label-routing-example/routing-service-provider-example/target"
|
||||
provider_example_docker_path="label-routing-service-provider-example"
|
||||
|
||||
|
||||
cp ../../${provider_example_project_path}/routing-service-provider-example-*.jar ./${provider_example_docker_path}/app.jar
|
||||
cp ../../${gateway_example_project_path}/gateway-consumer-example-*.jar ./${gateway_example_docker_path}/app.jar
|
||||
cp ../../${zuul_example_project_path}/zuul-consumer-example-*.jar ./${zuul_example_docker_path}/app.jar
|
||||
cp ../../${feign_example_project_path}/openfeign-consumer-example-*.jar ./${feign_example_docker_path}/app.jar
|
||||
cp ../../${rest_example_project_path}/restTemplate-consumer-example-*.jar ./${rest_example_docker_path}/app.jar
|
||||
cp ../../${reactive_example_project_path}/webClient-consumer-example-*.jar ./${reactive_example_docker_path}/app.jar
|
@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.examples;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.cloud.commons.governance.event.RoutingDataChangedEvent;
|
||||
import com.alibaba.cloud.commons.governance.routing.MatchService;
|
||||
import com.alibaba.cloud.commons.governance.routing.RoutingRule;
|
||||
import com.alibaba.cloud.commons.governance.routing.UnifiedRoutingDataStructure;
|
||||
import com.alibaba.cloud.commons.governance.routing.rule.HeaderRoutingRule;
|
||||
import com.alibaba.cloud.commons.governance.routing.rule.Rule;
|
||||
import com.alibaba.cloud.commons.governance.routing.rule.UrlRoutingRule;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author HH
|
||||
*/
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient(autoRegister = true)
|
||||
@EnableFeignClients
|
||||
public class ConsumerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ConsumerApplication.class, args);
|
||||
}
|
||||
|
||||
@FeignClient(name = "service-provider")
|
||||
public interface FeignService {
|
||||
|
||||
/**
|
||||
* Feign test.
|
||||
* @return String
|
||||
*/
|
||||
@GetMapping("/test")
|
||||
String test();
|
||||
|
||||
}
|
||||
|
||||
@RestController
|
||||
public class Controller implements ApplicationContextAware {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
private ConsumerApplication.FeignService feignService;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@GetMapping("/router-test")
|
||||
public String notFound() {
|
||||
return feignService.test();
|
||||
}
|
||||
|
||||
@GetMapping("/add")
|
||||
public void getDataFromControlPlaneTest() {
|
||||
List<Rule> routeRules = new ArrayList<>();
|
||||
List<MatchService> matchServices = new ArrayList<>();
|
||||
|
||||
UnifiedRoutingDataStructure unifiedRouteDataStructure = new UnifiedRoutingDataStructure();
|
||||
unifiedRouteDataStructure.setTargetService("service-provider");
|
||||
|
||||
RoutingRule labelRouteData = new RoutingRule();
|
||||
labelRouteData.setDefaultRouteVersion("v1");
|
||||
|
||||
Rule routeRule = new HeaderRoutingRule();
|
||||
routeRule.setCondition("=");
|
||||
routeRule.setKey("tag");
|
||||
routeRule.setValue("v2");
|
||||
Rule routeRule1 = new UrlRoutingRule.ParameterRoutingRule();
|
||||
routeRule1.setCondition(">");
|
||||
routeRule1.setKey("id");
|
||||
routeRule1.setValue("10");
|
||||
Rule routeRule2 = new UrlRoutingRule.PathRoutingRule();
|
||||
routeRule2.setCondition("=");
|
||||
routeRule2.setValue("/router-test");
|
||||
routeRules.add(routeRule);
|
||||
routeRules.add(routeRule1);
|
||||
routeRules.add(routeRule2);
|
||||
|
||||
MatchService matchService = new MatchService();
|
||||
matchService.setVersion("v2");
|
||||
matchService.setWeight(100);
|
||||
matchService.setRuleList(routeRules);
|
||||
matchServices.add(matchService);
|
||||
|
||||
labelRouteData.setMatchRouteList(matchServices);
|
||||
|
||||
unifiedRouteDataStructure.setLabelRouteRule(labelRouteData);
|
||||
|
||||
List<UnifiedRoutingDataStructure> unifiedRouteDataStructureList = new ArrayList<>();
|
||||
unifiedRouteDataStructureList.add(unifiedRouteDataStructure);
|
||||
applicationContext.publishEvent(
|
||||
new RoutingDataChangedEvent(this, unifiedRouteDataStructureList));
|
||||
}
|
||||
|
||||
@GetMapping("/update")
|
||||
public void updateDataFromControlPlaneTest() {
|
||||
List<Rule> routeRules = new ArrayList<>();
|
||||
List<MatchService> matchServices = new ArrayList<>();
|
||||
|
||||
UnifiedRoutingDataStructure unifiedRouteDataStructure = new UnifiedRoutingDataStructure();
|
||||
unifiedRouteDataStructure.setTargetService("service-provider");
|
||||
|
||||
RoutingRule labelRouteData = new RoutingRule();
|
||||
labelRouteData.setDefaultRouteVersion("v1");
|
||||
|
||||
Rule routeRule = new HeaderRoutingRule();
|
||||
routeRule.setCondition("=");
|
||||
routeRule.setKey("tag");
|
||||
routeRule.setValue("v2");
|
||||
Rule routeRule1 = new UrlRoutingRule.ParameterRoutingRule();
|
||||
routeRule1.setCondition(">");
|
||||
routeRule1.setKey("id");
|
||||
routeRule1.setValue("10");
|
||||
Rule routeRule2 = new UrlRoutingRule.PathRoutingRule();
|
||||
routeRule2.setCondition("=");
|
||||
routeRule2.setValue("/router-test");
|
||||
routeRules.add(routeRule);
|
||||
routeRules.add(routeRule1);
|
||||
routeRules.add(routeRule2);
|
||||
|
||||
MatchService matchService = new MatchService();
|
||||
matchService.setVersion("v2");
|
||||
matchService.setWeight(50);
|
||||
matchService.setRuleList(routeRules);
|
||||
matchServices.add(matchService);
|
||||
|
||||
labelRouteData.setMatchRouteList(matchServices);
|
||||
|
||||
unifiedRouteDataStructure.setLabelRouteRule(labelRouteData);
|
||||
|
||||
List<UnifiedRoutingDataStructure> unifiedRouteDataStructureList = new ArrayList<>();
|
||||
unifiedRouteDataStructureList.add(unifiedRouteDataStructure);
|
||||
applicationContext.publishEvent(
|
||||
new RoutingDataChangedEvent(this, unifiedRouteDataStructureList));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
spring.application.name=service-consumer
|
||||
server.port=18083
|
||||
management.endpoints.web.exposure.include=*
|
||||
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
|
||||
spring.cloud.nacos.discovery.fail-fast=true
|
||||
spring.cloud.nacos.username=nacos
|
||||
spring.cloud.nacos.password=nacos
|
||||
#spring.cloud.governance.routing.rule=RandomRule
|
@ -1,45 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<parent>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-examples</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>default-provider-version-example</artifactId>
|
||||
<name>Spring Cloud Starter Alibaba Label Routing Provider Example</name>
|
||||
<description>Example demonstrating how to use label routing provider</description>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -1,12 +0,0 @@
|
||||
server.port=18081
|
||||
spring.application.name=service-provider
|
||||
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
|
||||
spring.cloud.nacos.discovery.enabled=true
|
||||
spring.cloud.nacos.discovery.metadata.version=v1
|
||||
|
||||
|
||||
spring.cloud.nacos.username=nacos
|
||||
spring.cloud.nacos.password=nacos
|
||||
|
||||
management.endpoints.web.exposure.include=*
|
||||
management.endpoint.health.show-details=always
|
@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-examples</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>gateway-consumer-example</artifactId>
|
||||
<name>Label Routing Gateway Consumer Example </name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-governance-routing</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-commons</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>label-routing-example-common</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.example.gateway;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient
|
||||
public class GatewayConsumerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
SpringApplication.run(GatewayConsumerApplication.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.example.gateway.configuration;
|
||||
|
||||
import com.alibaba.cloud.example.gateway.handler.AddGatewayRoutingRuleHandler;
|
||||
import com.alibaba.cloud.example.gateway.handler.GatewayServerListHandler;
|
||||
import com.alibaba.cloud.example.gateway.handler.UpdateGatewayRoutingRuleHandler;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.web.reactive.function.server.RequestPredicates;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.RouterFunctions;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@Configuration
|
||||
public class GatewayRouterFunctionConfiguration {
|
||||
|
||||
@Autowired
|
||||
private AddGatewayRoutingRuleHandler addGatewayRoutingRuleHandler;
|
||||
|
||||
@Autowired
|
||||
private UpdateGatewayRoutingRuleHandler updateGatewayRoutingRuleHandler;
|
||||
|
||||
@Autowired
|
||||
private GatewayServerListHandler gatewayServerListHandler;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Bean
|
||||
public RouterFunction gatewayRouterFunction() {
|
||||
|
||||
return RouterFunctions.route()
|
||||
.GET("/addRule", RequestPredicates.accept(MediaType.TEXT_PLAIN),
|
||||
addGatewayRoutingRuleHandler)
|
||||
.GET("/updateRule", RequestPredicates.accept(MediaType.TEXT_PLAIN),
|
||||
updateGatewayRoutingRuleHandler)
|
||||
.GET("/services", RequestPredicates.accept(MediaType.TEXT_PLAIN),
|
||||
gatewayServerListHandler)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.example.gateway.handler;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.server.HandlerFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerRequest;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@Service
|
||||
public class GatewayServerListHandler implements HandlerFunction<ServerResponse> {
|
||||
|
||||
private final DiscoveryClient discoveryClient;
|
||||
|
||||
public GatewayServerListHandler(DiscoveryClient discoveryClient) {
|
||||
this.discoveryClient = discoveryClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<ServerResponse> handle(ServerRequest serverRequest) {
|
||||
|
||||
HashMap<String, List<ServiceInstance>> map = new HashMap<>();
|
||||
|
||||
List<String> services = discoveryClient.getServices();
|
||||
for (String service : services) {
|
||||
List<ServiceInstance> instances = discoveryClient.getInstances(service);
|
||||
map.put(service, instances);
|
||||
}
|
||||
|
||||
return ServerResponse.status(HttpStatus.OK).body(BodyInserters.fromValue(map));
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.example.gateway.service;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
public interface AddGatewayRoutingRuleService {
|
||||
|
||||
void getDataFromControlPlaneTest();
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.example.gateway.service;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
public interface UpdateGatewayRoutingRuleService {
|
||||
|
||||
void updateDataFromControlPlaneTest();
|
||||
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.example.gateway.service.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.cloud.commons.governance.event.RoutingDataChangedEvent;
|
||||
import com.alibaba.cloud.commons.governance.routing.UnifiedRoutingDataStructure;
|
||||
import com.alibaba.cloud.example.gateway.service.AddGatewayRoutingRuleService;
|
||||
import com.alibaba.cloud.routing.consumer.constants.ConsumerConstants;
|
||||
import com.alibaba.cloud.routing.consumer.converter.Converter;
|
||||
import com.alibaba.cloud.routing.consumer.util.ReadJsonFileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@Service
|
||||
public class AddGatewayRoutingRuleServiceImpl
|
||||
implements AddGatewayRoutingRuleService, ApplicationContextAware {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(AddGatewayRoutingRuleServiceImpl.class);
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
private Converter<String, List<UnifiedRoutingDataStructure>> jsonConverter;
|
||||
|
||||
private static String addRoutingRulePath;
|
||||
|
||||
static {
|
||||
org.springframework.core.io.Resource resource = new ClassPathResource(
|
||||
"add-routing-rule.json");
|
||||
|
||||
try {
|
||||
addRoutingRulePath = resource.getFile().getPath();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDataFromControlPlaneTest() {
|
||||
|
||||
log.info("Access /addRule interface, publish routing rule..." + "\n"
|
||||
+ ConsumerConstants.ADD_RULE_DESCRIPTION);
|
||||
|
||||
String content = ReadJsonFileUtils.convertFile2String(addRoutingRulePath);
|
||||
List<UnifiedRoutingDataStructure> unifiedRouteDataStructureList = jsonConverter
|
||||
.convert(content);
|
||||
|
||||
applicationContext.publishEvent(
|
||||
new RoutingDataChangedEvent(this, unifiedRouteDataStructureList));
|
||||
|
||||
log.info("Add routing rule success!");
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
[
|
||||
{
|
||||
"targetService": "routing-service-provider",
|
||||
"labelRouteRule": {
|
||||
"matchRouteList": [
|
||||
{
|
||||
"ruleList": [
|
||||
{
|
||||
"type": "header",
|
||||
"condition": "=",
|
||||
"key": "tag",
|
||||
"value": "v2"
|
||||
},
|
||||
{
|
||||
"type": "parameter",
|
||||
"condition": ">",
|
||||
"key": "id",
|
||||
"value": "10"
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"condition": "=",
|
||||
"value": "/test-a1",
|
||||
"key": null
|
||||
}
|
||||
],
|
||||
"version": "v2",
|
||||
"weight": 100,
|
||||
"fallback": null
|
||||
}
|
||||
],
|
||||
"defaultRouteVersion": "v1"
|
||||
}
|
||||
}
|
||||
]
|
@ -0,0 +1,28 @@
|
||||
server:
|
||||
port: 19098
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: gateway-consumer-example
|
||||
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: 127.0.0.1:8848
|
||||
|
||||
# Regional affinity routing configuration
|
||||
governance:
|
||||
routing:
|
||||
region: dev
|
||||
zone: zone1
|
||||
# rule: RandomRule
|
||||
|
||||
# Gateway route config
|
||||
gateway:
|
||||
routes:
|
||||
- id: label-routing-test-route
|
||||
uri: lb://routing-service-provider
|
||||
predicates:
|
||||
- Path=/routing-service-provider/**
|
||||
filters:
|
||||
- StripPrefix=1
|
@ -0,0 +1,35 @@
|
||||
[
|
||||
{
|
||||
"targetService": "routing-service-provider",
|
||||
"labelRouteRule": {
|
||||
"matchRouteList": [
|
||||
{
|
||||
"ruleList": [
|
||||
{
|
||||
"type": "header",
|
||||
"condition": "=",
|
||||
"key": "tag",
|
||||
"value": "v2"
|
||||
},
|
||||
{
|
||||
"type": "parameter",
|
||||
"condition": ">",
|
||||
"key": "id",
|
||||
"value": "10"
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"condition": "=",
|
||||
"value": "/test-a1",
|
||||
"key": null
|
||||
}
|
||||
],
|
||||
"version": "v2",
|
||||
"weight": 50,
|
||||
"fallback": null
|
||||
}
|
||||
],
|
||||
"defaultRouteVersion": "v1"
|
||||
}
|
||||
}
|
||||
]
|
@ -0,0 +1,224 @@
|
||||
{
|
||||
"info": {
|
||||
"_postman_id": "5b1fe8e3-9334-40b1-978c-bf7ba146b3dc",
|
||||
"name": "网关消费者",
|
||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
|
||||
"_exporter_id": "16212773"
|
||||
},
|
||||
"item": [
|
||||
{
|
||||
"name": "sc-gw",
|
||||
"item": [
|
||||
{
|
||||
"name": "添加路由规则",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19098/addRule",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19098",
|
||||
"path": [
|
||||
"addRule"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "更新路由规则",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19098/updateRule",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19098",
|
||||
"path": [
|
||||
"updateRule"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "V1版本测试",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19098/routing-service-provider/test-a1",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19098",
|
||||
"path": [
|
||||
"routing-service-provider",
|
||||
"test-a1"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "V2版本测试",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "tag",
|
||||
"value": "v2",
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "http://localhost:19098/routing-service-provider/test-a1?id=11",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19098",
|
||||
"path": [
|
||||
"routing-service-provider",
|
||||
"test-a1"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "id",
|
||||
"value": "11"
|
||||
},
|
||||
{
|
||||
"key": "tag",
|
||||
"value": "v2",
|
||||
"disabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "获取服务列表",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19098/services",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19098",
|
||||
"path": [
|
||||
"services"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "zuul",
|
||||
"item": [
|
||||
{
|
||||
"name": "V1版本测试",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19099/routing-service-provider/test-a1",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19099",
|
||||
"path": [
|
||||
"routing-service-provider",
|
||||
"test-a1"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "V2版本测试",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "tag",
|
||||
"value": "v2",
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "http://localhost:19099/routing-service-provider/test-a1?id=11",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19099",
|
||||
"path": [
|
||||
"routing-service-provider",
|
||||
"test-a1"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "id",
|
||||
"value": "11"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "添加路由规则",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19099/addRule",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19099",
|
||||
"path": [
|
||||
"addRule"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "更新路由规则",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19099/updateRule",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19099",
|
||||
"path": [
|
||||
"updateRule"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-examples</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>zuul-consumer-example</artifactId>
|
||||
<name>Label Routing Zuul Consumer Example</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-governance-routing</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-commons</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>label-routing-example-common</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.example.zuul;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@EnableZuulProxy
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication
|
||||
public class ZuulConsumerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
SpringApplication.run(ZuulConsumerApplication.class);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.example.zuul.controller;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import com.alibaba.example.zuul.service.AddZuulRoutingRuleService;
|
||||
import com.alibaba.example.zuul.service.UpdateZuulRoutingRuleService;
|
||||
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@RestController
|
||||
public class ZuulConsumerController {
|
||||
|
||||
@Resource
|
||||
private AddZuulRoutingRuleService addZuulRoutingRuleService;
|
||||
|
||||
@Resource
|
||||
private UpdateZuulRoutingRuleService updateZuulRoutingRuleService;
|
||||
|
||||
@GetMapping("/addRule")
|
||||
public void getDataFromControlPlaneTest() {
|
||||
|
||||
addZuulRoutingRuleService.getDataFromControlPlaneTest();
|
||||
}
|
||||
|
||||
@GetMapping("/updateRule")
|
||||
public void updateDataFromControlPlaneTest() {
|
||||
|
||||
updateZuulRoutingRuleService.updateDataFromControlPlaneTest();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.example.zuul.service;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
public interface AddZuulRoutingRuleService {
|
||||
|
||||
void getDataFromControlPlaneTest();
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.example.zuul.service;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
public interface UpdateZuulRoutingRuleService {
|
||||
|
||||
void updateDataFromControlPlaneTest();
|
||||
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.example.zuul.service.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.cloud.commons.governance.event.RoutingDataChangedEvent;
|
||||
import com.alibaba.cloud.commons.governance.routing.UnifiedRoutingDataStructure;
|
||||
import com.alibaba.cloud.routing.consumer.constants.ConsumerConstants;
|
||||
import com.alibaba.cloud.routing.consumer.converter.Converter;
|
||||
import com.alibaba.cloud.routing.consumer.util.ReadJsonFileUtils;
|
||||
import com.alibaba.example.zuul.service.AddZuulRoutingRuleService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@Service
|
||||
public class AddZuulRoutingRuleServiceImpl
|
||||
implements AddZuulRoutingRuleService, ApplicationContextAware {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(AddZuulRoutingRuleServiceImpl.class);
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
private Converter<String, List<UnifiedRoutingDataStructure>> jsonConverter;
|
||||
|
||||
private static String addRoutingRulePath;
|
||||
|
||||
static {
|
||||
org.springframework.core.io.Resource resource = new ClassPathResource(
|
||||
"add-routing-rule.json");
|
||||
|
||||
try {
|
||||
addRoutingRulePath = resource.getFile().getPath();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDataFromControlPlaneTest() {
|
||||
|
||||
log.info("Access /addRule interface, publish routing rule..." + "\n"
|
||||
+ ConsumerConstants.ADD_RULE_DESCRIPTION);
|
||||
|
||||
String content = ReadJsonFileUtils.convertFile2String(addRoutingRulePath);
|
||||
List<UnifiedRoutingDataStructure> unifiedRouteDataStructureList = jsonConverter
|
||||
.convert(content);
|
||||
|
||||
applicationContext.publishEvent(
|
||||
new RoutingDataChangedEvent(this, unifiedRouteDataStructureList));
|
||||
|
||||
log.info("Add routing rule success!");
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
[
|
||||
{
|
||||
"targetService": "routing-service-provider",
|
||||
"labelRouteRule": {
|
||||
"matchRouteList": [
|
||||
{
|
||||
"ruleList": [
|
||||
{
|
||||
"type": "header",
|
||||
"condition": "=",
|
||||
"key": "tag",
|
||||
"value": "v2"
|
||||
},
|
||||
{
|
||||
"type": "parameter",
|
||||
"condition": ">",
|
||||
"key": "id",
|
||||
"value": "10"
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"condition": "=",
|
||||
"value": "/routing-service-provider/test-a1",
|
||||
"key": null
|
||||
}
|
||||
],
|
||||
"version": "v2",
|
||||
"weight": 100,
|
||||
"fallback": null
|
||||
}
|
||||
],
|
||||
"defaultRouteVersion": "v1"
|
||||
}
|
||||
}
|
||||
]
|
@ -0,0 +1,25 @@
|
||||
server:
|
||||
port: 19099
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: zuul-consumer-example
|
||||
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: 127.0.0.1:8848
|
||||
|
||||
# Regional affinity routing configuration
|
||||
governance:
|
||||
routing:
|
||||
region: dev
|
||||
zone: zone1
|
||||
# rule: RandomRule
|
||||
|
||||
# Zuul route config
|
||||
zuul:
|
||||
routes:
|
||||
my-service:
|
||||
serviceId: routing-service-provider
|
||||
path: /routing-service-provider/**
|
@ -0,0 +1,35 @@
|
||||
[
|
||||
{
|
||||
"targetService": "routing-service-provider",
|
||||
"labelRouteRule": {
|
||||
"matchRouteList": [
|
||||
{
|
||||
"ruleList": [
|
||||
{
|
||||
"type": "header",
|
||||
"condition": "=",
|
||||
"key": "tag",
|
||||
"value": "v2"
|
||||
},
|
||||
{
|
||||
"type": "parameter",
|
||||
"condition": ">",
|
||||
"key": "id",
|
||||
"value": "10"
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"condition": "=",
|
||||
"value": "/routing-service-provider/test-a1",
|
||||
"key": null
|
||||
}
|
||||
],
|
||||
"version": "v2",
|
||||
"weight": 50,
|
||||
"fallback": null
|
||||
}
|
||||
],
|
||||
"defaultRouteVersion": "v1"
|
||||
}
|
||||
}
|
||||
]
|
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-examples</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<version>${revision}</version>
|
||||
<name> Label Routing Example Common Module </name>
|
||||
<packaging>jar</packaging>
|
||||
<artifactId>label-routing-example-common</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>2.0.26</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-alibaba-commons</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
21
spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-governance-routing/src/main/java/com/alibaba/cloud/routing/ribbon/RoutingLoadBalanceRuleAutoConfiguration.java → spring-cloud-alibaba-examples/governance-example/label-routing-example/label-routing-example-common/src/main/java/com/alibaba/cloud/routing/consumer/config/ConsumerCommonConfig.java
21
spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-governance-routing/src/main/java/com/alibaba/cloud/routing/ribbon/RoutingLoadBalanceRuleAutoConfiguration.java → spring-cloud-alibaba-examples/governance-example/label-routing-example/label-routing-example-common/src/main/java/com/alibaba/cloud/routing/consumer/config/ConsumerCommonConfig.java
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.routing.consumer.constants;
|
||||
|
||||
/**
|
||||
* @author yuluo
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
public final class ConsumerConstants {
|
||||
|
||||
private ConsumerConstants() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Service port.
|
||||
*/
|
||||
public static final String PORT = "port";
|
||||
|
||||
/**
|
||||
* Service host.
|
||||
*/
|
||||
public static final String HOST = "host";
|
||||
|
||||
/**
|
||||
* Service instance id.
|
||||
*/
|
||||
public static final String INSTANCE_ID = "instanceId";
|
||||
|
||||
/**
|
||||
* Service provider name.
|
||||
*/
|
||||
public static final String SERVICE_PROVIDER_NAME = "routing-service-provider";
|
||||
|
||||
/**
|
||||
* Access service provider url.
|
||||
*/
|
||||
public static final String SERVICE_PROVIDER_ADDRESS = "http://"
|
||||
+ SERVICE_PROVIDER_NAME;
|
||||
|
||||
/**
|
||||
* Routing rule description.
|
||||
*/
|
||||
public static final String ADD_RULE_DESCRIPTION = "If the request parameters contain `tag=v2`, the request header contains id and the value is less than 10, and the uri is `/test-a1`, then all traffic will be routed to the v2 version. If one of them is not satisfied, the traffic will be routed to In v1 version.";
|
||||
|
||||
/**
|
||||
* Routing rule description.
|
||||
*/
|
||||
public static final String UPDATE_RULE_DESCRIPTION = "If the request parameters contain `tag=v2`, the request header contains id and the value is less than 10, and the uri is `/test-a1`, then 50% of the traffic is routed to the v2 version, and the remaining traffic is routed to the v1 version. If any one of them is not satisfied, the traffic will be routed to version v1.";
|
||||
|
||||
/**
|
||||
* Gateway Consumer Constants.
|
||||
*/
|
||||
public class GatewayConsumerConstants {
|
||||
|
||||
/**
|
||||
* Gateway consumer example name.
|
||||
*/
|
||||
public static final String GATEWAY_CONSUMER_EXAMPLE = "gateway-consumer-example";
|
||||
|
||||
/**
|
||||
* Zuul consumer example name.
|
||||
*/
|
||||
public static final String ZUUL_CONSUMER_EXAMPLE = "zuul-consumer-example";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* WebClient Consumer Constants.
|
||||
*/
|
||||
public class WebClientConsumerConstants {
|
||||
|
||||
/**
|
||||
* RestTemplate consumer Application name.
|
||||
*/
|
||||
public static final String REST_APPLICATION_NAME = "routing-rest-consumer";
|
||||
|
||||
/**
|
||||
* Openfeign consumer Application name.
|
||||
*/
|
||||
public static final String FEIGN_APPLICATION_NAME = "routing-feign-consumer";
|
||||
|
||||
/**
|
||||
* WebClient consumer Application name.
|
||||
*/
|
||||
public static final String WEBCLIENT_APPLICATION_NAME = "routing-reactive-consumer";
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.routing.consumer.converter;
|
||||
|
||||
/**
|
||||
* @author yuluo
|
||||
* @author 1481556636@qq.com
|
||||
*/
|
||||
|
||||
public interface Converter<S, T> {
|
||||
|
||||
T convert(S val);
|
||||
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.routing.consumer.converter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.cloud.commons.governance.routing.UnifiedRoutingDataStructure;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
|
||||
/**
|
||||
* @author yuluo
|
||||
* @author 1481556636@qq.com
|
||||
*/
|
||||
|
||||
public class JsonConverter
|
||||
implements Converter<String, List<UnifiedRoutingDataStructure>> {
|
||||
|
||||
@Override
|
||||
public List<UnifiedRoutingDataStructure> convert(String val) {
|
||||
|
||||
return JSON.parseObject(val,
|
||||
new TypeReference<List<UnifiedRoutingDataStructure>>() {
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.routing.consumer.entity;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@Component
|
||||
public final class ConsumerNodeInfo {
|
||||
|
||||
private static Map<String, List<Map<String, List<String>>>> nodeIno = new ConcurrentHashMap<>();
|
||||
|
||||
private ConsumerNodeInfo() {
|
||||
}
|
||||
|
||||
public static void set(String var1, List<Map<String, List<String>>> var2) {
|
||||
|
||||
nodeIno.put(var1, var2);
|
||||
}
|
||||
|
||||
public static List<Map<String, List<String>>> get(String var) {
|
||||
|
||||
return nodeIno.get(var);
|
||||
}
|
||||
|
||||
public static Map<String, List<Map<String, List<String>>>> getNodeIno() {
|
||||
|
||||
return nodeIno;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.routing.consumer.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author yuluo
|
||||
* @author 1481556636@qq.com
|
||||
*/
|
||||
|
||||
public final class ReadJsonFileUtils {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ReadJsonFileUtils.class);
|
||||
|
||||
private ReadJsonFileUtils() {
|
||||
}
|
||||
|
||||
public static String convertFile2String(String filePath) {
|
||||
|
||||
File file = new File(filePath);
|
||||
StringBuilder content = new StringBuilder();
|
||||
|
||||
try (Scanner scanner = new Scanner(file)) {
|
||||
while (scanner.hasNextLine()) {
|
||||
content.append(scanner.nextLine()).append("\n");
|
||||
}
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
log.warn("File not found: " + filePath);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return content.toString();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.alibaba.cloud.routing.consumer.config.ConsumerCommonConfig
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.example.convert;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import com.alibaba.cloud.commons.governance.routing.UnifiedRoutingDataStructure;
|
||||
import com.alibaba.cloud.routing.consumer.config.ConsumerCommonConfig;
|
||||
import com.alibaba.cloud.routing.consumer.converter.Converter;
|
||||
import com.alibaba.cloud.routing.consumer.converter.JsonConverter;
|
||||
import com.alibaba.cloud.routing.consumer.util.ReadJsonFileUtils;
|
||||
import com.fasterxml.jackson.databind.json.JsonMapper;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
/**
|
||||
* @author yuluo
|
||||
* @author 1481556636@qq.com
|
||||
*/
|
||||
|
||||
@SpringBootTest(classes = TestConverter.TestConfig.class)
|
||||
@RunWith(SpringRunner.class)
|
||||
public class TestConverter {
|
||||
|
||||
Resource resource = new ClassPathResource("add-routing-rule.json");
|
||||
|
||||
@Autowired
|
||||
private Converter<String, List<UnifiedRoutingDataStructure>> jsonConverter;
|
||||
|
||||
private static final String data = "[{\"targetService\":\"routing-service-provider\",\"labelRouteRule\":{\"matchRouteList\":[{\"ruleList\":[{\"value\":\"v2\",\"key\":\"tag\",\"type\":\"header\",\"condition\":\"=\"},{\"value\":\"10\",\"key\":\"id\",\"type\":\"parameter\",\"condition\":\">\"},{\"value\":\"/router-test\",\"key\":null,\"type\":\"path\",\"condition\":\"=\"}],\"version\":\"v2\",\"weight\":100,\"fallback\":null}],\"defaultRouteVersion\":\"v1\"}}]";
|
||||
|
||||
@Test
|
||||
public void test_json_converter() throws IOException {
|
||||
|
||||
String content = ReadJsonFileUtils
|
||||
.convertFile2String(resource.getFile().getPath());
|
||||
|
||||
Assert.assertEquals(data,
|
||||
new JsonMapper().writeValueAsString(jsonConverter.convert(content)));
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@ImportAutoConfiguration({ ConsumerCommonConfig.class })
|
||||
public static class TestConfig {
|
||||
|
||||
@Bean
|
||||
public Converter<String, List<UnifiedRoutingDataStructure>> jonConverter() {
|
||||
|
||||
return new JsonConverter();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
[
|
||||
{
|
||||
"targetService": "routing-service-provider",
|
||||
"labelRouteRule": {
|
||||
"matchRouteList": [
|
||||
{
|
||||
"ruleList": [
|
||||
{
|
||||
"type": "header",
|
||||
"condition": "=",
|
||||
"key": "tag",
|
||||
"value": "v2"
|
||||
},
|
||||
{
|
||||
"type": "parameter",
|
||||
"condition": ">",
|
||||
"key": "id",
|
||||
"value": "10"
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"condition": "=",
|
||||
"value": "/router-test",
|
||||
"key": null
|
||||
}
|
||||
],
|
||||
"version": "v2",
|
||||
"weight": 100,
|
||||
"fallback": null
|
||||
}
|
||||
],
|
||||
"defaultRouteVersion": "v1"
|
||||
}
|
||||
}
|
||||
]
|
20
spring-cloud-alibaba-examples/governance-example/label-routing-example/provider-version-example/src/main/java/com/alibaba/cloud/examples/ProviderApplication.java → spring-cloud-alibaba-examples/governance-example/label-routing-example/routing-service-provider-example/src/main/java/com/alibaba/cloud/examples/A1ProviderApplication.java
20
spring-cloud-alibaba-examples/governance-example/label-routing-example/provider-version-example/src/main/java/com/alibaba/cloud/examples/ProviderApplication.java → spring-cloud-alibaba-examples/governance-example/label-routing-example/routing-service-provider-example/src/main/java/com/alibaba/cloud/examples/A1ProviderApplication.java
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.examples;
|
||||
|
||||
import com.alibaba.cloud.nacos.registry.NacosRegistration;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author yuluo
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication
|
||||
public class A2ProviderApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.setProperty("spring.profiles.active", "a2");
|
||||
SpringApplication.run(A2ProviderApplication.class, args);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
NacosRegistration nacosRegistration;
|
||||
|
||||
@RestController
|
||||
class A2Controller {
|
||||
|
||||
@GetMapping("/test-a2")
|
||||
public String testA2() {
|
||||
|
||||
String host = nacosRegistration.getHost();
|
||||
int port = nacosRegistration.getPort();
|
||||
String zone = nacosRegistration.getMetadata().get("zone");
|
||||
String region = nacosRegistration.getMetadata().get("region");
|
||||
String version = nacosRegistration.getMetadata().get("version");
|
||||
return "Route in " + host + ":" + port + ", region: " + region + ", zone: "
|
||||
+ zone + ", version: " + version;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
21
spring-cloud-alibaba-examples/governance-example/label-routing-example/default-provider-version-example/src/main/java/com/alibaba/cloud/examples/ProviderApplication.java → spring-cloud-alibaba-examples/governance-example/label-routing-example/routing-service-provider-example/src/main/java/com/alibaba/cloud/examples/A3ProviderApplication.java
21
spring-cloud-alibaba-examples/governance-example/label-routing-example/default-provider-version-example/src/main/java/com/alibaba/cloud/examples/ProviderApplication.java → spring-cloud-alibaba-examples/governance-example/label-routing-example/routing-service-provider-example/src/main/java/com/alibaba/cloud/examples/A3ProviderApplication.java
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.examples;
|
||||
|
||||
import com.alibaba.cloud.nacos.registry.NacosRegistration;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author yuluo
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication
|
||||
public class A4ProviderApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.setProperty("spring.profiles.active", "a4");
|
||||
SpringApplication.run(A4ProviderApplication.class, args);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
NacosRegistration nacosRegistration;
|
||||
|
||||
@RestController
|
||||
class A4Controller {
|
||||
|
||||
@GetMapping("/test-a4")
|
||||
public String testA4() {
|
||||
|
||||
String host = nacosRegistration.getHost();
|
||||
int port = nacosRegistration.getPort();
|
||||
String zone = nacosRegistration.getMetadata().get("zone");
|
||||
String region = nacosRegistration.getMetadata().get("region");
|
||||
String version = nacosRegistration.getMetadata().get("version");
|
||||
return "Route in " + host + ":" + port + ", region: " + region + ", zone: "
|
||||
+ zone + ", version: " + version;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,9 +1,6 @@
|
||||
server.port=18082
|
||||
spring.application.name=service-provider
|
||||
# register center configuration
|
||||
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
|
||||
spring.cloud.nacos.discovery.enabled=true
|
||||
spring.cloud.nacos.discovery.metadata.version=v2
|
||||
|
||||
spring.cloud.nacos.username=nacos
|
||||
spring.cloud.nacos.password=nacos
|
||||
|
@ -0,0 +1,9 @@
|
||||
server.port=19091
|
||||
|
||||
# spring application configuration
|
||||
spring.application.name=routing-service-provider
|
||||
|
||||
# register center configuration
|
||||
spring.cloud.nacos.discovery.metadata.version=v1
|
||||
spring.cloud.nacos.discovery.metadata.region=qa
|
||||
spring.cloud.nacos.discovery.metadata.zone=zone1
|
@ -0,0 +1,9 @@
|
||||
server.port=19092
|
||||
|
||||
# spring application configuration
|
||||
spring.application.name=routing-service-provider
|
||||
|
||||
# register center configuration
|
||||
spring.cloud.nacos.discovery.metadata.version=v2
|
||||
spring.cloud.nacos.discovery.metadata.region=qa
|
||||
spring.cloud.nacos.discovery.metadata.zone=zone2
|
@ -0,0 +1,9 @@
|
||||
server.port=19093
|
||||
|
||||
# spring application configuration
|
||||
spring.application.name=routing-service-provider
|
||||
|
||||
# register center configuration
|
||||
spring.cloud.nacos.discovery.metadata.version=v1
|
||||
spring.cloud.nacos.discovery.metadata.region=dev
|
||||
spring.cloud.nacos.discovery.metadata.zone=zone1
|
@ -0,0 +1,9 @@
|
||||
server.port=19094
|
||||
|
||||
# spring application configuration
|
||||
spring.application.name=routing-service-provider
|
||||
|
||||
# register center configuration
|
||||
spring.cloud.nacos.discovery.metadata.version=v2
|
||||
spring.cloud.nacos.discovery.metadata.region=dev
|
||||
spring.cloud.nacos.discovery.metadata.zone=zone2
|
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>web-client-consumer-example</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>openfeign-consumer-example</artifactId>
|
||||
<name> Label Routing OpenFeign Consumer Example</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>label-routing-example-common</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.consumer.feign;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.EnableFeignClients;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@EnableFeignClients
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication
|
||||
public class ConsumerFeignApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
SpringApplication.run(ConsumerFeignApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.consumer.feign.api;
|
||||
|
||||
import com.alibaba.cloud.routing.consumer.constants.ConsumerConstants;
|
||||
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@FeignClient(name = ConsumerConstants.SERVICE_PROVIDER_NAME)
|
||||
public interface ConsumerFeignService {
|
||||
|
||||
/**
|
||||
* Feign test api.
|
||||
* @return String type.
|
||||
*/
|
||||
@GetMapping("/test-a1")
|
||||
String routerTest();
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.consumer.feign.configuration;
|
||||
|
||||
import com.alibaba.cloud.consumer.feign.decorator.ConsumerFeignClientDecorator;
|
||||
import feign.Client;
|
||||
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.cloud.openfeign.ribbon.CachingSpringLoadBalancerFactory;
|
||||
import org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@Configuration
|
||||
public class ConsumerFeignConfiguration {
|
||||
|
||||
@Bean
|
||||
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
|
||||
SpringClientFactory clientFactory) {
|
||||
|
||||
return new LoadBalancerFeignClient(
|
||||
new ConsumerFeignClientDecorator(new Client.Default(null, null)),
|
||||
cachingFactory, clientFactory);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.consumer.feign.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.cloud.commons.governance.event.RoutingDataChangedEvent;
|
||||
import com.alibaba.cloud.commons.governance.routing.UnifiedRoutingDataStructure;
|
||||
import com.alibaba.cloud.consumer.feign.api.ConsumerFeignService;
|
||||
import com.alibaba.cloud.routing.consumer.constants.ConsumerConstants;
|
||||
import com.alibaba.cloud.routing.consumer.converter.Converter;
|
||||
import com.alibaba.cloud.routing.consumer.entity.ConsumerNodeInfo;
|
||||
import com.alibaba.cloud.routing.consumer.util.ReadJsonFileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@RestController
|
||||
public class ConsumerFeignController implements ApplicationContextAware {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(ConsumerFeignController.class);
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
private ConsumerFeignService consumerFeignService;
|
||||
|
||||
@Autowired
|
||||
private Converter<String, List<UnifiedRoutingDataStructure>> jsonConverter;
|
||||
|
||||
private static String addRoutingRulePath;
|
||||
|
||||
private static String updateRoutingRulePath;
|
||||
|
||||
static {
|
||||
org.springframework.core.io.Resource resource1 = new ClassPathResource(
|
||||
"add-routing-rule.json");
|
||||
org.springframework.core.io.Resource resource2 = new ClassPathResource(
|
||||
"update-routing-rule.json");
|
||||
|
||||
try {
|
||||
addRoutingRulePath = resource1.getFile().getPath();
|
||||
updateRoutingRulePath = resource2.getFile().getPath();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@GetMapping("/info4node")
|
||||
public Map<String, List<Map<String, List<String>>>> getInfo4Node() {
|
||||
|
||||
return ConsumerNodeInfo.getNodeIno();
|
||||
}
|
||||
|
||||
@GetMapping("/router-test")
|
||||
public String notFound() {
|
||||
|
||||
return consumerFeignService.routerTest();
|
||||
}
|
||||
|
||||
@GetMapping("/add")
|
||||
public void getDataFromControlPlaneTest() {
|
||||
|
||||
log.info("Access /add routing rule interface, add routing rule..." + "\n"
|
||||
+ ConsumerConstants.ADD_RULE_DESCRIPTION);
|
||||
|
||||
String content = ReadJsonFileUtils.convertFile2String(addRoutingRulePath);
|
||||
List<UnifiedRoutingDataStructure> unifiedRouteDataStructureList = jsonConverter
|
||||
.convert(content);
|
||||
|
||||
applicationContext.publishEvent(
|
||||
new RoutingDataChangedEvent(this, unifiedRouteDataStructureList));
|
||||
|
||||
log.info("Add routing rule success!");
|
||||
}
|
||||
|
||||
@GetMapping("/update")
|
||||
public void updateDataFromControlPlaneTest() {
|
||||
|
||||
log.info("Access /update routing rule interface, update routing rule..." + "\n"
|
||||
+ ConsumerConstants.UPDATE_RULE_DESCRIPTION);
|
||||
|
||||
String content = ReadJsonFileUtils.convertFile2String(updateRoutingRulePath);
|
||||
List<UnifiedRoutingDataStructure> unifiedRouteDataStructureList = jsonConverter
|
||||
.convert(content);
|
||||
|
||||
applicationContext.publishEvent(
|
||||
new RoutingDataChangedEvent(this, unifiedRouteDataStructureList));
|
||||
|
||||
log.info("Update routing rule success!");
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.consumer.feign.decorator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.cloud.routing.consumer.constants.ConsumerConstants;
|
||||
import com.alibaba.cloud.routing.consumer.entity.ConsumerNodeInfo;
|
||||
import feign.Client;
|
||||
import feign.Request;
|
||||
import feign.Response;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*
|
||||
* Rewrite the feign client to get the feign response.
|
||||
*/
|
||||
|
||||
public class ConsumerFeignClientDecorator implements Client {
|
||||
|
||||
private final Client delegateClient;
|
||||
|
||||
public ConsumerFeignClientDecorator(Client delegateClient) {
|
||||
this.delegateClient = delegateClient;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response execute(Request request, Request.Options options) throws IOException {
|
||||
|
||||
Response response = delegateClient.execute(request, options);
|
||||
|
||||
List<Map<String, List<String>>> list = new ArrayList<>();
|
||||
|
||||
request.headers().forEach((k, v) -> {
|
||||
Map<String, List<String>> headerMap = new HashMap<>();
|
||||
List<String> headerValue = new ArrayList<>(v);
|
||||
headerMap.put(k, headerValue);
|
||||
list.add(headerMap);
|
||||
});
|
||||
ConsumerNodeInfo.set(
|
||||
ConsumerConstants.WebClientConsumerConstants.FEIGN_APPLICATION_NAME,
|
||||
list);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.consumer.feign.decorator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import com.alibaba.cloud.routing.consumer.constants.ConsumerConstants;
|
||||
import com.alibaba.cloud.routing.consumer.entity.ConsumerNodeInfo;
|
||||
import feign.FeignException;
|
||||
import feign.Response;
|
||||
import feign.Util;
|
||||
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.openfeign.support.SpringDecoder;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@Component
|
||||
public class ConsumerFeignResponseDecoder extends SpringDecoder {
|
||||
|
||||
@Resource
|
||||
private DiscoveryClient discoveryClient;
|
||||
|
||||
public ConsumerFeignResponseDecoder(
|
||||
ObjectFactory<HttpMessageConverters> messageConverters) {
|
||||
|
||||
super(messageConverters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object decode(Response response, Type type)
|
||||
throws IOException, FeignException {
|
||||
|
||||
Reader reader = response.body().asReader(StandardCharsets.UTF_8);
|
||||
String res = Util.toString(reader);
|
||||
String result = getResult(res);
|
||||
if (Objects.isNull(result)) {
|
||||
|
||||
return super.decode(
|
||||
response.toBuilder().body(res, StandardCharsets.UTF_8).build(), type);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
private String getResult(String res) {
|
||||
|
||||
String serverPort = res.substring(21, 26);
|
||||
|
||||
List<String> services = discoveryClient.getServices();
|
||||
for (String service : services) {
|
||||
List<ServiceInstance> instances = discoveryClient.getInstances(service);
|
||||
for (ServiceInstance instance : instances) {
|
||||
if ((instance.getPort() + "").equals(serverPort)) {
|
||||
String server = instance.getServiceId();
|
||||
Map<String, String> metadata = instance.getMetadata();
|
||||
List<Map<String, List<String>>> metaList = new ArrayList<>();
|
||||
Map<String, List<String>> map = new HashMap<>();
|
||||
for (String s : metadata.keySet()) {
|
||||
map.put(s, Collections.singletonList(metadata.get(s)));
|
||||
}
|
||||
map.put(ConsumerConstants.PORT,
|
||||
Collections.singletonList(instance.getPort() + ""));
|
||||
map.put(ConsumerConstants.HOST,
|
||||
Collections.singletonList(instance.getHost()));
|
||||
map.put(ConsumerConstants.INSTANCE_ID,
|
||||
Collections.singletonList(instance.getInstanceId()));
|
||||
metaList.add(map);
|
||||
|
||||
ConsumerNodeInfo.set(server, metaList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
[
|
||||
{
|
||||
"targetService": "routing-service-provider",
|
||||
"labelRouteRule": {
|
||||
"matchRouteList": [
|
||||
{
|
||||
"ruleList": [
|
||||
{
|
||||
"type": "header",
|
||||
"condition": "=",
|
||||
"key": "tag",
|
||||
"value": "v2"
|
||||
},
|
||||
{
|
||||
"type": "parameter",
|
||||
"condition": ">",
|
||||
"key": "id",
|
||||
"value": "10"
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"condition": "=",
|
||||
"value": "/router-test",
|
||||
"key": null
|
||||
}
|
||||
],
|
||||
"version": "v2",
|
||||
"weight": 100,
|
||||
"fallback": null
|
||||
}
|
||||
],
|
||||
"defaultRouteVersion": "v1"
|
||||
}
|
||||
}
|
||||
]
|
@ -0,0 +1,21 @@
|
||||
server:
|
||||
port: 19095
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: openfeign-service-consumer
|
||||
|
||||
cloud:
|
||||
|
||||
# register center configuration
|
||||
nacos:
|
||||
discovery:
|
||||
fail-fast: true
|
||||
server-addr: 127.0.0.1:8848
|
||||
|
||||
# label routing configuration
|
||||
governance:
|
||||
routing:
|
||||
region: dev
|
||||
zone: zone1
|
||||
# rule: RandomRule
|
@ -0,0 +1,35 @@
|
||||
[
|
||||
{
|
||||
"targetService": "routing-service-provider",
|
||||
"labelRouteRule": {
|
||||
"matchRouteList": [
|
||||
{
|
||||
"ruleList": [
|
||||
{
|
||||
"type": "header",
|
||||
"condition": "=",
|
||||
"key": "tag",
|
||||
"value": "v2"
|
||||
},
|
||||
{
|
||||
"type": "parameter",
|
||||
"condition": ">",
|
||||
"key": "id",
|
||||
"value": "10"
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"condition": "=",
|
||||
"value": "/router-test",
|
||||
"key": null
|
||||
}
|
||||
],
|
||||
"version": "v2",
|
||||
"weight": 50,
|
||||
"fallback": null
|
||||
}
|
||||
],
|
||||
"defaultRouteVersion": "v1"
|
||||
}
|
||||
}
|
||||
]
|
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>web-client-consumer-example</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>reactive-consumer-example</artifactId>
|
||||
<name> Label Routing Reactive Consumer Example</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>label-routing-example-common</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.consumer.reactive;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient
|
||||
public class ConsumerReactiveApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
SpringApplication.run(ConsumerReactiveApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.consumer.reactive.configuration;
|
||||
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.reactive.function.BodyExtractors;
|
||||
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@Configuration
|
||||
public class ConsumerWebClientConfiguration {
|
||||
|
||||
private static String serverPort = null;
|
||||
|
||||
@Bean
|
||||
@LoadBalanced
|
||||
public WebClient.Builder webClient() {
|
||||
|
||||
return WebClient.builder().filter(response());
|
||||
}
|
||||
|
||||
private ExchangeFilterFunction response() {
|
||||
|
||||
return ExchangeFilterFunction.ofResponseProcessor(clientResponse -> {
|
||||
|
||||
Object body = clientResponse.body(BodyExtractors.toDataBuffers());
|
||||
serverPort = body.toString().substring(45, 50);
|
||||
|
||||
return Mono.just(clientResponse);
|
||||
});
|
||||
}
|
||||
|
||||
public String getServerPort() {
|
||||
|
||||
return serverPort;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.consumer.reactive.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import com.alibaba.cloud.commons.governance.event.RoutingDataChangedEvent;
|
||||
import com.alibaba.cloud.commons.governance.routing.UnifiedRoutingDataStructure;
|
||||
import com.alibaba.cloud.consumer.reactive.configuration.ConsumerWebClientConfiguration;
|
||||
import com.alibaba.cloud.routing.consumer.constants.ConsumerConstants;
|
||||
import com.alibaba.cloud.routing.consumer.converter.Converter;
|
||||
import com.alibaba.cloud.routing.consumer.entity.ConsumerNodeInfo;
|
||||
import com.alibaba.cloud.routing.consumer.util.ReadJsonFileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@RestController
|
||||
public class ConsumerReactiveController implements ApplicationContextAware {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(ConsumerReactiveController.class);
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Resource
|
||||
private ReactiveDiscoveryClient reactiveDiscoveryClient;
|
||||
|
||||
@Resource
|
||||
private WebClient.Builder webClientBuilder;
|
||||
|
||||
@Resource
|
||||
private ConsumerWebClientConfiguration consumerWebClientConfiguration;
|
||||
|
||||
@Autowired
|
||||
private DiscoveryClient discoveryClient;
|
||||
|
||||
private static String addRoutingRulePath;
|
||||
|
||||
private static String updateRoutingRulePath;
|
||||
|
||||
static {
|
||||
org.springframework.core.io.Resource resource1 = new ClassPathResource(
|
||||
"add-routing-rule.json");
|
||||
org.springframework.core.io.Resource resource2 = new ClassPathResource(
|
||||
"update-routing-rule.json");
|
||||
|
||||
try {
|
||||
addRoutingRulePath = resource1.getFile().getPath();
|
||||
updateRoutingRulePath = resource2.getFile().getPath();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private Converter<String, List<UnifiedRoutingDataStructure>> jsonConverter;
|
||||
|
||||
@GetMapping("/info4node")
|
||||
public Map<String, List<Map<String, List<String>>>> getInfo4Node() {
|
||||
|
||||
String serverPort = consumerWebClientConfiguration.getServerPort();
|
||||
|
||||
List<String> services = discoveryClient.getServices();
|
||||
for (String service : services) {
|
||||
List<ServiceInstance> instances = discoveryClient.getInstances(service);
|
||||
for (ServiceInstance instance : instances) {
|
||||
if ((instance.getPort() + "").equals(serverPort)) {
|
||||
String server = instance.getServiceId();
|
||||
Map<String, String> metadata = instance.getMetadata();
|
||||
List<Map<String, List<String>>> metaList = new ArrayList<>();
|
||||
Map<String, List<String>> nmap = new HashMap<>();
|
||||
for (String s : metadata.keySet()) {
|
||||
nmap.put(s, Collections.singletonList(metadata.get(s)));
|
||||
}
|
||||
nmap.put(ConsumerConstants.PORT,
|
||||
Collections.singletonList(instance.getPort() + ""));
|
||||
nmap.put(ConsumerConstants.HOST,
|
||||
Collections.singletonList(instance.getHost()));
|
||||
nmap.put(ConsumerConstants.INSTANCE_ID,
|
||||
Collections.singletonList(instance.getInstanceId()));
|
||||
metaList.add(nmap);
|
||||
|
||||
ConsumerNodeInfo.set(server, metaList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ConsumerNodeInfo.getNodeIno();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@GetMapping("/services")
|
||||
public Flux<String> getAllServices() {
|
||||
|
||||
return reactiveDiscoveryClient
|
||||
.getInstances(ConsumerConstants.SERVICE_PROVIDER_NAME)
|
||||
.map(serviceInstance -> serviceInstance.getHost() + ":"
|
||||
+ serviceInstance.getPort());
|
||||
}
|
||||
|
||||
@GetMapping("/router-test")
|
||||
public Mono<String> routerTest() {
|
||||
|
||||
return webClientBuilder.build().get()
|
||||
.uri(ConsumerConstants.SERVICE_PROVIDER_ADDRESS + "/test-a1").retrieve()
|
||||
.bodyToMono(String.class);
|
||||
}
|
||||
|
||||
@GetMapping("/add")
|
||||
public void getDataFromControlPlaneTest() {
|
||||
|
||||
log.info("Access /add routing rule interface, add routing rule..." + "\n"
|
||||
+ ConsumerConstants.ADD_RULE_DESCRIPTION);
|
||||
|
||||
String content = ReadJsonFileUtils.convertFile2String(addRoutingRulePath);
|
||||
List<UnifiedRoutingDataStructure> unifiedRouteDataStructureList = jsonConverter
|
||||
.convert(content);
|
||||
|
||||
applicationContext.publishEvent(
|
||||
new RoutingDataChangedEvent(this, unifiedRouteDataStructureList));
|
||||
|
||||
log.info("Add routing rule success!");
|
||||
}
|
||||
|
||||
@GetMapping("/update")
|
||||
public void updateDataFromControlPlaneTest() {
|
||||
|
||||
log.info("Access /update routing rule interface, update routing rule..." + "\n"
|
||||
+ ConsumerConstants.UPDATE_RULE_DESCRIPTION);
|
||||
|
||||
String content = ReadJsonFileUtils.convertFile2String(updateRoutingRulePath);
|
||||
List<UnifiedRoutingDataStructure> unifiedRouteDataStructureList = jsonConverter
|
||||
.convert(content);
|
||||
|
||||
applicationContext.publishEvent(
|
||||
new RoutingDataChangedEvent(this, unifiedRouteDataStructureList));
|
||||
applicationContext.publishEvent(
|
||||
new RoutingDataChangedEvent(this, unifiedRouteDataStructureList));
|
||||
|
||||
log.info("Update routing rule success!");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
[
|
||||
{
|
||||
"targetService": "routing-service-provider",
|
||||
"labelRouteRule": {
|
||||
"matchRouteList": [
|
||||
{
|
||||
"ruleList": [
|
||||
{
|
||||
"type": "header",
|
||||
"condition": "=",
|
||||
"key": "tag",
|
||||
"value": "v2"
|
||||
},
|
||||
{
|
||||
"type": "parameter",
|
||||
"condition": ">",
|
||||
"key": "id",
|
||||
"value": "10"
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"condition": "=",
|
||||
"value": "/router-test",
|
||||
"key": null
|
||||
}
|
||||
],
|
||||
"version": "v2",
|
||||
"weight": 100,
|
||||
"fallback": null
|
||||
}
|
||||
],
|
||||
"defaultRouteVersion": "v1"
|
||||
}
|
||||
}
|
||||
]
|
@ -0,0 +1,18 @@
|
||||
server:
|
||||
port: 19096
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: webClient-service-consumer
|
||||
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: 127.0.0.1:8848
|
||||
|
||||
# label routing configuration
|
||||
governance:
|
||||
routing:
|
||||
region: dev
|
||||
zone: zone1
|
||||
# rule: RandomRule
|
@ -0,0 +1,35 @@
|
||||
[
|
||||
{
|
||||
"targetService": "routing-service-provider",
|
||||
"labelRouteRule": {
|
||||
"matchRouteList": [
|
||||
{
|
||||
"ruleList": [
|
||||
{
|
||||
"type": "header",
|
||||
"condition": "=",
|
||||
"key": "tag",
|
||||
"value": "v2"
|
||||
},
|
||||
{
|
||||
"type": "parameter",
|
||||
"condition": ">",
|
||||
"key": "id",
|
||||
"value": "10"
|
||||
},
|
||||
{
|
||||
"type": "path",
|
||||
"condition": "=",
|
||||
"value": "/router-test",
|
||||
"key": null
|
||||
}
|
||||
],
|
||||
"version": "v2",
|
||||
"weight": 50,
|
||||
"fallback": null
|
||||
}
|
||||
],
|
||||
"defaultRouteVersion": "v1"
|
||||
}
|
||||
}
|
||||
]
|
@ -0,0 +1,351 @@
|
||||
{
|
||||
"info": {
|
||||
"_postman_id": "15318bb7-4dee-4a05-af0c-373dc73b80b1",
|
||||
"name": "客户端消费者",
|
||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
|
||||
"_exporter_id": "16212773"
|
||||
},
|
||||
"item": [
|
||||
{
|
||||
"name": "feign",
|
||||
"item": [
|
||||
{
|
||||
"name": "V1版本测试",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19095/router-test",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19095",
|
||||
"path": [
|
||||
"router-test"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "V2版本测试",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "tag",
|
||||
"value": "v2",
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "http://localhost:19095/router-test?id=11",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19095",
|
||||
"path": [
|
||||
"router-test"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "id",
|
||||
"value": "11"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "添加路由配置信息",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19095/add",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19095",
|
||||
"path": [
|
||||
"add"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "更新路由规则信息",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19095/update",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19095",
|
||||
"path": [
|
||||
"update"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "获取节点信息",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": []
|
||||
},
|
||||
"response": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "resttemplate",
|
||||
"item": [
|
||||
{
|
||||
"name": "V1版本测试",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19097/router-test",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19097",
|
||||
"path": [
|
||||
"router-test"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "V2版本测试",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "tag",
|
||||
"value": "v2",
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "http://localhost:19097/router-test?id=11",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19097",
|
||||
"path": [
|
||||
"router-test"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "id",
|
||||
"value": "11"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "添加路由配置信息",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19097/add",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19097",
|
||||
"path": [
|
||||
"add"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "更新路由规则信息",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19097/update",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19097",
|
||||
"path": [
|
||||
"update"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "获取节点信息",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": []
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "获取服务列表",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": []
|
||||
},
|
||||
"response": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "webclient",
|
||||
"item": [
|
||||
{
|
||||
"name": "V1版本测试",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19096/router-test",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19096",
|
||||
"path": [
|
||||
"router-test"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "V2版本测试",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "tag",
|
||||
"value": "v2",
|
||||
"type": "text"
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "http://localhost:19096/router-test?id=11",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19096",
|
||||
"path": [
|
||||
"router-test"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "id",
|
||||
"value": "11"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "添加路由配置信息",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19096/add",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19096",
|
||||
"path": [
|
||||
"add"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "更新路由规则信息",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19096/update",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19096",
|
||||
"path": [
|
||||
"update"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "获取所有服务实例",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19096/all-services",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19096",
|
||||
"path": [
|
||||
"all-services"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "获取节点信息",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "http://localhost:19096/nodeInfo",
|
||||
"protocol": "http",
|
||||
"host": [
|
||||
"localhost"
|
||||
],
|
||||
"port": "19096",
|
||||
"path": [
|
||||
"nodeInfo"
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>web-client-consumer-example</artifactId>
|
||||
<version>${revision}</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>restTemplate-consumer-example</artifactId>
|
||||
<name> Label Routing RestTemplate Consumer Example</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>label-routing-example-common</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.consumer.resttemplate;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableDiscoveryClient
|
||||
public class ConsumerRestTemplateApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
SpringApplication.run(ConsumerRestTemplateApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.consumer.resttemplate.configuration;
|
||||
|
||||
import com.alibaba.cloud.consumer.resttemplate.interceptor.ConsumerRestRequestInterceptor;
|
||||
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.client.BufferingClientHttpRequestFactory;
|
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*
|
||||
* Resolve an issue where the response stream can only be read once.
|
||||
*/
|
||||
|
||||
@Configuration
|
||||
public class ConsumerRestTemplateConfiguration {
|
||||
|
||||
@Bean
|
||||
@LoadBalanced
|
||||
public RestTemplate restTemplate() {
|
||||
|
||||
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
|
||||
BufferingClientHttpRequestFactory simpleBufferingClientHttpRequest = new BufferingClientHttpRequestFactory(
|
||||
requestFactory);
|
||||
|
||||
RestTemplate restTemplateClient = new RestTemplate(
|
||||
simpleBufferingClientHttpRequest);
|
||||
restTemplateClient.getInterceptors().add(new ConsumerRestRequestInterceptor());
|
||||
|
||||
return restTemplateClient;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright 2013-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.alibaba.cloud.consumer.resttemplate.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.alibaba.cloud.commons.governance.event.RoutingDataChangedEvent;
|
||||
import com.alibaba.cloud.commons.governance.routing.UnifiedRoutingDataStructure;
|
||||
import com.alibaba.cloud.consumer.resttemplate.interceptor.ConsumerRestRequestInterceptor;
|
||||
import com.alibaba.cloud.routing.consumer.constants.ConsumerConstants;
|
||||
import com.alibaba.cloud.routing.consumer.converter.Converter;
|
||||
import com.alibaba.cloud.routing.consumer.entity.ConsumerNodeInfo;
|
||||
import com.alibaba.cloud.routing.consumer.util.ReadJsonFileUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* @author yuluo-yx
|
||||
* @author <a href="1481556636@qq.com"></a>
|
||||
*/
|
||||
|
||||
@RestController
|
||||
public class ConsumerRestTemplateController implements ApplicationContextAware {
|
||||
|
||||
private static final Logger log = LoggerFactory
|
||||
.getLogger(ConsumerRestTemplateController.class);
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired
|
||||
private RestTemplate restTemplate;
|
||||
|
||||
@Autowired
|
||||
private DiscoveryClient discoveryClient;
|
||||
|
||||
@Autowired
|
||||
private ConsumerRestRequestInterceptor consumerRestRequestInterceptor;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private Converter<String, List<UnifiedRoutingDataStructure>> jsonConverter;
|
||||
|
||||
private static String addRoutingRulePath;
|
||||
|
||||
private static String updateRoutingRulePath;
|
||||
|
||||
static {
|
||||
org.springframework.core.io.Resource resource1 = new ClassPathResource(
|
||||
"add-routing-rule.json");
|
||||
org.springframework.core.io.Resource resource2 = new ClassPathResource(
|
||||
"update-routing-rule.json");
|
||||
|
||||
try {
|
||||
addRoutingRulePath = resource1.getFile().getPath();
|
||||
updateRoutingRulePath = resource2.getFile().getPath();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@GetMapping("/info4node")
|
||||
public Map<String, List<Map<String, List<String>>>> getNodeInfo() {
|
||||
|
||||
String serverPort = consumerRestRequestInterceptor.getServerPort();
|
||||
|
||||
List<String> services = discoveryClient.getServices();
|
||||
for (String service : services) {
|
||||
List<ServiceInstance> instances = discoveryClient.getInstances(service);
|
||||
for (ServiceInstance instance : instances) {
|
||||
if ((instance.getPort() + "").equals(serverPort)) {
|
||||
String server = instance.getServiceId();
|
||||
Map<String, String> metadata = instance.getMetadata();
|
||||
List<Map<String, List<String>>> metaList = new ArrayList<>();
|
||||
Map<String, List<String>> nmap = new HashMap<>();
|
||||
for (String s : metadata.keySet()) {
|
||||
nmap.put(s, Collections.singletonList(metadata.get(s)));
|
||||
}
|
||||
nmap.put(ConsumerConstants.PORT,
|
||||
Collections.singletonList(instance.getPort() + ""));
|
||||
nmap.put(ConsumerConstants.HOST,
|
||||
Collections.singletonList(instance.getHost()));
|
||||
nmap.put(ConsumerConstants.INSTANCE_ID,
|
||||
Collections.singletonList(instance.getInstanceId()));
|
||||
metaList.add(nmap);
|
||||
|
||||
ConsumerNodeInfo.set(server, metaList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ConsumerNodeInfo.getNodeIno();
|
||||
}
|
||||
|
||||
@GetMapping("/services")
|
||||
public Object getAllServices() {
|
||||
|
||||
return discoveryClient.getServices();
|
||||
}
|
||||
|
||||
@GetMapping("/router-test")
|
||||
public String routerTest() {
|
||||
|
||||
return restTemplate.getForObject(
|
||||
ConsumerConstants.SERVICE_PROVIDER_ADDRESS + "/test-a1", String.class);
|
||||
}
|
||||
|
||||
@GetMapping("/add")
|
||||
public void getDataFromControlPlaneTest() {
|
||||
|
||||
log.info("Access /add routing rule interface, add routing rule..." + "\n"
|
||||
+ ConsumerConstants.ADD_RULE_DESCRIPTION);
|
||||
|
||||
String content = ReadJsonFileUtils.convertFile2String(addRoutingRulePath);
|
||||
List<UnifiedRoutingDataStructure> unifiedRouteDataStructureList = jsonConverter
|
||||
.convert(content);
|
||||
|
||||
applicationContext.publishEvent(
|
||||
new RoutingDataChangedEvent(this, unifiedRouteDataStructureList));
|
||||
|
||||
log.info("Add routing rule success!");
|
||||
|
||||
}
|
||||
|
||||
@GetMapping("/update")
|
||||
public void updateDataFromControlPlaneTest() {
|
||||
|
||||
log.info("Access /update routing rule interface, update routing rule..." + "\n"
|
||||
+ ConsumerConstants.UPDATE_RULE_DESCRIPTION);
|
||||
|
||||
String content = ReadJsonFileUtils.convertFile2String(updateRoutingRulePath);
|
||||
List<UnifiedRoutingDataStructure> unifiedRouteDataStructureList = jsonConverter
|
||||
.convert(content);
|
||||
|
||||
applicationContext.publishEvent(
|
||||
new RoutingDataChangedEvent(this, unifiedRouteDataStructureList));
|
||||
|
||||
log.info("Update routing rule success!");
|
||||
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue