This is an automated email from the ASF dual-hosted git repository.
youling1128 pushed a commit to branch 2.8.x
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/2.8.x by this push:
new c8b77b334 [#5013] Fixing the issue where microservices cannot be
registered when enabling RBAC authentication in a dual-engine disaster recovery
scenario. (#5014)
c8b77b334 is described below
commit c8b77b334e52c66fba40eee04ea8a7aba14ed2e8
Author: Alex <[email protected]>
AuthorDate: Mon Nov 24 19:08:08 2025 +0800
[#5013] Fixing the issue where microservices cannot be registered when
enabling RBAC authentication in a dual-engine disaster recovery scenario.
(#5014)
---
.../center/client/ConfigCenterAddressManager.java | 5 +-
.../config/center/client/ConfigCenterClient.java | 19 +++-
.../servicecomb/config/kie/client/KieClient.java | 19 +++-
.../config/kie/client/model/KieAddressManager.java | 4 +-
.../kie/client/model/KieAddressManagerTest.java | 4 +-
.../dashboard/client/DashboardAddressManager.java | 4 +-
.../dashboard/client/AddressManagerTest.java | 4 +-
.../http/client/common/AbstractAddressManager.java | 107 +++++++++++++++++++--
.../http/client/common/HttpTransportImpl.java | 15 ++-
.../http/client/event}/OperationEvents.java | 10 +-
.../client/common/AbstractAddressManagerTest.java | 33 ++++++-
.../center/client/ServiceCenterAddressManager.java | 5 +-
.../service/center/client/ServiceCenterClient.java | 35 +------
.../center/client/ServiceCenterOperation.java | 2 +-
.../center/client/ServiceCenterRawClient.java | 48 ++++++---
.../service/center/client/ServiceCenterWatch.java | 15 ++-
.../client/ServiceCenterAddressManagerTest.java | 6 +-
.../center/client/ServiceCenterRawClientTest.java | 3 +-
.../RegistryClientTest.java | 4 +-
demo/docker-build-config/pom.xml | 2 +-
.../servicecomb/config/ConfigCenterConfig.java | 12 +++
.../ConfigCenterConfigurationSourceImpl.java | 13 ++-
.../ConfigCenterConfigurationSourceImplTest.java | 8 +-
.../client/ConfigCenterAddressManagerTest.java | 6 +-
.../apache/servicecomb/config/kie/KieConfig.java | 12 +++
.../config/kie/KieConfigurationSourceImpl.java | 8 +-
.../foundation/auth/AuthHeaderProvider.java | 14 ++-
.../monitor/DefaultMonitorDataPublisher.java | 11 ++-
.../serviceregistry/auth/RBACBootStrapService.java | 4 +-
.../auth/TokenAuthHeaderProvider.java | 4 +-
.../serviceregistry/auth/TokenCacheManager.java | 91 ++++++++----------
.../serviceregistry/client/IpPortManager.java | 15 ++-
.../client/http/EmptyAuthHeaderProvider.java | 2 +-
.../client/http/ServiceRegistryClientImpl.java | 20 ++--
.../config/ServiceRegistryConfig.java | 11 +++
.../config/ServiceRegistryConfigBuilder.java | 8 ++
.../refresh/ServiceRegistryAddressManager.java | 45 ++++++++-
.../client/http/MockAuthHeaderProvider.java | 2 +-
.../refresh/ServiceRegistryAddressManagerTest.java | 8 +-
39 files changed, 463 insertions(+), 175 deletions(-)
diff --git
a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManager.java
b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManager.java
index 3b346153a..62dcb7f8d 100644
---
a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManager.java
+++
b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManager.java
@@ -28,8 +28,9 @@ import com.google.common.eventbus.Subscribe;
public class ConfigCenterAddressManager extends AbstractAddressManager {
- public ConfigCenterAddressManager(String projectName, List<String>
addresses, EventBus eventBus) {
- super(projectName, addresses);
+ public ConfigCenterAddressManager(String projectName, List<String>
addresses, String ownRegion,
+ String ownAvailableZone, EventBus eventBus) {
+ super(projectName, addresses, ownRegion, ownAvailableZone);
eventBus.register(this);
}
diff --git
a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterClient.java
b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterClient.java
index 7763f5ec6..1b6c4e70f 100644
---
a/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterClient.java
+++
b/clients/config-center-client/src/main/java/org/apache/servicecomb/config/center/client/ConfigCenterClient.java
@@ -32,6 +32,7 @@ import org.apache.servicecomb.http.client.common.HttpRequest;
import org.apache.servicecomb.http.client.common.HttpResponse;
import org.apache.servicecomb.http.client.common.HttpTransport;
import org.apache.servicecomb.http.client.common.HttpUtils;
+import
org.apache.servicecomb.http.client.event.OperationEvents.UnAuthorizedOperationEvent;
import
org.apache.servicecomb.http.client.utils.ServiceCombServiceAvailableUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -61,12 +62,15 @@ public class ConfigCenterClient implements
ConfigCenterOperation {
private final Map<String, List<String>> dimensionConfigNames = new
HashMap<>();
+ private EventBus eventBus;
+
public ConfigCenterClient(ConfigCenterAddressManager addressManager,
HttpTransport httpTransport) {
this.addressManager = addressManager;
this.httpTransport = httpTransport;
}
public void setEventBus(EventBus eventBus) {
+ this.eventBus = eventBus;
addressManager.setEventBus(eventBus);
}
@@ -88,6 +92,7 @@ public class ConfigCenterClient implements
ConfigCenterOperation {
HttpRequest.GET);
HttpResponse httpResponse = httpTransport.doRequest(httpRequest);
+ recordAndSendUnAuthorizedEvent(httpResponse, address);
if (httpResponse.getStatusCode() == HttpStatus.SC_OK) {
Map<String, Map<String, Object>> allConfigMap = HttpUtils.deserialize(
httpResponse.getContent(),
@@ -121,21 +126,17 @@ public class ConfigCenterClient implements
ConfigCenterOperation {
}
queryConfigurationsResponse.setConfigurations(configurations);
queryConfigurationsResponse.setChanged(true);
- addressManager.recordSuccessState(address);
return queryConfigurationsResponse;
} else if (httpResponse.getStatusCode() == HttpStatus.SC_NOT_MODIFIED) {
queryConfigurationsResponse.setChanged(false);
- addressManager.recordSuccessState(address);
return queryConfigurationsResponse;
} else if (httpResponse.getStatusCode() ==
HttpStatus.SC_TOO_MANY_REQUESTS) {
LOGGER.warn("rate limited, keep the local dimension [{}] configs
unchanged.", dimensionsInfo);
queryConfigurationsResponse.setChanged(false);
- addressManager.recordSuccessState(address);
return queryConfigurationsResponse;
} else if (httpResponse.getStatusCode() == HttpStatus.SC_BAD_REQUEST) {
throw new OperationException("Bad request for query configurations.");
} else {
- addressManager.recordFailState(address);
throw new OperationException(
"read response failed. status:"
+ httpResponse.getStatusCode()
@@ -151,6 +152,16 @@ public class ConfigCenterClient implements
ConfigCenterOperation {
}
}
+ private void recordAndSendUnAuthorizedEvent(HttpResponse response, String
address) {
+ if (this.eventBus != null && response.getStatusCode() ==
HttpStatus.SC_UNAUTHORIZED) {
+ LOGGER.warn("query configuration unauthorized from server [{}], message
[{}]", address, response.getMessage());
+ addressManager.recordFailState(address);
+ this.eventBus.post(new UnAuthorizedOperationEvent(address));
+ } else {
+ addressManager.recordSuccessState(address);
+ }
+ }
+
/**
* Only the name of the new configuration item is printed.
* No log is printed when the configuration content is updated.
diff --git
a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java
index 7d6cd6548..175baadfb 100644
---
a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java
+++
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/KieClient.java
@@ -46,6 +46,7 @@ import org.apache.servicecomb.http.client.common.HttpRequest;
import org.apache.servicecomb.http.client.common.HttpResponse;
import org.apache.servicecomb.http.client.common.HttpTransport;
import org.apache.servicecomb.http.client.common.HttpUtils;
+import
org.apache.servicecomb.http.client.event.OperationEvents.UnAuthorizedOperationEvent;
import
org.apache.servicecomb.http.client.utils.ServiceCombServiceAvailableUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -71,6 +72,8 @@ public class KieClient implements KieConfigOperation {
private final Map<String, List<String>> dimensionConfigNames = new
HashMap<>();
+ private EventBus eventBus;
+
public KieClient(KieAddressManager addressManager, HttpTransport
httpTransport, KieConfiguration kieConfiguration) {
this.httpTransport = httpTransport;
this.addressManager = addressManager;
@@ -78,6 +81,7 @@ public class KieClient implements KieConfigOperation {
}
public void setEventBus(EventBus eventBus) {
+ this.eventBus = eventBus;
addressManager.setEventBus(eventBus);
}
@@ -91,6 +95,7 @@ public class KieClient implements KieConfigOperation {
HttpRequest httpRequest = new HttpRequest(url, null, null,
HttpRequest.GET);
HttpResponse httpResponse = httpTransport.doRequest(httpRequest);
+ recordAndSendUnAuthorizedEvent(httpResponse, address);
ConfigurationsResponse configurationsResponse = new
ConfigurationsResponse();
if (httpResponse.getStatusCode() == HttpStatus.SC_OK) {
revision = httpResponse.getHeader("X-Kie-Revision");
@@ -100,7 +105,6 @@ public class KieClient implements KieConfigOperation {
configurationsResponse.setConfigurations(configurations);
configurationsResponse.setChanged(true);
configurationsResponse.setRevision(revision);
- addressManager.recordSuccessState(address);
return configurationsResponse;
}
if (httpResponse.getStatusCode() == HttpStatus.SC_BAD_REQUEST) {
@@ -108,16 +112,13 @@ public class KieClient implements KieConfigOperation {
}
if (httpResponse.getStatusCode() == HttpStatus.SC_NOT_MODIFIED) {
configurationsResponse.setChanged(false);
- addressManager.recordSuccessState(address);
return configurationsResponse;
}
if (httpResponse.getStatusCode() == HttpStatus.SC_TOO_MANY_REQUESTS) {
LOGGER.warn("rate limited, keep the local dimension [{}] configs
unchanged.", request.getLabelsQuery());
configurationsResponse.setChanged(false);
- addressManager.recordSuccessState(address);
return configurationsResponse;
}
- addressManager.recordFailState(address);
throw new OperationException(
"read response failed. status:" + httpResponse.getStatusCode() + ";
message:" +
httpResponse.getMessage() + "; content:" +
httpResponse.getContent());
@@ -128,6 +129,16 @@ public class KieClient implements KieConfigOperation {
}
}
+ private void recordAndSendUnAuthorizedEvent(HttpResponse response, String
address) {
+ if (this.eventBus != null && response.getStatusCode() ==
HttpStatus.SC_UNAUTHORIZED) {
+ LOGGER.warn("query configuration unauthorized from server [{}], message
[{}]", address, response.getMessage());
+ addressManager.recordFailState(address);
+ this.eventBus.post(new UnAuthorizedOperationEvent(address));
+ } else {
+ addressManager.recordSuccessState(address);
+ }
+ }
+
/**
* Only the name of the new configuration item is printed.
* No log is printed when the configuration content is updated.
diff --git
a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieAddressManager.java
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieAddressManager.java
index 0742c11fb..d8b6582d8 100644
---
a/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieAddressManager.java
+++
b/clients/config-kie-client/src/main/java/org/apache/servicecomb/config/kie/client/model/KieAddressManager.java
@@ -27,8 +27,8 @@ import com.google.common.eventbus.Subscribe;
public class KieAddressManager extends AbstractAddressManager {
- public KieAddressManager(List<String> addresses, EventBus eventBus) {
- super(addresses);
+ public KieAddressManager(List<String> addresses, String ownRegion, String
ownAvailableZone, EventBus eventBus) {
+ super(addresses, ownRegion, ownAvailableZone);
eventBus.register(this);
}
diff --git
a/clients/config-kie-client/src/test/java/org/apache/servicecomb/config/kie/client/model/KieAddressManagerTest.java
b/clients/config-kie-client/src/test/java/org/apache/servicecomb/config/kie/client/model/KieAddressManagerTest.java
index 6533fc60e..4fd547a2c 100644
---
a/clients/config-kie-client/src/test/java/org/apache/servicecomb/config/kie/client/model/KieAddressManagerTest.java
+++
b/clients/config-kie-client/src/test/java/org/apache/servicecomb/config/kie/client/model/KieAddressManagerTest.java
@@ -40,7 +40,7 @@ class KieAddressManagerTest {
public void kieAddressManagerTest() throws NoSuchFieldException,
IllegalAccessException {
addresses.add("http://127.0.0.1:30103");
addresses.add("https://127.0.0.2:30103");
- addressManager1 = new KieAddressManager(addresses, new EventBus());
+ addressManager1 = new KieAddressManager(addresses, "", "", new EventBus());
Field addressManagerField =
addressManager1.getClass().getSuperclass().getDeclaredField("index");
addressManagerField.setAccessible(true);
addressManagerField.set(addressManager1, 0);
@@ -64,7 +64,7 @@ class KieAddressManagerTest {
Map<String, List<String>> zoneAndRegion = new HashMap<>();
zoneAndRegion.put("sameZone", addressAZ);
zoneAndRegion.put("sameRegion", addressRG);
- addressManager1 = new KieAddressManager(addresses, new EventBus());
+ addressManager1 = new KieAddressManager(addresses, "", "", new EventBus());
RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion,
"KIE");
addressManager1.refreshEndpoint(event, "KIE");
diff --git
a/clients/dashboard-client/src/main/java/org/apache/servicecomb/dashboard/client/DashboardAddressManager.java
b/clients/dashboard-client/src/main/java/org/apache/servicecomb/dashboard/client/DashboardAddressManager.java
index 9dd8c6a34..e80c537bc 100644
---
a/clients/dashboard-client/src/main/java/org/apache/servicecomb/dashboard/client/DashboardAddressManager.java
+++
b/clients/dashboard-client/src/main/java/org/apache/servicecomb/dashboard/client/DashboardAddressManager.java
@@ -29,8 +29,8 @@ import com.google.common.eventbus.Subscribe;
public class DashboardAddressManager extends AbstractAddressManager {
- public DashboardAddressManager(List<String> addresses, EventBus eventBus) {
- super(addresses);
+ public DashboardAddressManager(List<String> addresses, String ownRegion,
String ownAvailableZone, EventBus eventBus) {
+ super(addresses, ownRegion, ownAvailableZone);
eventBus.register(this);
}
diff --git
a/clients/dashboard-client/src/test/java/org/apache/servicecomb/dashboard/client/AddressManagerTest.java
b/clients/dashboard-client/src/test/java/org/apache/servicecomb/dashboard/client/AddressManagerTest.java
index ac0c08b3e..448f2d717 100644
---
a/clients/dashboard-client/src/test/java/org/apache/servicecomb/dashboard/client/AddressManagerTest.java
+++
b/clients/dashboard-client/src/test/java/org/apache/servicecomb/dashboard/client/AddressManagerTest.java
@@ -41,7 +41,7 @@ class AddressManagerTest {
public void kieAddressManagerTest() throws IllegalAccessException,
NoSuchFieldException {
addresses.add("http://127.0.0.1:30103");
addresses.add("https://127.0.0.2:30103");
- addressManager1 = new DashboardAddressManager(addresses, new EventBus());
+ addressManager1 = new DashboardAddressManager(addresses, "", "", new
EventBus());
Field addressManagerField =
addressManager1.getClass().getSuperclass().getDeclaredField("index");
addressManagerField.setAccessible(true);
addressManagerField.set(addressManager1, 0);
@@ -65,7 +65,7 @@ class AddressManagerTest {
Map<String, List<String>> zoneAndRegion = new HashMap<>();
zoneAndRegion.put("sameZone", addressAZ);
zoneAndRegion.put("sameRegion", addressRG);
- addressManager1 = new DashboardAddressManager(addresses, new EventBus());
+ addressManager1 = new DashboardAddressManager(addresses, "", "", new
EventBus());
RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion,
"CseMonitoring");
addressManager1.refreshEndpoint(event, "CseMonitoring");
diff --git
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/AbstractAddressManager.java
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/AbstractAddressManager.java
index 7493aff4e..508b523a0 100644
---
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/AbstractAddressManager.java
+++
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/AbstractAddressManager.java
@@ -17,18 +17,21 @@
package org.apache.servicecomb.http.client.common;
+import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
+import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import org.apache.servicecomb.http.client.event.EngineConnectChangedEvent;
import org.apache.servicecomb.http.client.event.RefreshEndpointEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.util.CollectionUtils;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.eventbus.EventBus;
@@ -42,6 +45,10 @@ public class AbstractAddressManager {
private static final String V3_PREFIX = "/v3/";
+ private static final String ZONE = "availableZone";
+
+ private static final String REGION = "region";
+
private static final int ISOLATION_THRESHOLD = 3;
private volatile List<String> addresses = new ArrayList<>();
@@ -74,17 +81,58 @@ public class AbstractAddressManager {
private EventBus eventBus;
- public AbstractAddressManager(List<String> addresses) {
+ public AbstractAddressManager(List<String> addresses, String ownRegion,
String ownAvailableZone) {
this.projectName = DEFAULT_PROJECT;
- this.addresses.addAll(addresses);
- this.defaultAddress.addAll(addresses);
+ parseAndInitAddresses(addresses, ownRegion, ownAvailableZone, false);
this.index = !addresses.isEmpty() ? getRandomIndex() : 0;
}
- public AbstractAddressManager(String projectName, List<String> addresses) {
+ /**
+ * address support config with region/availableZone info, to enable engine
affinity calls during startup
+ * address may be like:
+ * https://192.168.20.13:30110?region=region1&availableZone=az
+ * https://192.168.20.13:30100?region=region1&availableZone=az
+ * When address have no datacenter information, roundRobin using address
+ *
+ * @param addresses engine addresses
+ * @param ownRegion microservice region
+ * @param ownAvailableZone microservice zone
+ * @param isFormat is need format
+ */
+ private void parseAndInitAddresses(List<String> addresses, String ownRegion,
String ownAvailableZone,
+ boolean isFormat) {
+ if (CollectionUtils.isEmpty(addresses)) {
+ return;
+ }
+ List<String> tempList = new ArrayList<>();
+ addressAutoRefreshed = addresses.stream().anyMatch(addr ->
addr.contains(ZONE) || addr.contains(REGION));
+ for (String address : addresses) {
+ // Compatible IpPortManager init address is 127.0.0.1:30100
+ if (!address.startsWith("http")) {
+ tempList.add(address);
+ continue;
+ }
+ URLEndPoint endpoint = new URLEndPoint(address);
+ tempList.add(endpoint.toString());
+ buildAffinityAddress(endpoint, ownRegion, ownAvailableZone);
+ }
+ this.addresses.addAll(isFormat ? this.transformAddress(tempList) :
tempList);
+ this.defaultAddress.addAll(isFormat ? this.transformAddress(tempList) :
tempList);
+ }
+
+ private void buildAffinityAddress(URLEndPoint endpoint, String ownRegion,
String ownAvailableZone) {
+ if (addressAutoRefreshed) {
+ if (regionAndAZMatch(ownRegion, ownAvailableZone,
endpoint.getFirst(REGION), endpoint.getFirst(ZONE))) {
+ availableZone.add(endpoint.toString());
+ } else {
+ availableRegion.add(endpoint.toString());
+ }
+ }
+ }
+
+ public AbstractAddressManager(String projectName, List<String> addresses,
String ownRegion, String ownAvailableZone) {
this.projectName = StringUtils.isEmpty(projectName) ? DEFAULT_PROJECT :
projectName;
- this.addresses = this.transformAddress(addresses);
- this.defaultAddress.addAll(addresses);
+ parseAndInitAddresses(addresses, ownRegion, ownAvailableZone, true);
this.index = !addresses.isEmpty() ? getRandomIndex() : 0;
}
@@ -170,8 +218,9 @@ public class AbstractAddressManager {
return getCurrentAddress(zoneOrRegionAddress);
}
LOGGER.warn("all auto discovery addresses are isolation, please check
server status.");
+
// when all available address are isolation, it will use config addresses
for polling.
- return getCurrentAddress(addresses);
+ return getDefaultAddress();
}
private String getCurrentAddress(List<String> addresses) {
@@ -221,6 +270,11 @@ public class AbstractAddressManager {
addressFailureStatus.put(address, 0);
}
+ /**
+ * Only authentication failure, IO, and timeout exception record as failed.
+ *
+ * @param address request address
+ */
public void recordFailState(String address) {
synchronized (lock) {
if (!addressFailureStatus.containsKey(address)) {
@@ -271,4 +325,41 @@ public class AbstractAddressManager {
isolationAddresses.addAll(isolationRegionAddress);
return isolationAddresses;
}
+
+ public String compareAndGetAddress(String host) {
+ for (String address : defaultAddress) {
+ if (isAddressHostSame(address, host)) {
+ return address;
+ }
+ }
+ return "";
+ }
+
+ private boolean isAddressHostSame(String address, String host) {
+ if (StringUtils.isEmpty(host)) {
+ return false;
+ }
+ try {
+ URI uri = new URI(address);
+ return host.equals(uri.getHost());
+ } catch (Exception e) {
+ LOGGER.warn("Exception occurred while constructing URI using the address
[{}]", address);
+ }
+ return false;
+ }
+
+ private boolean regionAndAZMatch(String ownRegion, String ownAvailableZone,
String engineRegion,
+ String engineAvailableZone) {
+ return ownRegion.equalsIgnoreCase(engineRegion) &&
ownAvailableZone.equals(engineAvailableZone);
+ }
+
+ public void refreshAffinityAddress(Set<String> sameZone, Set<String>
sameRegion) {
+ addressAutoRefreshed = true;
+ if (!sameZone.isEmpty()) {
+ availableZone.addAll(sameZone);
+ }
+ if (!sameRegion.isEmpty()) {
+ availableRegion.addAll(sameRegion);
+ }
+ }
}
diff --git
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java
index da8789292..4f03f112f 100644
---
a/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java
+++
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/common/HttpTransportImpl.java
@@ -18,6 +18,7 @@
package org.apache.servicecomb.http.client.common;
import java.io.IOException;
+import java.net.URI;
import java.util.Map;
import org.apache.http.client.HttpClient;
@@ -87,7 +88,7 @@ public class HttpTransportImpl implements HttpTransport {
globalHeaders.forEach(httpRequest::addHeader);
}
-
httpRequest.getHeaders().putAll(requestAuthHeaderProvider.loadAuthHeader(createSignRequest()));
+
httpRequest.getHeaders().putAll(requestAuthHeaderProvider.loadAuthHeader(createSignRequest(httpRequest.getUrl())));
//get Http response
org.apache.http.HttpResponse response =
httpClient.execute(httpRequest.getRealRequest());
@@ -98,9 +99,15 @@ public class HttpTransportImpl implements HttpTransport {
response.getAllHeaders());
}
- private static SignRequest createSignRequest() {
- // Now the implementations do not process SignRequest, so return null.
Maybe future will use it.
- return null;
+ private static SignRequest createSignRequest(String url) {
+ try {
+ URI uri = URI.create(url);
+ SignRequest signRequest = new SignRequest();
+ signRequest.setEndpoint(uri);
+ return signRequest;
+ } catch (Exception e) {
+ return null;
+ }
}
@Override
diff --git
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/OperationEvents.java
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/event/OperationEvents.java
similarity index 79%
rename from
clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/OperationEvents.java
rename to
clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/event/OperationEvents.java
index 62274519e..69896f750 100644
---
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/OperationEvents.java
+++
b/clients/http-client-common/src/main/java/org/apache/servicecomb/http/client/event/OperationEvents.java
@@ -15,10 +15,18 @@
* limitations under the License.
*/
-package org.apache.servicecomb.service.center.client;
+package org.apache.servicecomb.http.client.event;
public abstract class OperationEvents {
public static class UnAuthorizedOperationEvent extends OperationEvents {
+ private final String address;
+ public UnAuthorizedOperationEvent(String address) {
+ this.address = address;
+ }
+
+ public String getAddress() {
+ return address;
+ }
}
}
diff --git
a/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/AbstractAddressManagerTest.java
b/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/AbstractAddressManagerTest.java
index b831d0324..b14d6827c 100644
---
a/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/AbstractAddressManagerTest.java
+++
b/clients/http-client-common/src/test/java/org/apache/servicecomb/http/client/common/AbstractAddressManagerTest.java
@@ -46,9 +46,9 @@ public class AbstractAddressManagerTest {
public void setUp() throws NoSuchFieldException, IllegalAccessException {
addresses.add("http://127.0.0.1:30103");
addresses.add("https://127.0.0.2:30103");
- addressManager1 = new AbstractAddressManager(addresses);
- addressManager2 = new AbstractAddressManager("project", addresses);
- addressManager3 = new AbstractAddressManager(null, addresses);
+ addressManager1 = new AbstractAddressManager(addresses, "", "");
+ addressManager2 = new AbstractAddressManager("project", addresses, "", "");
+ addressManager3 = new AbstractAddressManager(null, addresses, "", "");
Field addressManagerField =
addressManager1.getClass().getDeclaredField("index");
addressManagerField.setAccessible(true);
addressManagerField.set(addressManager1, 0);
@@ -88,7 +88,7 @@ public class AbstractAddressManagerTest {
zoneAndRegion.put("sameZone", addressAZ);
zoneAndRegion.put("sameRegion", addressRG);
RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion,
"TEST");
- AbstractAddressManager addressManager = new
AbstractAddressManager(addresses) {};
+ AbstractAddressManager addressManager = new
AbstractAddressManager(addresses, "", "") {};
addressManager.refreshEndpoint(event, "TEST");
@@ -124,7 +124,7 @@ public class AbstractAddressManagerTest {
@Test
public void testMultipleThread() throws Exception {
- AbstractAddressManager addressManager = new
AbstractAddressManager(addresses);
+ AbstractAddressManager addressManager = new
AbstractAddressManager(addresses, "", "");
String address = "http://127.0.0.3:30100";
CountDownLatch latch = new CountDownLatch(2);
@@ -302,4 +302,27 @@ public class AbstractAddressManagerTest {
uri =
addressManager1.normalizeUri("rest://[2008::7:957f:b2d6:1af4:a1f8]:30100");
Assertions.assertEquals("http://[2008::7:957f:b2d6:1af4:a1f8]:30100", uri);
}
+
+ @Test
+ public void compareAndGetAddressTest() {
+ List<String> testAddr = new ArrayList<>();
+ testAddr.add("https://192.168.20.160:30100");
+ testAddr.add("https://127.0.0.1:30100");
+ testAddr.add("https://127.0.0.3:30100");
+ AbstractAddressManager manager = new AbstractAddressManager(testAddr, "",
"");
+
Assertions.assertTrue(manager.compareAndGetAddress("192.168.20.16").isEmpty());
+ Assertions.assertEquals("https://192.168.20.160:30100",
manager.compareAndGetAddress("192.168.20.160"));
+ }
+
+ @Test
+ public void AddressAffinityTest() {
+ List<String> testAddr = new ArrayList<>();
+
testAddr.add("https://192.168.20.160:30100?region=region1&availableZone=zone1");
+ testAddr.add("https://127.0.0.1:30100");
+ AbstractAddressManager manager = new AbstractAddressManager(testAddr,
"region1", "zone1");
+ Assertions.assertEquals("https://192.168.20.160:30100", manager.address());
+
+ AbstractAddressManager manager2 = new AbstractAddressManager("default",
testAddr, "region1", "zone1");
+ Assertions.assertEquals("https://192.168.20.160:30100",
manager2.address());
+ }
}
diff --git
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManager.java
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManager.java
index a5fd128ab..f955c148a 100644
---
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManager.java
+++
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManager.java
@@ -26,8 +26,9 @@ import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
public class ServiceCenterAddressManager extends AbstractAddressManager {
- public ServiceCenterAddressManager(String projectName, List<String>
addresses, EventBus eventBus) {
- super(projectName, addresses);
+ public ServiceCenterAddressManager(String projectName, List<String>
addresses, String ownRegion,
+ String ownAvailableZone, EventBus eventBus) {
+ super(projectName, addresses, ownRegion, ownAvailableZone);
eventBus.register(this);
}
diff --git
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java
index 56e07bae0..9f6e2baf8 100755
---
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java
+++
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterClient.java
@@ -33,7 +33,6 @@ import org.apache.servicecomb.http.client.common.HttpResponse;
import org.apache.servicecomb.http.client.common.HttpTransport;
import org.apache.servicecomb.http.client.common.HttpTransportFactory;
import org.apache.servicecomb.http.client.common.HttpUtils;
-import
org.apache.servicecomb.service.center.client.OperationEvents.UnAuthorizedOperationEvent;
import
org.apache.servicecomb.service.center.client.exception.OperationException;
import
org.apache.servicecomb.service.center.client.model.CreateMicroserviceInstanceRequest;
import
org.apache.servicecomb.service.center.client.model.CreateMicroserviceRequest;
@@ -76,8 +75,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
private final ServiceCenterRawClient httpClient;
- private EventBus eventBus;
-
private ServiceCenterAddressManager addressManager;
public ServiceCenterClient(ServiceCenterRawClient httpClient) {
@@ -85,8 +82,8 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
}
public ServiceCenterClient setEventBus(EventBus eventBus) {
- this.eventBus = eventBus;
addressManager.setEventBus(eventBus);
+ this.httpClient.setEventBus(eventBus);
return this;
}
@@ -124,7 +121,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
if (response.getStatusCode() == HttpStatus.SC_OK) {
return HttpUtils.deserialize(response.getContent(),
MicroserviceInstancesResponse.class);
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"get service-center instances fails, statusCode = " +
response.getStatusCode() + "; message = " + response
.getMessage()
@@ -145,7 +141,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
if (response.getStatusCode() == HttpStatus.SC_OK) {
return HttpUtils.deserialize(response.getContent(),
RegisteredMicroserviceResponse.class);
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"register service fails, statusCode = " + response.getStatusCode() +
"; message = " + response
.getMessage()
@@ -163,7 +158,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
if (response.getStatusCode() == HttpStatus.SC_OK) {
return HttpUtils.deserialize(response.getContent(),
MicroservicesResponse.class);
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"get service List fails, statusCode = " + response.getStatusCode() +
"; message = " + response
.getMessage()
@@ -188,7 +182,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
if (response.getStatusCode() == HttpStatus.SC_OK) {
return HttpUtils.deserialize(response.getContent(),
RegisteredMicroserviceResponse.class);
}
- sendUnAuthorizedEvent(response);
LOGGER.info("Query serviceId fails, statusCode = " +
response.getStatusCode() + "; message = " + response
.getMessage()
+ "; content = " + response.getContent());
@@ -211,7 +204,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
.deserialize(response.getContent(), MicroserviceResponse.class);
return microserviceResponse.getService();
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"get service message fails, statusCode = " +
response.getStatusCode() + "; message = " + response
.getMessage()
@@ -233,7 +225,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
if (response.getStatusCode() == HttpStatus.SC_OK) {
return HttpUtils.deserialize(response.getContent(),
RegisteredMicroserviceInstanceResponse.class);
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"register service instance fails, statusCode = " +
response.getStatusCode() + "; message = " + response
.getMessage()
@@ -274,7 +265,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
result.setModified(false);
return result;
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"get service instances list fails, statusCode = " +
response.getStatusCode() + "; message = " + response
.getMessage()
@@ -293,7 +283,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
if (response.getStatusCode() == HttpStatus.SC_OK) {
return HttpUtils.deserialize(response.getContent(),
MicroserviceInstancesResponse.class);
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"get service instances list fails, statusCode = " +
response.getStatusCode() + "; message = " + response
.getMessage()
@@ -314,7 +303,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
.deserialize(response.getContent(),
MicroserviceInstanceResponse.class);
return instanceResponse.getInstance();
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"get service instance message fails, statusCode = " +
response.getStatusCode() + "; message = " + response
.getMessage()
@@ -334,7 +322,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
LOGGER.info("Delete service instance successfully.");
return;
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"delete service instance fails, statusCode = " +
response.getStatusCode() + "; message = " + response
.getMessage()
@@ -354,7 +341,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
if (response.getStatusCode() == HttpStatus.SC_OK) {
return true;
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"update service instance status fails, statusCode = " +
response.getStatusCode() + "; message = " + response
.getMessage()
@@ -373,7 +359,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
if (response.getStatusCode() == HttpStatus.SC_OK) {
return;
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"heartbeats fails, statusCode = " + response.getStatusCode() + ";
message = " + response.getMessage()
+ "; content = " + response.getContent());
@@ -393,7 +378,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
if (response.getStatusCode() == HttpStatus.SC_OK) {
return true;
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"heartbeats fails, statusCode = " + response.getStatusCode() + ";
message = " + response.getMessage()
+ "; content = " + response.getContent());
@@ -418,7 +402,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
.deserialize(response.getContent(), GetSchemaListResponse.class);
return getSchemaResponse.getSchemas();
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"get service schemas list fails, statusCode = " +
response.getStatusCode() + "; message = " + response
.getMessage()
@@ -445,7 +428,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
GetSchemaResponse getSchemaResponse =
HttpUtils.deserialize(response.getContent(), GetSchemaResponse.class);
return getSchemaResponse.getSchema();
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"get service schema context fails, statusCode = " +
response.getStatusCode() + "; message = " + response
.getMessage()
@@ -465,7 +447,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
if (response.getStatusCode() == HttpStatus.SC_OK) {
return true;
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"update service schema fails, statusCode = " +
response.getStatusCode() + "; message = " + response
.getMessage()
@@ -488,7 +469,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
if (response.getStatusCode() == HttpStatus.SC_OK) {
return true;
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"update service schema fails, statusCode = " +
response.getStatusCode() + "; message = " + response
.getMessage()
@@ -508,7 +488,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
if (response.getStatusCode() == HttpStatus.SC_OK) {
return true;
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"update service schema fails, statusCode = " +
response.getStatusCode() + "; message = " + response
.getMessage()
@@ -519,18 +498,13 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
}
}
- private void sendUnAuthorizedEvent(HttpResponse response) {
- if (this.eventBus != null && response.getStatusCode() ==
HttpStatus.SC_UNAUTHORIZED) {
- this.eventBus.post(new UnAuthorizedOperationEvent());
- }
- }
-
@Override
- public RbacTokenResponse queryToken(RbacTokenRequest request) {
+ public RbacTokenResponse queryToken(RbacTokenRequest request, String host) {
try {
+ String queryAddress = addressManager.compareAndGetAddress(host);
HttpResponse response = httpClient
.postHttpRequestAbsoluteUrl("/v4/token", null,
- HttpUtils.serialize(request));
+ HttpUtils.serialize(request), queryAddress);
if (response.getStatusCode() == HttpStatus.SC_OK) {
RbacTokenResponse result =
HttpUtils.deserialize(response.getContent(), RbacTokenResponse.class);
result.setStatusCode(HttpStatus.SC_OK);
@@ -570,7 +544,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
if (response.getStatusCode() == HttpStatus.SC_OK) {
return true;
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"update service instance status fails, statusCode = " +
response.getStatusCode() + "; message = " + response
.getMessage()
diff --git
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterOperation.java
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterOperation.java
index 85671fee9..5c9fd21cb 100644
---
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterOperation.java
+++
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterOperation.java
@@ -185,7 +185,7 @@ public interface ServiceCenterOperation {
* @return if heartbeat is successful
* @throws OperationException If some problems happened to contact service
center or non http 200 returned.
*/
- RbacTokenResponse queryToken(RbacTokenRequest request);
+ RbacTokenResponse queryToken(RbacTokenRequest request, String host);
/**
* Update properties of microservice
diff --git
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java
index a8dc9963b..a76f86ddd 100755
---
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java
+++
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClient.java
@@ -21,13 +21,18 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.HttpStatus;
import org.apache.servicecomb.http.client.common.HttpRequest;
import org.apache.servicecomb.http.client.common.HttpResponse;
import org.apache.servicecomb.http.client.common.HttpTransport;
+import
org.apache.servicecomb.http.client.event.OperationEvents.UnAuthorizedOperationEvent;
import
org.apache.servicecomb.http.client.utils.ServiceCombServiceAvailableUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.eventbus.EventBus;
+
public class ServiceCenterRawClient {
private static final Logger LOGGER =
LoggerFactory.getLogger(ServiceCenterRawClient.class);
@@ -41,6 +46,8 @@ public class ServiceCenterRawClient {
private final ServiceCenterAddressManager addressManager;
+ private EventBus eventBus;
+
private ServiceCenterRawClient(String tenantName, HttpTransport
httpTransport,
ServiceCenterAddressManager addressManager) {
this.httpTransport = httpTransport;
@@ -49,36 +56,35 @@ public class ServiceCenterRawClient {
}
public HttpResponse getHttpRequest(String url, Map<String, String> headers,
String content) throws IOException {
- return doHttpRequest(url, false, headers, content, HttpRequest.GET);
+ return doHttpRequest(url, false, headers, content, HttpRequest.GET, "");
}
- public HttpResponse postHttpRequestAbsoluteUrl(String url, Map<String,
String> headers, String content)
+ public HttpResponse postHttpRequestAbsoluteUrl(String url, Map<String,
String> headers, String content, String address)
throws IOException {
- return doHttpRequest(url, true, headers, content, HttpRequest.POST);
+ return doHttpRequest(url, true, headers, content, HttpRequest.POST,
address);
}
public HttpResponse postHttpRequest(String url, Map<String, String> headers,
String content) throws IOException {
- return doHttpRequest(url, false, headers, content, HttpRequest.POST);
+ return doHttpRequest(url, false, headers, content, HttpRequest.POST, "");
}
public HttpResponse putHttpRequest(String url, Map<String, String> headers,
String content) throws IOException {
- return doHttpRequest(url, false, headers, content, HttpRequest.PUT);
+ return doHttpRequest(url, false, headers, content, HttpRequest.PUT, "");
}
public HttpResponse deleteHttpRequest(String url, Map<String, String>
headers, String content) throws IOException {
- return doHttpRequest(url, false, headers, content, HttpRequest.DELETE);
+ return doHttpRequest(url, false, headers, content, HttpRequest.DELETE, "");
}
private HttpResponse doHttpRequest(String url, boolean absoluteUrl,
Map<String, String> headers, String content,
- String method)
- throws IOException {
- String address = addressManager.address();
+ String method, String queryAddress) throws IOException {
+ String address = StringUtils.isEmpty(queryAddress) ?
addressManager.address() : queryAddress;
String formatUrl = addressManager.formatUrl(url, absoluteUrl, address);
HttpRequest httpRequest = buildHttpRequest(formatUrl, headers, content,
method);
-
+ HttpResponse httpResponse;
try {
- HttpResponse httpResponse = httpTransport.doRequest(httpRequest);
- addressManager.recordSuccessState(address);
+ httpResponse = httpTransport.doRequest(httpRequest);
+ recordAndSendUnAuthorizedEvent(httpResponse, address);
return httpResponse;
} catch (IOException e) {
addressManager.recordFailState(address);
@@ -87,7 +93,9 @@ public class ServiceCenterRawClient {
LOGGER.warn("send request to {} failed and retry to {} once. ", address,
retryAddress, e);
httpRequest = new HttpRequest(formatUrl, headers, content, method);
try {
- return httpTransport.doRequest(httpRequest);
+ httpResponse = httpTransport.doRequest(httpRequest);
+ recordAndSendUnAuthorizedEvent(httpResponse, retryAddress);
+ return httpResponse;
} catch (IOException ioException) {
addressManager.recordFailState(retryAddress);
LOGGER.warn("retry to {} failed again. ", retryAddress, e);
@@ -96,6 +104,16 @@ public class ServiceCenterRawClient {
}
}
+ private void recordAndSendUnAuthorizedEvent(HttpResponse response, String
address) {
+ if (this.eventBus != null && response.getStatusCode() ==
HttpStatus.SC_UNAUTHORIZED) {
+ LOGGER.warn("request unauthorized from server [{}], message [{}]",
address, response.getMessage());
+ addressManager.recordFailState(address);
+ this.eventBus.post(new UnAuthorizedOperationEvent(address));
+ } else {
+ addressManager.recordSuccessState(address);
+ }
+ }
+
public void checkAddressAvailable(String address) {
ServiceCombServiceAvailableUtils.checkAddressAvailable(addressManager,
address, httpTransport, ADDRESS_CHECK_PATH);
}
@@ -108,6 +126,10 @@ public class ServiceCenterRawClient {
return new HttpRequest(url, headers, content, method);
}
+ public void setEventBus(EventBus eventBus) {
+ this.eventBus = eventBus;
+ }
+
public static class Builder {
private String tenantName;
diff --git
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterWatch.java
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterWatch.java
index a8be8b98b..46ba02b8b 100644
---
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterWatch.java
+++
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterWatch.java
@@ -17,12 +17,14 @@
package org.apache.servicecomb.service.center.client;
+import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
+import org.apache.servicecomb.foundation.auth.SignRequest;
import org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;
import
org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;
import org.apache.servicecomb.http.client.common.WebSocketListener;
@@ -107,7 +109,7 @@ public class ServiceCenterWatch implements
WebSocketListener {
Map<String, String> headers = new HashMap<>();
headers.put("x-domain-name", this.tenantName);
headers.putAll(this.extraGlobalHeaders);
- headers.putAll(this.requestAuthHeaderProvider.loadAuthHeader(null));
+
headers.putAll(this.requestAuthHeaderProvider.loadAuthHeader(createSignRequest(address)));
currentServerUri = convertAddress(address);
LOGGER.info("start watch to address {}", currentServerUri);
webSocketTransport = new WebSocketTransport(currentServerUri,
sslProperties,
@@ -121,6 +123,17 @@ public class ServiceCenterWatch implements
WebSocketListener {
});
}
+ private SignRequest createSignRequest(String url) {
+ try {
+ URI uri = URI.create(url);
+ SignRequest signRequest = new SignRequest();
+ signRequest.setEndpoint(uri);
+ return signRequest;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
private String convertAddress(String address) {
String url = String.format(WATCH, project, serviceId);
if (address.startsWith(HTTP)) {
diff --git
a/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManagerTest.java
b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManagerTest.java
index f5c316cd8..d425cc5d4 100644
---
a/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManagerTest.java
+++
b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterAddressManagerTest.java
@@ -41,7 +41,7 @@ class ServiceCenterAddressManagerTest {
@Test
public void getUrlPrefix() {
addresses.add("http://127.0.0.1:30103");
- addressManager1 = new ServiceCenterAddressManager("project", addresses,
new EventBus());
+ addressManager1 = new ServiceCenterAddressManager("project", addresses,
"", "", new EventBus());
Assertions.assertNotNull(addressManager1);
@@ -55,7 +55,7 @@ class ServiceCenterAddressManagerTest {
@Test
public void formatUrlTest() {
addresses.add("http://127.0.0.1:30103");
- addressManager1 = new ServiceCenterAddressManager("project", addresses,
new EventBus());
+ addressManager1 = new ServiceCenterAddressManager("project", addresses,
"", "", new EventBus());
Assertions.assertNotNull(addressManager1);
String address = addressManager1.address();
@@ -76,7 +76,7 @@ class ServiceCenterAddressManagerTest {
Map<String, List<String>> zoneAndRegion = new HashMap<>();
zoneAndRegion.put("sameZone", addressAZ);
zoneAndRegion.put("sameRegion", addressRG);
- addressManager1 = new ServiceCenterAddressManager("project", addresses,
new EventBus());
+ addressManager1 = new ServiceCenterAddressManager("project", addresses,
"", "", new EventBus());
RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion,
"SERVICECENTER");
addressManager1.refreshEndpoint(event, "SERVICECENTER");
diff --git
a/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClientTest.java
b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClientTest.java
index 29337e31a..0cda29fc5 100755
---
a/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClientTest.java
+++
b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterRawClientTest.java
@@ -41,7 +41,8 @@ public class ServiceCenterRawClientTest {
public void TestDefaultParameter() throws IOException {
HttpTransport httpTransport = Mockito.mock(HttpTransport.class);
- ServiceCenterAddressManager addressManager = new
ServiceCenterAddressManager(PROJECT_NAME,
Arrays.asList("http://127.0.0.1:30100"), new EventBus());
+ ServiceCenterAddressManager addressManager = new
ServiceCenterAddressManager(PROJECT_NAME,
+ Arrays.asList("http://127.0.0.1:30100"), "", "", new EventBus());
ServiceCenterRawClient client = new ServiceCenterRawClient.Builder()
.setHttpTransport(httpTransport)
.setAddressManager(addressManager)
diff --git
a/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java
b/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java
index 50ae96db1..bfcfc4bbf 100644
---
a/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java
+++
b/demo/demo-multi-service-center/demo-multi-service-center-client/src/main/java/org/apache/servicecomb/demo/multiServiceCenterClient/RegistryClientTest.java
@@ -69,8 +69,8 @@ public class RegistryClientTest implements
CategorizedTestCase {
@Override
public void testRestTransport() throws Exception {
- ServiceCenterAddressManager addressManager = new
ServiceCenterAddressManager("default", Arrays.asList("http://127.0.0.1:30100"),
- new EventBus());
+ ServiceCenterAddressManager addressManager = new
ServiceCenterAddressManager("default",
+ Arrays.asList("http://127.0.0.1:30100"), "", "", new EventBus());
SSLProperties sslProperties = new SSLProperties();
sslProperties.setEnabled(false);
ServiceCenterClient serviceCenterClient = new
ServiceCenterClient(addressManager, sslProperties,
diff --git a/demo/docker-build-config/pom.xml b/demo/docker-build-config/pom.xml
index 4faa3efdd..625e01894 100644
--- a/demo/docker-build-config/pom.xml
+++ b/demo/docker-build-config/pom.xml
@@ -42,7 +42,7 @@
<name>${project.artifactId}:${project.version}</name>
<alias>${project.artifactId}</alias>
<build>
- <from>openjdk:8-jre-alpine</from>
+ <from>openjdk:8u342-jre</from>
<ports>
<port>7070</port>
<port>8080</port>
diff --git
a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/ConfigCenterConfig.java
b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/ConfigCenterConfig.java
index 430ab1589..daf3935ae 100644
---
a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/ConfigCenterConfig.java
+++
b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/ConfigCenterConfig.java
@@ -58,6 +58,10 @@ public final class ConfigCenterConfig {
private static final String CLIENT_SOCKET_TIMEOUT =
"servicecomb.config.client.timeout.socket";
+ private static final String REGION = "servicecomb.datacenter.region";
+
+ private static final String AVAILABLE_ZONE =
"servicecomb.datacenter.availableZone";
+
private ConfigCenterConfig() {
}
@@ -154,4 +158,12 @@ public final class ConfigCenterConfig {
public int getSocketTimeout(Configuration configuration) {
return configuration.getInt(CLIENT_SOCKET_TIMEOUT, 5000);
}
+
+ public String getRegion() {
+ return finalConfig.getString(REGION, "");
+ }
+
+ public String getAvailableZone() {
+ return finalConfig.getString(AVAILABLE_ZONE, "");
+ }
}
diff --git
a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImpl.java
b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImpl.java
index 492c5658f..37e315212 100644
---
a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImpl.java
+++
b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImpl.java
@@ -188,8 +188,9 @@ public class ConfigCenterConfigurationSourceImpl implements
ConfigCenterConfigur
private static RequestAuthHeaderProvider
getRequestAuthHeaderProvider(List<AuthHeaderProvider> authHeaderProviders) {
return signRequest -> {
+ String host = signRequest != null && signRequest.getEndpoint() != null ?
signRequest.getEndpoint().getHost() : "";
Map<String, String> headers = new HashMap<>();
- authHeaderProviders.forEach(provider ->
headers.putAll(provider.authHeaders()));
+ authHeaderProviders.forEach(provider ->
headers.putAll(provider.authHeaders(host)));
return headers;
};
}
@@ -198,7 +199,15 @@ public class ConfigCenterConfigurationSourceImpl
implements ConfigCenterConfigur
return new
ConfigCenterAddressManager(ConfigCenterConfig.INSTANCE.getDomainName(),
Deployment
.getSystemBootStrapInfo(ConfigCenterDefaultDeploymentProvider.SYSTEM_KEY_CONFIG_CENTER).getAccessURL(),
- EventManager.getEventBus());
+ getRegion(), getAvailableZone(), EventManager.getEventBus());
+ }
+
+ private String getRegion() {
+ return ConfigCenterConfig.INSTANCE.getRegion();
+ }
+
+ private String getAvailableZone() {
+ return ConfigCenterConfig.INSTANCE.getAvailableZone();
}
private void updateConfiguration(WatchedUpdateResult result) {
diff --git
a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImplTest.java
b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImplTest.java
index 4a9b64a88..f5fa3d404 100644
---
a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImplTest.java
+++
b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/ConfigCenterConfigurationSourceImplTest.java
@@ -36,7 +36,8 @@ class ConfigCenterConfigurationSourceImplTest {
List<String> addresses = new ArrayList<>();
addresses.add("http://127.0.0.1:30103");
addresses.add("http://127.0.0.2:30103");
- ConfigCenterAddressManager addressManager = new
ConfigCenterAddressManager("test", addresses, EventManager.getEventBus());
+ ConfigCenterAddressManager addressManager = new
ConfigCenterAddressManager("test", addresses,
+ "", "", EventManager.getEventBus());
Field addressManagerField =
addressManager.getClass().getSuperclass().getDeclaredField("index");
addressManagerField.setAccessible(true);
addressManagerField.set(addressManager, 0);
@@ -47,7 +48,7 @@ class ConfigCenterConfigurationSourceImplTest {
address = addressManager.address();
Assertions.assertEquals("http://127.0.0.1:30103/v3/test", address);
- addressManager = new ConfigCenterAddressManager(null, addresses,
EventManager.getEventBus());
+ addressManager = new ConfigCenterAddressManager(null, addresses, "", "",
EventManager.getEventBus());
addressManagerField =
addressManager.getClass().getSuperclass().getDeclaredField("index");
addressManagerField.setAccessible(true);
addressManagerField.set(addressManager, 0);
@@ -65,7 +66,8 @@ class ConfigCenterConfigurationSourceImplTest {
zoneAndRegion.put("sameZone", addressAZ);
zoneAndRegion.put("sameRegion", new ArrayList<>());
RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion,
"CseConfigCenter");
- ConfigCenterAddressManager addressManager = new
ConfigCenterAddressManager("test", addresses, EventManager.getEventBus());
+ ConfigCenterAddressManager addressManager = new
ConfigCenterAddressManager("test", addresses,
+ "", "", EventManager.getEventBus());
addressManager.onRefreshEndpointEvent(event);
List<String> availableAZ = addressManager.getAvailableZone();
diff --git
a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManagerTest.java
b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManagerTest.java
index f47cc35be..4592b867f 100644
---
a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManagerTest.java
+++
b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/center/client/ConfigCenterAddressManagerTest.java
@@ -40,8 +40,8 @@ class ConfigCenterAddressManagerTest {
public void addressManagerTest() throws NoSuchFieldException,
IllegalAccessException {
addresses.add("http://127.0.0.1:30103");
addresses.add("https://127.0.0.2:30103");
- addressManager1 = new ConfigCenterAddressManager("project", addresses, new
EventBus());
- addressManager2 = new ConfigCenterAddressManager(null, addresses, new
EventBus());
+ addressManager1 = new ConfigCenterAddressManager("project", addresses, "",
"", new EventBus());
+ addressManager2 = new ConfigCenterAddressManager(null, addresses, "", "",
new EventBus());
Field addressManagerField =
addressManager1.getClass().getSuperclass().getDeclaredField("index");
addressManagerField.setAccessible(true);
addressManagerField.set(addressManager1, 0);
@@ -70,7 +70,7 @@ class ConfigCenterAddressManagerTest {
Map<String, List<String>> zoneAndRegion = new HashMap<>();
zoneAndRegion.put("sameZone", addressAZ);
zoneAndRegion.put("sameRegion", addressRG);
- addressManager1 = new ConfigCenterAddressManager("project", addresses, new
EventBus());
+ addressManager1 = new ConfigCenterAddressManager("project", addresses, "",
"", new EventBus());
RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion,
"CseConfigCenter");
addressManager1.refreshEndpoint(event, "CseConfigCenter");
diff --git
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfig.java
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfig.java
index 872165f51..e556c778e 100644
---
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfig.java
+++
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfig.java
@@ -75,6 +75,10 @@ public class KieConfig {
private static final String CUSTOM_LABEL_VALUE_DEFAULT = "";
+ private static final String REGION = "servicecomb.datacenter.region";
+
+ private static final String AVAILABLE_ZONE =
"servicecomb.datacenter.availableZone";
+
private KieConfig() {
}
@@ -185,4 +189,12 @@ public class KieConfig {
public String getProxyPasswd() {
return finalConfig.getString(VertxConst.PROXY_PASSWD, null);
}
+
+ public String getRegion() {
+ return finalConfig.getString(REGION, "");
+ }
+
+ public String getAvailableZone() {
+ return finalConfig.getString(AVAILABLE_ZONE, "");
+ }
}
diff --git
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfigurationSourceImpl.java
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfigurationSourceImpl.java
index 514466089..683a81b83 100644
---
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfigurationSourceImpl.java
+++
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieConfigurationSourceImpl.java
@@ -169,15 +169,19 @@ public class KieConfigurationSourceImpl implements
ConfigCenterConfigurationSour
private static RequestAuthHeaderProvider
getRequestAuthHeaderProvider(List<AuthHeaderProvider> authHeaderProviders) {
return signRequest -> {
+ String host = signRequest != null && signRequest.getEndpoint() != null ?
signRequest.getEndpoint().getHost() : "";
Map<String, String> headers = new HashMap<>();
- authHeaderProviders.forEach(provider ->
headers.putAll(provider.authHeaders()));
+ authHeaderProviders.forEach(provider ->
headers.putAll(provider.authHeaders(host)));
return headers;
};
}
private KieAddressManager configKieAddressManager() {
+ String region = KieConfig.INSTANCE.getRegion();
+ String availableZone = KieConfig.INSTANCE.getAvailableZone();
return new KieAddressManager(
- Arrays.asList(KieConfig.INSTANCE.getServerUri().split(",")),
EventManager.getEventBus());
+ Arrays.asList(KieConfig.INSTANCE.getServerUri().split(",")), region,
availableZone,
+ EventManager.getEventBus());
}
private void updateConfiguration(WatchedUpdateResult result) {
diff --git
a/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java
b/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java
index 313c19ee5..0e036e21a 100644
---
a/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java
+++
b/foundations/foundation-spi/src/main/java/org/apache/servicecomb/foundation/auth/AuthHeaderProvider.java
@@ -21,11 +21,21 @@ import java.util.HashMap;
import java.util.Map;
public interface AuthHeaderProvider {
- default Map<String, String> authHeaders() {
+ /**
+ * Obtain RBAC authentication request header, host is the key of cache
+ *
+ * @param host engine address ip
+ * @return auth headers
+ */
+ default Map<String, String> authHeaders(String host) {
return new HashMap<>(0);
}
default Map<String, String> getSignAuthHeaders(SignRequest request) {
- return authHeaders();
+ String host = "";
+ if (request != null && request.getEndpoint() != null) {
+ host = request.getEndpoint().getHost();
+ }
+ return authHeaders(host);
}
}
diff --git
a/huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/DefaultMonitorDataPublisher.java
b/huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/DefaultMonitorDataPublisher.java
index de350f787..920f0b103 100644
---
a/huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/DefaultMonitorDataPublisher.java
+++
b/huawei-cloud/dashboard/src/main/java/org/apache/servicecomb/huaweicloud/dashboard/monitor/DefaultMonitorDataPublisher.java
@@ -45,6 +45,8 @@ import
org.apache.servicecomb.huaweicloud.dashboard.monitor.data.MonitorConstant
import
org.apache.servicecomb.huaweicloud.dashboard.monitor.model.MonitorDataProvider;
import
org.apache.servicecomb.huaweicloud.dashboard.monitor.model.MonitorDataPublisher;
+import com.netflix.config.DynamicPropertyFactory;
+
public class DefaultMonitorDataPublisher implements MonitorDataPublisher {
private static final String SSL_KEY = "mc.consumer";
@@ -76,7 +78,11 @@ public class DefaultMonitorDataPublisher implements
MonitorDataPublisher {
throw new IllegalStateException("dashboard address is not configured.");
}
- return new DashboardAddressManager(addresses, EventManager.getEventBus());
+ String region = DynamicPropertyFactory.getInstance().
+ getStringProperty("servicecomb.datacenter.region", "").get();
+ String availableZone = DynamicPropertyFactory.getInstance().
+ getStringProperty("servicecomb.datacenter.availableZone", "").get();
+ return new DashboardAddressManager(addresses, region, availableZone,
EventManager.getEventBus());
}
private HttpTransport createHttpTransport(DashboardAddressManager
addressManager, RequestConfig requestConfig,
@@ -111,8 +117,9 @@ public class DefaultMonitorDataPublisher implements
MonitorDataPublisher {
private static RequestAuthHeaderProvider
getRequestAuthHeaderProvider(List<AuthHeaderProvider> authHeaderProviders) {
return signRequest -> {
+ String host = signRequest != null && signRequest.getEndpoint() != null ?
signRequest.getEndpoint().getHost() : "";
Map<String, String> headers = new HashMap<>();
- authHeaderProviders.forEach(provider ->
headers.putAll(provider.authHeaders()));
+ authHeaderProviders.forEach(provider ->
headers.putAll(provider.authHeaders(host)));
return headers;
};
}
diff --git
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/RBACBootStrapService.java
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/RBACBootStrapService.java
index 1c599c4cc..a3671a3eb 100644
---
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/RBACBootStrapService.java
+++
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/RBACBootStrapService.java
@@ -93,8 +93,10 @@ public class RBACBootStrapService implements
BootStrapService {
}
private ServiceCenterAddressManager createAddressManager(Environment
environment) {
+ String region = environment.getProperty("servicecomb.datacenter.region",
"");
+ String availableZone =
environment.getProperty("servicecomb.datacenter.availableZone", "");
return new ServiceCenterAddressManager(getTenantName(environment),
- getRBACAddressList(environment), EventManager.getEventBus());
+ getRBACAddressList(environment), region, availableZone,
EventManager.getEventBus());
}
private SSLProperties createSSLProperties(Environment environment, String
tag) {
diff --git
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenAuthHeaderProvider.java
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenAuthHeaderProvider.java
index 0f0755683..b040f516f 100644
---
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenAuthHeaderProvider.java
+++
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenAuthHeaderProvider.java
@@ -26,8 +26,8 @@ import
org.apache.servicecomb.foundation.auth.AuthHeaderProvider;
public class TokenAuthHeaderProvider implements AuthHeaderProvider {
@Override
- public Map<String, String> authHeaders() {
- String token =
TokenCacheManager.getInstance().getToken(RBACBootStrapService.DEFAULT_REGISTRY_NAME);
+ public Map<String, String> authHeaders(String host) {
+ String token = TokenCacheManager.getInstance().getToken(host);
if (StringUtils.isEmpty(token)) {
return new HashMap<>();
}
diff --git
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenCacheManager.java
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenCacheManager.java
index e43f9127b..31d6a0ee9 100644
---
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenCacheManager.java
+++
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/auth/TokenCacheManager.java
@@ -17,9 +17,8 @@
package org.apache.servicecomb.serviceregistry.auth;
+import java.net.URI;
import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
@@ -28,13 +27,11 @@ import javax.ws.rs.core.Response.Status;
import org.apache.commons.lang3.StringUtils;
import org.apache.servicecomb.foundation.auth.Cipher;
-import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
-import org.apache.servicecomb.http.client.event.EngineConnectChangedEvent;
+import
org.apache.servicecomb.http.client.event.OperationEvents.UnAuthorizedOperationEvent;
import org.apache.servicecomb.registry.api.event.ServiceCenterEventBus;
import org.apache.servicecomb.service.center.client.ServiceCenterClient;
import org.apache.servicecomb.service.center.client.model.RbacTokenRequest;
import org.apache.servicecomb.service.center.client.model.RbacTokenResponse;
-import org.apache.servicecomb.serviceregistry.event.NotPermittedEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -55,17 +52,15 @@ public final class TokenCacheManager {
private static final TokenCacheManager INSTANCE = new TokenCacheManager();
-
- private final Map<String, TokenCache> tokenCacheMap;
-
private Map<String, ServiceCenterClient> serviceCenterClients;
+ private TokenCache tokenCache;
+
public static TokenCacheManager getInstance() {
return INSTANCE;
}
private TokenCacheManager() {
- tokenCacheMap = new ConcurrentHashMapEx<>();
}
public void setServiceCenterClients(Map<String, ServiceCenterClient>
serviceCenterClients) {
@@ -73,24 +68,17 @@ public final class TokenCacheManager {
}
public void addTokenCache(String registryName, String accountName, String
password, Cipher cipher) {
- Objects.requireNonNull(registryName, "registryName should not be null!");
- if (tokenCacheMap.containsKey(registryName)) {
- LOGGER.warn("duplicate token cache registration for
serviceRegistry[{}]", registryName);
- return;
- }
-
- tokenCacheMap.put(registryName, new TokenCache(registryName, accountName,
password, cipher));
+ tokenCache = new TokenCache(registryName, accountName, password, cipher);
}
- public String getToken(String registryName) {
- return Optional.ofNullable(tokenCacheMap.get(registryName))
- .map(TokenCache::getToken)
- .orElse(null);
+ public String getToken(String host) {
+ if (tokenCache == null) {
+ return null;
+ }
+ return tokenCache.getToken(host);
}
public class TokenCache {
- private static final String UN_AUTHORIZED_CODE_HALF_OPEN = "401302";
-
private static final long TOKEN_REFRESH_TIME_IN_SECONDS = 20 * 60 * 1000;
private final String registryName;
@@ -105,10 +93,6 @@ public final class TokenCacheManager {
private final Cipher cipher;
- private int lastStatusCode;
-
- private String lastErrorCode;
-
public TokenCache(String registryName, String accountName, String password,
Cipher cipher) {
this.registryName = registryName;
@@ -133,12 +117,12 @@ public final class TokenCacheManager {
.build(new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
- return createHeaders();
+ return createHeaders(key);
}
@Override
public ListenableFuture<String> reload(String key, String
oldValue) throws Exception {
- return Futures.submit(() -> createHeaders(), executorService);
+ return Futures.submit(() -> createHeaders(key),
executorService);
}
});
ServiceCenterEventBus.getEventBus().register(this);
@@ -146,34 +130,28 @@ public final class TokenCacheManager {
}
@Subscribe
- public void onNotPermittedEvent(NotPermittedEvent event) {
- this.executorService.submit(() -> {
- if (lastStatusCode == Status.UNAUTHORIZED.getStatusCode() &&
UN_AUTHORIZED_CODE_HALF_OPEN
- .equals(lastErrorCode)) {
- cache.refresh(registryName);
- }
- });
+ public void onUnAuthorizedOperationEvent(UnAuthorizedOperationEvent event)
{
+ LOGGER.warn("address {} unAuthorized, refresh cache token!",
event.getAddress());
+ cache.refresh(getHostByAddress(event.getAddress()));
}
- @Subscribe
- public void onEngineConnectChangedEvent(EngineConnectChangedEvent event) {
- cache.refresh(registryName);
+ private String getHostByAddress(String address) {
+ try {
+ URI uri = URI.create(address);
+ return uri.getHost();
+ } catch (Exception e) {
+ LOGGER.error("get host by address [{}] error!", address, e);
+ return registryName;
+ }
}
- private String createHeaders() {
- LOGGER.info("start to create RBAC headers");
-
+ private String createHeaders(String host) {
+ LOGGER.info("start to create RBAC headers for host: {}", host);
ServiceCenterClient serviceCenterClient =
serviceCenterClients.get(this.registryName);
-
RbacTokenRequest request = new RbacTokenRequest();
request.setName(accountName);
request.setPassword(new String(cipher.decrypt(password.toCharArray())));
-
- RbacTokenResponse rbacTokenResponse =
serviceCenterClient.queryToken(request);
-
- this.lastStatusCode = rbacTokenResponse.getStatusCode();
- this.lastErrorCode = rbacTokenResponse.getErrorCode();
-
+ RbacTokenResponse rbacTokenResponse =
serviceCenterClient.queryToken(request, "");
if (Status.UNAUTHORIZED.getStatusCode() ==
rbacTokenResponse.getStatusCode()
|| Status.FORBIDDEN.getStatusCode() ==
rbacTokenResponse.getStatusCode()) {
// password wrong, do not try anymore
@@ -185,8 +163,14 @@ public final class TokenCacheManager {
LOGGER.warn("service center do not support RBAC token, you should not
config account info");
return INVALID_TOKEN;
}
+ if (Status.INTERNAL_SERVER_ERROR.getStatusCode() ==
rbacTokenResponse.getStatusCode()) {
+ // return null for server_error, so the token information can be
re-fetched on the next call.
+ // It will prompt 'CacheLoader returned null for key xxx'
+ LOGGER.warn("service center query RBAC token error!");
+ return null;
+ }
- LOGGER.info("refresh token successfully {}",
rbacTokenResponse.getStatusCode());
+ LOGGER.info("refresh host [{}] token successfully {}", host,
rbacTokenResponse.getStatusCode());
return rbacTokenResponse.getToken();
}
@@ -194,13 +178,16 @@ public final class TokenCacheManager {
return TOKEN_REFRESH_TIME_IN_SECONDS;
}
- public String getToken() {
+ public String getToken(String host) {
if (!enabled()) {
return null;
}
-
+ String address = host;
+ if (StringUtils.isEmpty(address)) {
+ address = registryName;
+ }
try {
- return cache.get(registryName);
+ return cache.get(address);
} catch (Exception e) {
LOGGER.error("failed to create token", e);
return null;
diff --git
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/IpPortManager.java
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/IpPortManager.java
index 1dcd10a0e..f2808189f 100644
---
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/IpPortManager.java
+++
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/IpPortManager.java
@@ -33,6 +33,8 @@ import
org.apache.servicecomb.serviceregistry.refresh.ClassificationAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.netflix.config.DynamicPropertyFactory;
+
public class IpPortManager {
private static final Logger LOGGER =
LoggerFactory.getLogger(IpPortManager.class);
@@ -66,11 +68,22 @@ public class IpPortManager {
throw new IllegalArgumentException("Service center address is required
to start the application.");
}
List<String> addresses =
defaultIpPort.stream().map(IpPort::toString).collect(Collectors.toList());
- addressManger = new ServiceRegistryAddressManager(addresses,
EventManager.getEventBus());
+ addressManger = new ServiceRegistryAddressManager(addresses, "", "",
EventManager.getEventBus());
+
addressManger.constructAffinityAddress(serviceRegistryConfig.getOriginAddress(),
getRegion(), getAvailableZone());
classificationAddress = new ClassificationAddress(serviceRegistryConfig,
instanceCacheManager);
LOGGER.info("Initial service center address is {}", getAvailableAddress());
}
+ private String getRegion() {
+ return DynamicPropertyFactory.getInstance().
+ getStringProperty("servicecomb.datacenter.region", "").get();
+ }
+
+ private String getAvailableZone() {
+ return DynamicPropertyFactory.getInstance().
+ getStringProperty("servicecomb.datacenter.availableZone", "").get();
+ }
+
// we have to do this operation after the first time setup has already done
public void initAutoDiscovery() {
if (!autoDiscoveryInited &&
this.serviceRegistryConfig.isRegistryAutoDiscovery()) {
diff --git
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/http/EmptyAuthHeaderProvider.java
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/http/EmptyAuthHeaderProvider.java
index 37828b4ad..79dc86cfd 100644
---
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/http/EmptyAuthHeaderProvider.java
+++
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/http/EmptyAuthHeaderProvider.java
@@ -24,7 +24,7 @@ import
org.apache.servicecomb.foundation.auth.AuthHeaderProvider;
public class EmptyAuthHeaderProvider implements AuthHeaderProvider {
@Override
- public Map<String, String> authHeaders() {
+ public Map<String, String> authHeaders(String host) {
return new HashMap<>(0);
}
}
diff --git
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java
index 28311a0eb..ff54002e1 100644
---
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java
+++
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java
@@ -35,6 +35,7 @@ import javax.ws.rs.core.Response.Status;
import org.apache.servicecomb.foundation.common.net.IpPort;
import org.apache.servicecomb.foundation.common.utils.JsonUtils;
import org.apache.servicecomb.foundation.vertx.AsyncResultCallback;
+import
org.apache.servicecomb.http.client.event.OperationEvents.UnAuthorizedOperationEvent;
import
org.apache.servicecomb.http.client.utils.ServiceCombServiceAvailableUtils;
import
org.apache.servicecomb.registry.api.event.MicroserviceInstanceChangedEvent;
import org.apache.servicecomb.registry.api.registry.FindInstancesResponse;
@@ -64,7 +65,6 @@ import
org.apache.servicecomb.serviceregistry.client.ClientException;
import org.apache.servicecomb.serviceregistry.client.IpPortManager;
import org.apache.servicecomb.serviceregistry.client.ServiceRegistryClient;
import org.apache.servicecomb.serviceregistry.config.ServiceRegistryConfig;
-import org.apache.servicecomb.serviceregistry.event.NotPermittedEvent;
import org.apache.servicecomb.registry.api.event.ServiceCenterEventBus;
import org.apache.servicecomb.serviceregistry.task.HeartbeatResult;
import
org.apache.servicecomb.serviceregistry.task.MicroserviceInstanceHeartbeatTask;
@@ -152,7 +152,7 @@ public final class ServiceRegistryClientImpl implements
ServiceRegistryClient {
return;
}
holder.setStatusCode(response.statusCode());
- sendUnAuthorizedEvent(response);
+ sendUnAuthorizedEvent(response, requestContext);
response.exceptionHandler(e -> {
LOGGER.error("error in processing response.", e);
countDownLatch.countDown();
@@ -232,7 +232,7 @@ public final class ServiceRegistryClientImpl implements
ServiceRegistryClient {
return;
}
- sendUnAuthorizedEvent(response);
+ sendUnAuthorizedEvent(response, requestContext);
response.exceptionHandler(e -> {
LOGGER.error("error in processing response.", e);
countDownLatch.countDown();
@@ -247,12 +247,20 @@ public final class ServiceRegistryClientImpl implements
ServiceRegistryClient {
};
}
- private void sendUnAuthorizedEvent(HttpClientResponse response) {
+ private void sendUnAuthorizedEvent(HttpClientResponse response,
RequestContext requestContext) {
if (response.statusCode() == Status.UNAUTHORIZED.getStatusCode()) {
- ServiceCenterEventBus.getEventBus().post(new NotPermittedEvent());
+ ServiceCenterEventBus.getEventBus().post(new
UnAuthorizedOperationEvent(getAddressWithProtocol(requestContext)));
}
}
+ private String getAddressWithProtocol(RequestContext requestContext) {
+ String ipAndPort = requestContext.getIpPort().toString();
+ if (ipAndPort.startsWith("http")) {
+ return ipAndPort;
+ }
+ return "https://" + ipAndPort;
+ }
+
private Handler<RestResponse> syncHandlerForInstances(CountDownLatch
countDownLatch,
MicroserviceInstances mInstances) {
return restResponse -> {
@@ -1007,7 +1015,7 @@ public final class ServiceRegistryClientImpl implements
ServiceRegistryClient {
return;
}
holder.setStatusCode(response.statusCode());
- sendUnAuthorizedEvent(response);
+ sendUnAuthorizedEvent(response, restResponse.getRequestContext());
countDownLatch.countDown();
};
}
diff --git
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/config/ServiceRegistryConfig.java
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/config/ServiceRegistryConfig.java
index 4e5b3a825..7cf3dafe2 100644
---
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/config/ServiceRegistryConfig.java
+++
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/config/ServiceRegistryConfig.java
@@ -132,6 +132,8 @@ public class ServiceRegistryConfig {
private Function<ServiceRegistry, ServiceRegistryClient>
serviceRegistryClientConstructor =
serviceRegistry -> new ServiceRegistryClientImpl(this);
+ private List<String> originAddress;
+
public ServiceRegistryConfig() {
}
@@ -446,4 +448,13 @@ public class ServiceRegistryConfig {
public ServiceRegistryClient createServiceRegistryClient(ServiceRegistry
serviceRegistry) {
return this.serviceRegistryClientConstructor.apply(serviceRegistry);
}
+
+ public List<String> getOriginAddress() {
+ return originAddress;
+ }
+
+ public ServiceRegistryConfig setOriginAddress(List<String> originAddress) {
+ this.originAddress = originAddress;
+ return this;
+ }
}
diff --git
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/config/ServiceRegistryConfigBuilder.java
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/config/ServiceRegistryConfigBuilder.java
index ae6b7fd08..647337db3 100644
---
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/config/ServiceRegistryConfigBuilder.java
+++
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/config/ServiceRegistryConfigBuilder.java
@@ -46,12 +46,15 @@ class ServiceRegistryConfigBuilder {
private boolean ssl;
+ private List<String> originAddress;
+
public ServiceRegistryConfig build() {
return new ServiceRegistryConfig()
.setHttpVersion(getHttpVersion())
.setInstances(getInstances())
.setIpPort(getIpPort())
.setSsl(isSsl())
+ .setOriginAddress(getOriginAddress())
.setClientName(RegistryHttpClientOptionsSPI.CLIENT_NAME)
.setWatchClientName(RegistryWatchHttpClientOptionsSPI.CLIENT_NAME)
.setConnectionTimeout(getConnectionTimeout())
@@ -110,11 +113,16 @@ class ServiceRegistryConfigBuilder {
return this.ssl;
}
+ public List<String> getOriginAddress() {
+ return originAddress;
+ }
+
public ArrayList<IpPort> getIpPort() {
List<String> uriList = Objects
.requireNonNull(Deployment.getSystemBootStrapInfo(ServiceCenterDefaultDeploymentProvider.SYSTEM_KEY_SERVICE_CENTER),
"no sc address found!")
.getAccessURL();
+ this.originAddress = uriList;
ArrayList<IpPort> ipPortList = new ArrayList<>();
uriList.forEach(anUriList -> {
try {
diff --git
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/refresh/ServiceRegistryAddressManager.java
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/refresh/ServiceRegistryAddressManager.java
index 4f25eafba..69f11ed5c 100644
---
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/refresh/ServiceRegistryAddressManager.java
+++
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/serviceregistry/refresh/ServiceRegistryAddressManager.java
@@ -18,11 +18,16 @@
package org.apache.servicecomb.serviceregistry.refresh;
import java.net.URI;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
import org.apache.servicecomb.foundation.common.net.IpPort;
+import org.apache.servicecomb.foundation.common.net.NetUtils;
import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
import org.apache.servicecomb.http.client.common.AbstractAddressManager;
+import org.apache.servicecomb.http.client.common.URLEndPoint;
import org.apache.servicecomb.http.client.event.RefreshEndpointEvent;
import com.google.common.eventbus.EventBus;
@@ -31,8 +36,13 @@ import com.google.common.eventbus.Subscribe;
public class ServiceRegistryAddressManager extends AbstractAddressManager {
private static final String URI_PREFIX = "rest://";
- public ServiceRegistryAddressManager(List<String> addresses, EventBus
eventBus) {
- super(addresses);
+ private static final String ZONE = "availableZone";
+
+ private static final String REGION = "region";
+
+ public ServiceRegistryAddressManager(List<String> addresses, String
ownRegion, String ownAvailableZone,
+ EventBus eventBus) {
+ super(addresses, ownRegion, ownAvailableZone);
eventBus.register(this);
}
@@ -54,4 +64,35 @@ public class ServiceRegistryAddressManager extends
AbstractAddressManager {
public void onRefreshEndpointEvent(RefreshEndpointEvent event) {
refreshEndpoint(event, RefreshEndpointEvent.SERVICE_CENTER_NAME);
}
+
+ public void constructAffinityAddress(List<String> addresses, String
ownRegion, String ownAvailableZone) {
+ boolean isAffinityAddress = addresses.stream().anyMatch(addr ->
addr.contains(ZONE) || addr.contains(REGION));
+ if (!isAffinityAddress || (StringUtils.isEmpty(ownRegion) &&
StringUtils.isEmpty(ownAvailableZone))) {
+ return;
+ }
+ Set<String> sameZone = new HashSet<>();
+ Set<String> sameRegion = new HashSet<>();
+ for (String address : addresses) {
+ URI uri = URI.create(address);
+ String ipPort = NetUtils.parseIpPort(uri).toString();
+ if (isMatchRegionAndZone(address, ownRegion, ownAvailableZone)) {
+ sameZone.add(ipPort);
+ } else {
+ sameRegion.add(ipPort);
+ }
+ }
+ refreshAffinityAddress(sameZone, sameRegion);
+ }
+
+ private boolean isMatchRegionAndZone(String address, String ownRegion,
String ownAvailableZone) {
+ try {
+ URLEndPoint endPoint = new URLEndPoint(address);
+ if (!StringUtils.equals(ownRegion, endPoint.getFirst(REGION))) {
+ return false;
+ }
+ return StringUtils.equals(ownAvailableZone, endPoint.getFirst(ZONE));
+ } catch (Exception e) {
+ return false;
+ }
+ }
}
diff --git
a/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/client/http/MockAuthHeaderProvider.java
b/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/client/http/MockAuthHeaderProvider.java
index ea210a6c1..64ae22092 100644
---
a/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/client/http/MockAuthHeaderProvider.java
+++
b/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/client/http/MockAuthHeaderProvider.java
@@ -24,7 +24,7 @@ import
org.apache.servicecomb.foundation.auth.AuthHeaderProvider;
public class MockAuthHeaderProvider implements AuthHeaderProvider {
@Override
- public Map<String, String> authHeaders() {
+ public Map<String, String> authHeaders(String host) {
HashMap<String, String> headers = new HashMap<>();
headers.put("X-Service-AK", "blah...");
return headers;
diff --git
a/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/refresh/ServiceRegistryAddressManagerTest.java
b/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/refresh/ServiceRegistryAddressManagerTest.java
index d6a181b4f..ff8547c4d 100644
---
a/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/refresh/ServiceRegistryAddressManagerTest.java
+++
b/service-registry/registry-service-center/src/test/java/org/apache/servicecomb/serviceregistry/refresh/ServiceRegistryAddressManagerTest.java
@@ -44,8 +44,8 @@ class ServiceRegistryAddressManagerTest {
public void addressManagerTest() {
IpPort ipPort = new IpPort("127.0.0.1", 30103);
addresses.add(ipPort.toString());
- addressManager1 = new ServiceRegistryAddressManager(addresses, new
EventBus());
- addressManager2 = new ServiceRegistryAddressManager(addresses, new
EventBus());
+ addressManager1 = new ServiceRegistryAddressManager(addresses, "", "", new
EventBus());
+ addressManager2 = new ServiceRegistryAddressManager(addresses, "", "", new
EventBus());
Assertions.assertNotNull(addressManager1);
Assertions.assertNotNull(addressManager2);
@@ -70,7 +70,7 @@ class ServiceRegistryAddressManagerTest {
Map<String, List<String>> zoneAndRegion = new HashMap<>();
zoneAndRegion.put("sameZone", addressAZ);
zoneAndRegion.put("sameRegion", addressRG);
- addressManager1 = new ServiceRegistryAddressManager(addresses, new
EventBus());
+ addressManager1 = new ServiceRegistryAddressManager(addresses, "", "", new
EventBus());
RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion,
"SERVICECENTER");
addressManager1.refreshEndpoint(event, "SERVICECENTER");
@@ -88,7 +88,7 @@ class ServiceRegistryAddressManagerTest {
Map<String, List<String>> zoneAndRegion = new HashMap<>();
zoneAndRegion.put("sameZone", addressAZ);
zoneAndRegion.put("sameRegion", new ArrayList<>());
- addressManager1 = new ServiceRegistryAddressManager(addresses,
EventManager.getEventBus());
+ addressManager1 = new ServiceRegistryAddressManager(addresses, "", "",
EventManager.getEventBus());
RefreshEndpointEvent event = new RefreshEndpointEvent(zoneAndRegion,
"SERVICECENTER");
addressManager1.refreshEndpoint(event, "SERVICECENTER");