| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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
- *
- * http://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 cn.exlive.exbooter.configure;
- import com.netflix.zuul.context.RequestContext;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.collections.keyvalue.DefaultKeyValue;
- import org.apache.commons.lang.StringUtils;
- import org.springframework.cloud.netflix.zuul.filters.Route;
- import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator;
- import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
- import java.net.URI;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Optional;
- import java.util.Random;
- import java.util.stream.Collectors;
- /**
- * <pre>
- *
- * Created by zhenqin.
- * User: zhenqin
- * Date: 2022/4/25
- * Time: 下午7:12
- *
- * </pre>
- *
- * @author zhenqin
- */
- @Slf4j
- public class ApiRouteLocator extends SimpleRouteLocator {
- /**
- * zull 配置
- */
- final ZuulProperties properties;
- /**
- * 随机策略
- */
- final Random r = new Random();
- public ApiRouteLocator(String servletPath, ZuulProperties properties) {
- super(servletPath, properties);
- this.properties = properties;
- }
- @Override
- protected Route getRoute(ZuulProperties.ZuulRoute route, String path) {
- if (route == null) {
- return null;
- }
- RequestContext ctx = RequestContext.getCurrentContext();
- final String referer = ctx.getRequest().getHeader("Referer");
- final Map<String, List<String>> queryParams = Optional.ofNullable(ctx.getRequestQueryParams()).orElse(new HashMap<>());
- String clusterId = queryParams.get("clusterId") == null ? null : StringUtils.join(queryParams.get("clusterId"), ",");
- if (StringUtils.isBlank(clusterId) && StringUtils.isNotBlank(referer)) {
- // 如果 URL 中没有,从 Referer 中获取
- final String query = URI.create(referer).getQuery();
- final Map<String, String> kv = Arrays.stream(query.split("&")).filter(StringUtils::isNotBlank).map(it -> {
- final String[] split = it.split("=");
- return split.length > 1 ? new DefaultKeyValue(split[0], split[1]) : new DefaultKeyValue(split[0], "");
- }).collect(Collectors.toMap(e -> (String)e.getKey(), e -> (String)e.getValue()));
- clusterId = kv.get("clusterId");
- }
- log.info("clusterId: {} and referer: {}", clusterId, referer);
- String targetPath = path;
- String prefix = this.properties.getPrefix();
- if (prefix.endsWith("/")) {
- prefix = prefix.substring(0, prefix.length() - 1);
- }
- if (path.startsWith(prefix + "/") && this.properties.isStripPrefix()) {
- targetPath = path.substring(prefix.length());
- }
- if (route.isStripPrefix()) {
- int index = route.getPath().indexOf("*") - 1;
- if (index > 0) {
- String routePrefix = route.getPath().substring(0, index);
- targetPath = targetPath.replaceFirst(routePrefix, "");
- prefix = prefix + routePrefix;
- }
- }
- Boolean retryable = this.properties.getRetryable();
- if (route.getRetryable() != null) {
- retryable = route.getRetryable();
- }
- final HashMap<String, String> globalVariables = new HashMap<>();
- // cluster: 1 path: /damp/aaa/bbb match to: http://localhost:8083/damp
- log.info("cluster: {} path: {} match to: {}", clusterId, path, route.getLocation());
- // 如果包含逗号,说明有多个地址,需要负载均衡
- if (route.getLocation().contains(",")) {
- final String[] segs = route.getLocation().split(",");
- // 随机策略
- String loc = segs[r.nextInt(segs.length)];
- // 替换路由地址
- // loc = PlaceholderUtils.replacePlaceholders(loc, globalVariables, Constants.REGEX_VARIABLE);
- // log.info("loc->> " + loc);
- return new Route(route.getId(),
- targetPath,
- loc,
- prefix,
- retryable,
- route.isCustomSensitiveHeaders() ? route.getSensitiveHeaders() : null,
- route.isStripPrefix());
- }
- // 替换路由地址
- // String loc = PlaceholderUtils.replacePlaceholders(route.getLocation(), globalVariables, Constants.REGEX_VARIABLE);
- return new Route(route.getId(),
- targetPath,
- route.getLocation(),
- prefix,
- retryable,
- route.isCustomSensitiveHeaders() ? route.getSensitiveHeaders() : null,
- route.isStripPrefix());
- }
- }
|