ny
昨天 b6f169fe43a2b13f351aefc152374fc7f0bc8cb7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
 * Copyright © 2017-2023 Knife4j(xiaoymin@foxmail.com)
 *
 * 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
 *
 *     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 com.github.xiaoymin.knife4j.spring.gateway.utils;
 
import com.github.xiaoymin.knife4j.spring.gateway.Knife4jGatewayProperties;
import com.github.xiaoymin.knife4j.spring.gateway.conf.GlobalConstants;
import com.github.xiaoymin.knife4j.spring.gateway.enums.GatewayRouterStrategy;
import com.github.xiaoymin.knife4j.spring.gateway.enums.OpenApiVersion;
import com.github.xiaoymin.knife4j.spring.gateway.spec.v2.OpenAPI2Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
 
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.regex.Pattern;
 
/**
 * 在服务发现(Discover)场景下的聚合辅助工具类
 * @author <a href="xiaoymin@foxmail.com">xiaoymin@foxmail.com</a>
 * 2023/7/31 15:05
 * @since knife4j v4.2.0
 */
@Slf4j
public class ServiceUtils {
 
    private final static String LB = "lb://";
 
    /**
     * 根据OpenAPI规范及分组名称不同获取不同的默认地址
     * @param discover 服务发现配置
     * @param contextPath contextPath
     * @param groupName 分组名称
     * @return openapi地址
     * @since v4.3.0
     */
    public static String getOpenAPIURL(Knife4jGatewayProperties.Discover discover, String contextPath, String groupName) {
        OpenApiVersion apiVersion = discover.getVersion();
        StringBuilder urlBuilder = new StringBuilder();
        String _defaultPath = PathUtils.processContextPath(contextPath);
        // String _groupName = StrUtil.defaultTo(groupName, GlobalConstants.DEFAULT_GROUP_NAME);
        String _groupName = "";
        String groupUrl = "";
        if (apiVersion == OpenApiVersion.Swagger2) {
            groupUrl = GlobalConstants.DEFAULT_OPEN_API_V2_PATH + _groupName;
        } else if (apiVersion == OpenApiVersion.OpenAPI3) {
            groupUrl = PathUtils.append(GlobalConstants.DEFAULT_OPEN_API_V3_PATH, _groupName);
        }
        urlBuilder.append(PathUtils.append(_defaultPath, groupUrl));
        return urlBuilder.toString();
    }
 
    /**
     * 判断服务路由是否负载配置
     * @param uri 路由
     * @return True-是,False-非lb
     */
    public static boolean startLoadBalance(URI uri) {
        if (uri == null) {
            return false;
        }
        String path = uri.toString();
        if (path == null || path.isEmpty()) {
            return false;
        }
        return path.startsWith(LB);
    }
 
    /**
     * 判断是否包含服务
     * @param uri 路由服务
     * @param service 服务列表
     * @param excludeService 已排除服务列表
     * @return  True-是,False-非
     */
    public static boolean includeService(URI uri, Collection<String> service, Collection<String> excludeService) {
        String serviceName = uri.getHost();
        // DUBBO服务无法解析
        if(serviceName == null){
            serviceName = uri.getAuthority();
        }
        if(serviceName == null){
            serviceName = uri.toString();
        }
        return service.stream().anyMatch(serviceName::equalsIgnoreCase) && !excludeServices(serviceName, excludeService);
    }
 
    /**
     * 判断当前服务是否在排除服务列表中
     * @param serviceName 服务名称
     * @param excludeService 排除服务规则列表,支持正则表达式(4.3.0版本)
     * @return True-在排除服务列表中,False-不满足规则
     * @since v4.3.0
     */
    public static boolean excludeServices(String serviceName, Collection<String> excludeService) {
        if (CollectionUtils.isEmpty(excludeService)) {
            return false;
        }
        for (String es : excludeService) {
            // 首先根据服务名称直接判断一次
            if (es.equalsIgnoreCase(serviceName)) {
                return true;
            }
            // 增加正则表达式判断
            if (Pattern.compile(es, Pattern.CASE_INSENSITIVE).matcher(serviceName).matches()) {
                return true;
            }
        }
        return false;
    }
}