Skip to content

add endpoint resolver #551

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions src/main/java/com/aliyun/oss/ClientConfiguration.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.common.utils.ResourceManager;
import com.aliyun.oss.common.utils.VersionInfoUtils;
import com.aliyun.oss.endpoint.DefaultEndpointResolver;
import com.aliyun.oss.endpoint.EndpointResolver;
import com.aliyun.oss.internal.OSSConstants;

/**
Expand Down Expand Up @@ -127,6 +129,10 @@ public class ClientConfiguration {

private boolean tracerEnabled = false;

private boolean isRefreshEndpointAddr = false;

private EndpointResolver endpointResolver = new DefaultEndpointResolver();

public ClientConfiguration() {
super();
AppendDefaultExcludeList(this.cnameExcludeList);
Expand Down Expand Up @@ -991,4 +997,41 @@ public boolean isTracerEnabled() {
public void setTracerEnabled(boolean enabled) {
this.tracerEnabled = enabled;
}

/**
* Gets the flag of refresh endpoint.
*
* @return True if it's enabled; False if it's disabled.
*/
public boolean isRefreshEndpointAddr() {
return isRefreshEndpointAddr;
}

/**
* Sets the flag of refresh endpoint.
*
* @param refreshEndpointAddr True if it's enabled; False if it's disabled.
*/
public void setRefreshEndpointAddr(boolean refreshEndpointAddr) {
isRefreshEndpointAddr = refreshEndpointAddr;
}

/**
* Gets the endpoint resolver.
*
* @return endpoint resolver.
*/
public EndpointResolver getEndpointResolver() {
return endpointResolver;
}

/**
* Sets the endpoint resolver.
*
* @param endpointResolver
*/
public void setEndpointResolver(EndpointResolver endpointResolver) {
this.endpointResolver = endpointResolver;
}

}
18 changes: 18 additions & 0 deletions src/main/java/com/aliyun/oss/common/comm/ServiceClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.util.List;

import com.aliyun.oss.internal.OSSUtils;
import org.apache.http.HttpMessage;

import com.aliyun.oss.ClientConfiguration;
Expand Down Expand Up @@ -120,6 +122,9 @@ private ResponseMessage sendRequestImpl(RequestMessage request, ExecutionContext
while (true) {
try {
if (retries > 0) {
if (config.isRefreshEndpointAddr()) {
refreshEndpointAddr(request);
}
pause(retries, retryStrategy);
if (requestContent != null && requestContent.markSupported()) {
try {
Expand Down Expand Up @@ -392,4 +397,17 @@ public void setUseChunkEncoding(boolean useChunkEncoding) {
this.useChunkEncoding = useChunkEncoding;
}
}

public void refreshEndpointAddr(RequestMessage request)
throws ServiceException, ClientException {
String endpoint = "";
if (config.isSupportCname()){
endpoint = config.getEndpointResolver().resolveGetServiceApiEndpoint(request.getEndpoint().toString());
} else {
endpoint = config.getEndpointResolver().resolveGeneralApiEndpoint(request.getEndpoint().toString());
}
String defaultProto = config.getProtocol().toString();
URI uri = OSSUtils.toEndpointURI(endpoint, defaultProto);
request.setEndpoint(uri);
}
}
19 changes: 19 additions & 0 deletions src/main/java/com/aliyun/oss/endpoint/DefaultEndpointResolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

package com.aliyun.oss.endpoint;

/**
* default endpoint resolver, just return the api endpoint
* the dns resolve will be implemented by http library.
*/
public class DefaultEndpointResolver implements EndpointResolver {

@Override
public String resolveGeneralApiEndpoint(String generalApiEndpoint) {
return generalApiEndpoint;
}

@Override
public String resolveGetServiceApiEndpoint(String getServiceApiEndpoint) {
return getServiceApiEndpoint;
}
}
26 changes: 26 additions & 0 deletions src/main/java/com/aliyun/oss/endpoint/EndpointResolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.aliyun.oss.endpoint;

/**
* resolve the endpoint like dns.
*
*/

public interface EndpointResolver {
/**
* return the general api endpoint, the result can be ip or ip:port. if you don't do
* anything like DefaultEndpointResolver. the http library will implement the dns resolve.
*
* @param generalApiEndpoint
* @return the endpoint addr
*/
public String resolveGeneralApiEndpoint(String generalApiEndpoint);

/**
* return the get service api endpoint, the result can be ip or ip:port. if you don't do
* anything like DefaultEndpointResolver. the http library will implement the dns resolve.
*
* @param getServiceApiEndpoint
* @return the endpoint
*/
public String resolveGetServiceApiEndpoint(String getServiceApiEndpoint);
}
8 changes: 8 additions & 0 deletions src/main/java/com/aliyun/oss/internal/OSSOperation.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ public URI getEndpoint() {

public URI getEndpoint(WebServiceRequest request) {
String reqEndpoint = request.getEndpoint();
if (client.getClientConfiguration().isRefreshEndpointAddr()) {
if (client.getClientConfiguration().isSupportCname()){
reqEndpoint = client.getClientConfiguration().getEndpointResolver().resolveGetServiceApiEndpoint(reqEndpoint);
} else {
reqEndpoint = client.getClientConfiguration().getEndpointResolver().resolveGeneralApiEndpoint(reqEndpoint);
}
}

if (reqEndpoint == null) {
return getEndpoint();

Expand Down
101 changes: 101 additions & 0 deletions src/test/java/com/aliyun/oss/common/comm/EndpointRefreshTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package com.aliyun.oss.common.comm;

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.Credentials;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.auth.DefaultCredentials;
import com.aliyun.oss.endpoint.EndpointResolver;
import com.aliyun.oss.integrationtests.TestBase;
import com.aliyun.oss.integrationtests.TestConfig;
import junit.framework.Assert;
import org.junit.Test;

public class EndpointRefreshTest extends TestBase {

@Test
public void testEndpointRefresh() {
class CustomEndpointResolver implements EndpointResolver {
private String endpoint = null;

public String getEndpoint() {
return endpoint;
}

public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}

@Override
public String resolveGeneralApiEndpoint(String generalApiEndpoint) {
return this.endpoint;
}

@Override
public String resolveGetServiceApiEndpoint(String getServiceApiEndpoint) {
return this.endpoint;
}
}

ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
Credentials credentials = new DefaultCredentials(TestConfig.OSS_TEST_ACCESS_KEY_ID, TestConfig.OSS_TEST_ACCESS_KEY_SECRET);
OSS client = new OSSClient(TestConfig.OSS_TEST_ENDPOINT, new DefaultCredentialProvider(credentials), conf);
Assert.assertEquals(TestConfig.OSS_TEST_ENDPOINT, ((OSSClient) client).getEndpoint().toString());

CustomEndpointResolver customEndpointResolver = new CustomEndpointResolver();

// Custom Domain
customEndpointResolver.setEndpoint("www.abbbc.com");
conf.setSupportCname(true);
conf.setRefreshEndpointAddr(true);
conf.setEndpointResolver(customEndpointResolver);

try {
client.getObject("bucket","object");
System.out.println("ok");
} catch (ClientException e) {
Assert.assertEquals("www.abbbc.com\n" +
"[ErrorCode]: UnknownHost\n" +
"[RequestId]: Unknown", e.getMessage());
}

// ip
customEndpointResolver.setEndpoint("127.0.0.1");
conf.setSupportCname(true);
conf.setEndpointResolver(customEndpointResolver);

try {
client.getObject("bucket","object");
System.out.println("ok");
} catch (ClientException e) {
Assert.assertEquals("Connect to 127.0.0.1:80 [/127.0.0.1] failed: Connection refused: connect\n" +
"[ErrorCode]: SocketException\n" +
"[RequestId]: Unknown", e.getMessage());
}

// ip:port
customEndpointResolver.setEndpoint("127.0.0.1:8080");
conf.setSupportCname(true);
conf.setEndpointResolver(customEndpointResolver);

try {
client.getObject("bucket","object");
System.out.println("ok");
} catch (ClientException e) {
Assert.assertEquals("Connect to 127.0.0.1:8080 [/127.0.0.1] failed: Connection refused: connect\n" +
"[ErrorCode]: SocketException\n" +
"[RequestId]: Unknown", e.getMessage());
}

// bucket.Domain
conf.setSupportCname(false);
customEndpointResolver.setEndpoint("aaa.aliyuncs.com");
conf.setEndpointResolver(customEndpointResolver);
try {
client.getObject("bucket","object");
} catch (ClientException e) {
Assert.assertEquals("aaa.aliyuncs.com\n" +
"[ErrorCode]: UnknownHost\n" +
"[RequestId]: Unknown", e.getMessage());
}
}
}
15 changes: 15 additions & 0 deletions src/test/java/com/aliyun/oss/common/comm/OSSClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import com.aliyun.oss.common.auth.Credentials;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.endpoint.DefaultEndpointResolver;
import com.aliyun.oss.endpoint.EndpointResolver;
import com.aliyun.oss.internal.OSSConstants;
import com.aliyun.oss.internal.RequestParameters;
import com.aliyun.oss.model.GetObjectRequest;
Expand Down Expand Up @@ -482,5 +484,18 @@ public void testExtractSettingFromEndpoint() {
Assert.assertEquals("region", clientImpl.getObjectOperation().getRegion());
Assert.assertEquals("oss-cloudbox", clientImpl.getObjectOperation().getProduct());
}

@Test
public void testConfigurationWithEndpointResolver() {
ClientConfiguration clientConfiguration = new ClientConfiguration();

clientConfiguration.setRefreshEndpointAddr(true);
Assert.assertEquals(true, clientConfiguration.isRefreshEndpointAddr());

DefaultEndpointResolver defaultEndpointResolver = new DefaultEndpointResolver();
clientConfiguration.setEndpointResolver(defaultEndpointResolver);
Assert.assertEquals(defaultEndpointResolver, clientConfiguration.getEndpointResolver());
}

}