Skip to content

Commit 8e478a5

Browse files
chore:add rds connect
1 parent 2941c6e commit 8e478a5

File tree

4 files changed

+119
-145
lines changed

4 files changed

+119
-145
lines changed

volcengine-java-sdk-core/src/main/java/com/volcengine/endpoint/DefaultEndpointProvider.java

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -836,23 +836,6 @@ private static boolean hasEnabledDualstack(Boolean useDualStack) {
836836
return useDualStack;
837837
}
838838

839-
/**
840-
* Build a regional endpoint for the given service and region.
841-
* <p>
842-
* Format: {standardized_service}.{region}.volcengineapi.com
843-
* e.g., rds_mysql -> rds-mysql.cn-beijing.volcengineapi.com
844-
* <p>
845-
* Supports dual-stack via VOLC_ENABLE_DUALSTACK=true env var.
846-
*
847-
* @param service Service code (e.g., "rds_mysql")
848-
* @param region Region code (e.g., "cn-beijing")
849-
* @return Regional endpoint string (without scheme)
850-
*/
851-
public static String getRegionalEndpoint(String service, String region) {
852-
String endpointSuffix = hasEnabledDualstack(null) ? DUALSTACK_ENDPOINT_SUFFIX : ENDPOINT_SUFFIX;
853-
return standardizeDomainServiceCode(service) + SEPARATOR + region + endpointSuffix;
854-
}
855-
856839
@Override
857840
public ResolvedEndpoint endpointFor(ResolveEndpointOption option) {
858841
String endpoint = DefaultEndpointProvider.getDefaultEndpointByServiceInfo(option.getService(),
Lines changed: 49 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package com.volcengine.feature.rds.auth;
22

33
import com.volcengine.ApiClient;
4-
import com.volcengine.endpoint.DefaultEndpointProvider;
5-
import com.volcengine.sign.Credentials;
6-
import com.volcengine.sign.VolcstackSign;
4+
import com.volcengine.ApiException;
5+
import com.volcengine.Pair;
6+
import com.volcengine.endpoint.ResolveEndpointOption;
7+
import com.volcengine.endpoint.ResolvedEndpoint;
8+
import com.volcengine.endpoint.StandardEndpointProvider;
9+
import com.volcengine.interceptor.*;
10+
import com.volcengine.sign.ServiceInfo;
711

812
import org.apache.commons.lang.StringUtils;
913

10-
1114
import java.util.*;
1215

1316
/**
@@ -23,78 +26,22 @@ public class ConnectUtils {
2326

2427
/**
2528
* Generate an authorization token for database connection (used as password).
26-
* Extracts credentials, region, and disableSSL from the ApiClient, similar to Go SDK's Config.
29+
* Aligned with Go SDK's BuildAuthToken implementation.
2730
*
28-
* @param apiClient ApiClient containing Credentials, Region, and DisableSSL settings
31+
* @param apiClient ApiClient containing Credentials, Region, DisableSSL, and UseDualStack settings
2932
* @param dbUser Database user account
3033
* @param instanceId Database instance ID
3134
* @param expires Expiration time in seconds, defaults to 900 seconds (15 minutes) if &lt;= 0
3235
* @return Presigned URL string that can be used as the authorization token for database connection
33-
* @throws Exception if parameters are invalid or signing fails
36+
* @throws ApiException if parameters are invalid or signing fails
3437
*/
35-
public static String buildAuthToken(
36-
ApiClient apiClient,
37-
String dbUser,
38-
String instanceId,
39-
int expires
40-
) throws Exception {
38+
public static String buildAuthToken(ApiClient apiClient, String dbUser, String instanceId, int expires) throws ApiException {
39+
// Parameter validation
4140
if (apiClient == null) {
4241
throw new IllegalArgumentException("apiClient must not be null");
4342
}
44-
return buildAuthToken(apiClient.getCredentials(), apiClient.getRegion(),
45-
dbUser, instanceId, expires, apiClient.getDisableSSL());
46-
}
4743

48-
/**
49-
* Generate an authorization token for database connection (used as password).
50-
* Uses HTTPS by default.
51-
*
52-
* @param credentials Credentials containing AccessKey and SecretKey for signing
53-
* @param region Region, e.g., "cn-beijing"
54-
* @param dbUser Database user account
55-
* @param instanceId Database instance ID
56-
* @param expires Expiration time in seconds, defaults to 900 seconds (15 minutes) if &lt;= 0
57-
* @return Presigned URL string that can be used as the authorization token for database connection
58-
* @throws Exception if parameters are invalid or signing fails
59-
*/
60-
public static String buildAuthToken(
61-
Credentials credentials,
62-
String region,
63-
String dbUser,
64-
String instanceId,
65-
int expires
66-
) throws Exception {
67-
return buildAuthToken(credentials, region, dbUser, instanceId, expires, false);
68-
}
69-
70-
/**
71-
* Generate an authorization token for database connection (used as password).
72-
*
73-
* @param credentials Credentials containing AccessKey and SecretKey for signing
74-
* @param region Region, e.g., "cn-beijing"
75-
* @param dbUser Database user account
76-
* @param instanceId Database instance ID
77-
* @param expires Expiration time in seconds, defaults to 900 seconds (15 minutes) if &lt;= 0
78-
* @param disableSSL If true, use http:// scheme; otherwise use https://
79-
* @return Presigned URL string that can be used as the authorization token for database connection
80-
* @throws Exception if parameters are invalid or signing fails
81-
*/
82-
public static String buildAuthToken(
83-
Credentials credentials,
84-
String region,
85-
String dbUser,
86-
String instanceId,
87-
int expires,
88-
boolean disableSSL
89-
) throws Exception {
90-
// Parameter validation
91-
if (credentials == null ||
92-
StringUtils.isEmpty(credentials.getAccessKey()) ||
93-
StringUtils.isEmpty(credentials.getSecretKey())) {
94-
throw new IllegalArgumentException("credentials must not be null and must contain valid access key and secret key");
95-
}
96-
97-
if (StringUtils.isEmpty(region)) {
44+
if (StringUtils.isEmpty(apiClient.getRegion())) {
9845
throw new IllegalArgumentException("region must not be empty");
9946
}
10047

@@ -111,56 +58,41 @@ public static String buildAuthToken(
11158
expires = DEFAULT_EXPIRES_SECONDS;
11259
}
11360

114-
// Build regional endpoint
115-
String endpoint = DefaultEndpointProvider.getRegionalEndpoint(SERVICE_NAME, region);
116-
117-
// Build query parameters
118-
Map<String, String> queryParams = new HashMap<>();
119-
queryParams.put("Action", ACTION);
120-
queryParams.put("Version", VERSION);
121-
queryParams.put("X-Expires", String.valueOf(expires));
122-
queryParams.put("DBUser", dbUser);
123-
queryParams.put("InstanceId", instanceId);
124-
125-
// Create signature object
126-
VolcstackSign sign = new VolcstackSign(credentials);
127-
sign.setRegion(region);
128-
sign.setService(SERVICE_NAME);
129-
sign.setMethod("GET");
130-
131-
// Generate presigned URL with host signing
132-
Map<String, String> presignedParams = sign.presign(queryParams, endpoint);
133-
134-
// Build complete URL
135-
String scheme = disableSSL ? "http" : "https";
136-
return buildUrl(scheme, endpoint, presignedParams);
137-
}
138-
139-
/**
140-
* Build complete URL with scheme, host, and query parameters.
141-
*
142-
* @param scheme URL scheme ("http" or "https")
143-
* @param endpoint Host endpoint (e.g., "rds-mysql.cn-beijing.volcengineapi.com")
144-
* @param presignedParams Presigned query parameters
145-
* @return Complete URL string
146-
*/
147-
private static String buildUrl(String scheme, String endpoint, Map<String, String> presignedParams) {
148-
StringBuilder url = new StringBuilder();
149-
url.append(scheme).append("://").append(endpoint).append("?");
150-
151-
// Sort parameter keys
152-
List<String> keys = new ArrayList<>(presignedParams.keySet());
153-
Collections.sort(keys);
154-
155-
for (int i = 0; i < keys.size(); i++) {
156-
String key = keys.get(i);
157-
String value = presignedParams.get(key);
158-
url.append(key).append("=").append(value);
159-
if (i < keys.size() - 1) {
160-
url.append("&");
161-
}
162-
}
163-
164-
return url.toString();
61+
// Use StandardEndpointProvider to resolve endpoint (handles regionalization + dual-stack)
62+
StandardEndpointProvider endpointProvider = new StandardEndpointProvider();
63+
ResolveEndpointOption option = new ResolveEndpointOption();
64+
option.setService(SERVICE_NAME);
65+
option.setRegion(apiClient.getRegion());
66+
option.setUseDualStack(apiClient.getUseDualStack());
67+
ResolvedEndpoint resolved = endpointProvider.endpointFor(option);
68+
String endpoint = resolved.getEndpoint();
69+
70+
// SSL handling, ResolveEndpointInterceptor dose not support this
71+
String schema = apiClient.getDisableSSL() ? "http" : "https";
72+
73+
// Build InterceptorContext with presigned flag
74+
InterceptorContext context = new InterceptorContext(apiClient.getHttpClient(), null);
75+
context.setApiClient(apiClient);
76+
77+
RequestInterceptorContext reqCtx = context.getRequestContext();
78+
reqCtx.setPresigned(true);
79+
reqCtx.setSchema(schema);
80+
reqCtx.setHost(endpoint);
81+
reqCtx.setMethod("GET");
82+
reqCtx.setServiceInfo(new ServiceInfo(SERVICE_NAME, "GET"));
83+
reqCtx.setHeaderParams(new HashMap<>());
84+
85+
List<Pair> queryParams = new ArrayList<>();
86+
queryParams.add(new Pair("Action", ACTION));
87+
queryParams.add(new Pair("Version", VERSION));
88+
queryParams.add(new Pair("X-Expires", String.valueOf(expires)));
89+
queryParams.add(new Pair("DBUser", dbUser));
90+
queryParams.add(new Pair("InstanceId", instanceId));
91+
reqCtx.setQueryParams(queryParams);
92+
93+
// Execute sign interceptor for presigning
94+
new SignRequestInterceptor().intercept(context);
95+
96+
return reqCtx.getPresignedUrl();
16597
}
16698
}

volcengine-java-sdk-core/src/main/java/com/volcengine/interceptor/RequestInterceptorContext.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ public class RequestInterceptorContext {
2222
private ProgressRequestBody.ProgressRequestListener progressRequestListener;
2323
private boolean isCommon;
2424

25+
private boolean presigned = false;
26+
private String presignedUrl;
27+
2528
private ServiceInfo serviceInfo;
2629
private Request request;
2730

@@ -120,4 +123,20 @@ public Request getRequest() {
120123
public void setRequest(Request request) {
121124
this.request = request;
122125
}
126+
127+
public boolean isPresigned() {
128+
return presigned;
129+
}
130+
131+
public void setPresigned(boolean presigned) {
132+
this.presigned = presigned;
133+
}
134+
135+
public String getPresignedUrl() {
136+
return presignedUrl;
137+
}
138+
139+
public void setPresignedUrl(String presignedUrl) {
140+
this.presignedUrl = presignedUrl;
141+
}
123142
}

volcengine-java-sdk-core/src/main/java/com/volcengine/interceptor/SignRequestInterceptor.java

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
import org.apache.commons.lang.StringUtils;
1515

1616
import java.io.IOException;
17-
import java.util.List;
18-
import java.util.Map;
17+
import java.util.*;
1918

2019
public class SignRequestInterceptor implements RequestInterceptor {
2120

@@ -35,17 +34,8 @@ public InterceptorContext intercept(InterceptorContext context) throws ApiExcept
3534
ServiceInfo serviceInfo = context.getRequestContext().getServiceInfo();
3635
String[] authNames = context.getRequestContext().getAuthNames();
3736
RequestBody reqBody = context.getRequestContext().getRequestBody();
38-
ProgressRequestBody.ProgressRequestListener progressRequestListener = context.getInitInterceptorContext().getProgressRequestListener();
3937

4038
//sign
41-
final Buffer buffer = new Buffer();
42-
try {
43-
if (reqBody != null) {
44-
reqBody.writeTo(buffer);
45-
}
46-
} catch (IOException e) {
47-
throw new ApiException(e);
48-
}
4939
VolcstackSign volcengineSign = new VolcstackSign();
5040
if (context.getApiClient().getCredentials() != null) {
5141
volcengineSign.setCredentials(context.getApiClient().getCredentials());
@@ -74,8 +64,39 @@ public InterceptorContext intercept(InterceptorContext context) throws ApiExcept
7464
if (StringUtils.isEmpty(volcengineSign.getRegion())) {
7565
throw new RuntimeException("Region must set when ApiClient init");
7666
}
67+
68+
// Presigned branch: aligned with Go SDK's `if req.IsPresigned() { signedQuery := c1.SignUrl(...) }`
69+
if (context.getRequestContext().isPresigned()) {
70+
Map<String, String> queryParamsMap = new HashMap<>();
71+
for (Pair p : queryParams) {
72+
queryParamsMap.put(p.getName(), p.getValue());
73+
}
74+
75+
String host = context.getRequestContext().getHost();
76+
try {
77+
Map<String, String> presignedParams = volcengineSign.presign(queryParamsMap, host);
78+
String presignedUrl = buildPresignedUrl(
79+
context.getRequestContext().getSchema(), host, presignedParams);
80+
context.getRequestContext().setPresignedUrl(presignedUrl);
81+
} catch (Exception e) {
82+
throw new ApiException(e);
83+
}
84+
return context;
85+
}
86+
87+
// Normal sign branch: aligned with Go SDK's `r := c1.Sign(req.HTTPRequest); req.HTTPRequest.Header = r.Header`
88+
final Buffer buffer = new Buffer();
89+
try {
90+
if (reqBody != null) {
91+
reqBody.writeTo(buffer);
92+
}
93+
} catch (IOException e) {
94+
throw new ApiException(e);
95+
}
7796
volcengineSign.applyToParams(queryParams, headerParams, buffer.readUtf8());
7897

98+
ProgressRequestBody.ProgressRequestListener progressRequestListener = context.getInitInterceptorContext().getProgressRequestListener();
99+
79100
//build final call
80101
StringBuilder url = new StringBuilder();
81102
url.append(context.getRequestContext().getSchema());
@@ -101,4 +122,23 @@ public InterceptorContext intercept(InterceptorContext context) throws ApiExcept
101122
context.getRequestContext().setRequest(request);
102123
return context;
103124
}
125+
126+
private static String buildPresignedUrl(String scheme, String host, Map<String, String> presignedParams) {
127+
StringBuilder url = new StringBuilder();
128+
url.append(scheme).append("://").append(host).append("?");
129+
130+
List<String> keys = new ArrayList<>(presignedParams.keySet());
131+
Collections.sort(keys);
132+
133+
for (int i = 0; i < keys.size(); i++) {
134+
String key = keys.get(i);
135+
String value = presignedParams.get(key);
136+
url.append(key).append("=").append(value);
137+
if (i < keys.size() - 1) {
138+
url.append("&");
139+
}
140+
}
141+
142+
return url.toString();
143+
}
104144
}

0 commit comments

Comments
 (0)