forked from php-danfu.shenzhenbenwo.com

lefengyang
2025-09-10 3c9dcaf742cfa3e3c2b0843c8752cf7713aaf1fc
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
/**
 * Alipay.com Inc. Copyright (c) 2004-2019 All Rights Reserved.
 */
package com.alipay.easysdk.kms.aliyun;
 
import com.alipay.easysdk.kms.aliyun.models.RuntimeOptions;
import com.aliyun.tea.*;
import com.aliyun.tea.utils.StringUtils;
import com.google.gson.Gson;
import org.bouncycastle.util.encoders.Base64;
 
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
 
public class AliyunRpcClient {
    private final String accessKeyId;
    private final String accessKeySecret;
    private final String endpoint;
    private final String format;
    private final String signatureMethod;
    private final String signatureVersion;
 
    public AliyunRpcClient(Map<String, Object> config) {
        this.accessKeyId = (String) config.get("aliyunAccessKeyId");
        this.accessKeySecret = (String) config.get("aliyunAccessKeySecret");
        this.endpoint = (String) config.get("kmsEndpoint");
        this.format = "JSON";
        this.signatureMethod = "HMAC-SHA1";
        this.signatureVersion = "1.0";
    }
 
    public Map<String, Object> doRequest(String action, String protocol, String method, String version, Map<String, Object> query, Map<String, Object> body, RuntimeOptions runtime) throws Exception {
        Map<String, Object> runtime_ = TeaConverter.buildMap(
                new TeaPair("readTimeout", runtime.readTimeout),
                new TeaPair("connectTimeout", runtime.connectTimeout),
                new TeaPair("retry", TeaConverter.buildMap(
                        new TeaPair("maxAttempts", runtime.maxAttempts)
                )),
                new TeaPair("backoff", TeaConverter.buildMap(
                        new TeaPair("policy", runtime.backoffPolicy),
                        new TeaPair("period", runtime.backoffPeriod)
                )),
                new TeaPair("ignoreSSL", runtime.ignoreSSL)
        );
 
        TeaRequest _lastRequest = null;
        long _now = System.currentTimeMillis();
        int _retryTimes = 0;
        while (Tea.allowRetry((Map<String, Object>) runtime_.get("retry"), _retryTimes, _now)) {
            if (_retryTimes > 0) {
                int backoffTime = Tea.getBackoffTime(runtime_.get("backoff"), _retryTimes);
                if (backoffTime > 0) {
                    Tea.sleep(backoffTime);
                }
            }
            _retryTimes = _retryTimes + 1;
            try {
                TeaRequest request_ = new TeaRequest();
                request_.protocol = protocol;
                request_.method = method;
                request_.pathname = "/";
                request_.query = TeaConverter.merge(String.class,
                        TeaConverter.buildMap(
                                new TeaPair("Action", action),
                                new TeaPair("Format", this.format),
                                new TeaPair("Timestamp", getTimestamp()),
                                new TeaPair("Version", version),
                                new TeaPair("SignatureNonce", getNonce())
                        ),
                        query
                );
                request_.headers = TeaConverter.buildMap(
                        new TeaPair("host", this.endpoint)
                );
                if (!isUnset(body)) {
                    Map<String, Object> tmp = anyifyMapValue(body);
                    request_.body = Tea.toReadable(toFormString(tmp));
                    request_.headers.put("content-type", "application/x-www-form-urlencoded");
                }
 
                request_.query.put("SignatureMethod", this.signatureMethod);
                request_.query.put("SignatureVersion", this.signatureVersion);
                request_.query.put("AccessKeyId", this.accessKeyId);
                Map<String, String> signedParam = TeaConverter.merge(String.class,
                        request_.query,
                        body
                );
                request_.query.put("Signature", getSignature(signedParam, request_.method, this.accessKeySecret));
 
 
                _lastRequest = request_;
                TeaResponse response_ = Tea.doAction(request_, runtime_);
 
                Object obj = readAsJSON(response_.body);
                Map<String, Object> res = assertAsMap(obj);
                if (is4xx(response_.statusCode) || is5xx(response_.statusCode)) {
                    throw new TeaException(TeaConverter.buildMap(
                            new TeaPair("message", res.get("Message")),
                            new TeaPair("data", res),
                            new TeaPair("code", res.get("Code"))
                    ));
                }
 
                return res;
            } catch (Exception e) {
                if (Tea.isRetryable(e)) {
                    continue;
                }
                throw e;
            }
        }
 
        throw new TeaUnretryableException(_lastRequest);
    }
 
    public static String percentEncode(String value) throws UnsupportedEncodingException {
        return value != null ? URLEncoder.encode(value, "UTF-8").replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;
    }
 
    private static String getSignature(Map<String, String> signedParams, String method, String secret) throws Exception {
        String[] sortedKeys = signedParams.keySet().toArray(new String[0]);
        Arrays.sort(sortedKeys);
        StringBuilder canonicalizedQueryString = new StringBuilder();
 
        for (String key : sortedKeys) {
            if (!StringUtils.isEmpty(signedParams.get(key))) {
                canonicalizedQueryString.append("&").append(percentEncode(key)).append("=").append(percentEncode((String) signedParams.get(key)));
            }
        }
 
        Mac mac = Mac.getInstance("HmacSHA1");
        mac.init(new SecretKeySpec((secret + "&").getBytes(StandardCharsets.UTF_8), "HmacSHA1"));
        String stringToSign = method +
                "&" +
                percentEncode("/") +
                "&" +
                percentEncode(canonicalizedQueryString.toString().substring(1));
        byte[] signData = mac.doFinal(stringToSign.getBytes(StandardCharsets.UTF_8));
        return Base64.toBase64String(signData);
    }
 
    public static Object parseJSON(String json) {
        return (new Gson()).fromJson(json, Map.class);
    }
 
    public static Map<String, Object> assertAsMap(Object object) {
        if (null != object && Map.class.isAssignableFrom(object.getClass())) {
            return (Map) object;
        } else {
            throw new RuntimeException("The value is not a object");
        }
    }
 
    public static byte[] readAsBytes(InputStream stream) throws IOException {
        if (null == stream) {
            return new byte[0];
        } else {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            byte[] buff = new byte[1024];
 
            while (true) {
                int read = stream.read(buff);
                if (read == -1) {
                    return os.toByteArray();
                }
 
                os.write(buff, 0, read);
            }
        }
    }
 
    public static String readAsString(InputStream stream) throws IOException {
        return new String(readAsBytes(stream), StandardCharsets.UTF_8);
    }
 
    public static Object readAsJSON(InputStream stream) throws IOException {
        String body = readAsString(stream);
        return parseJSON(body);
    }
 
    public static String getTimestamp() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        df.setTimeZone(new SimpleTimeZone(0, "UTC"));
        return df.format(new Date());
    }
 
    public static String getNonce() {
        StringBuilder uniqueNonce = new StringBuilder();
        UUID uuid = UUID.randomUUID();
        uniqueNonce.append(uuid.toString());
        uniqueNonce.append(System.currentTimeMillis());
        uniqueNonce.append(Thread.currentThread().getId());
        return uniqueNonce.toString();
    }
 
    public static String toFormString(Map<String, ?> map) throws UnsupportedEncodingException {
        if (null == map) {
            return "";
        }
        StringBuilder result = new StringBuilder();
        boolean first = true;
        for (Map.Entry<String, ?> entry : map.entrySet()) {
            if (StringUtils.isEmpty(entry.getValue())) {
                continue;
            }
            if (first) {
                first = false;
            } else {
                result.append("&");
            }
            result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
            result.append("=");
            result.append(URLEncoder.encode(String.valueOf(entry.getValue()), "UTF-8"));
        }
        return result.toString();
    }
 
    public static void validateModel(TeaModel m) throws Exception {
        if (null == m) {
            throw new ValidateException("parameter is not allowed as null");
        } else {
            m.validate();
        }
    }
 
    public static Map<String, Object> anyifyMapValue(Map<String, ?> map) {
        Map<String, Object> result = new HashMap<>();
        if (null == map) {
            return null;
        }
        for (Map.Entry<String, ?> entry : map.entrySet()) {
            result.put(entry.getKey(), entry.getValue());
        }
        return result;
    }
 
    public static boolean is4xx(Number code) {
        if (null == code) {
            return false;
        } else {
            return code.intValue() >= 400 && code.intValue() < 500;
        }
    }
 
    public static boolean is5xx(Number code) {
        if (null == code) {
            return false;
        } else {
            return code.intValue() >= 500 && code.intValue() < 600;
        }
    }
 
    public static boolean isUnset(Object object) {
        return null == object;
    }
}