This is an automated email from the ASF dual-hosted git repository.
youling1128 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
The following commit(s) were added to refs/heads/master by this push:
new 9b7f8e6039 [#5013] Fixing the issue where microservices cannot be
registered when enabling RBAC authentication in a dual-engine disaster recovery
scenario. (#5019)
9b7f8e6039 is described below
commit 9b7f8e60390043c5b8888272ef2560ef4316b51e
Author: Alex <[email protected]>
AuthorDate: Mon Nov 24 15:27:17 2025 +0800
[#5013] Fixing the issue where microservices cannot be registered when
enabling RBAC authentication in a dual-engine disaster recovery scenario.
(#5019)
---
.../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 | 86 +++++++++++++++++++--
.../http/client/common/HttpTransportImpl.java | 19 ++++-
.../http/client/event}/OperationEvents.java | 10 ++-
.../client/common/AbstractAddressManagerTest.java | 33 ++++++--
.../center/client/ServiceCenterAddressManager.java | 5 +-
.../service/center/client/ServiceCenterClient.java | 36 +--------
.../center/client/ServiceCenterOperation.java | 2 +-
.../center/client/ServiceCenterRawClient.java | 50 +++++++++----
.../center/client/ServiceCenterRegistration.java | 2 +-
.../service/center/client/ServiceCenterWatch.java | 15 +++-
.../client/ServiceCenterAddressManagerTest.java | 6 +-
.../center/client/ServiceCenterClientTest.java | 2 +-
.../center/client/ServiceCenterRawClientTest.java | 3 +-
.../RegistryClientTest.java | 4 +-
.../cc/ConfigCenterDynamicPropertiesSource.java | 12 +--
.../config/cc/ConfigCenterAddressManagerTest.java | 6 +-
.../ConfigCenterConfigurationSourceImplTest.java | 8 +-
.../config/kie/KieDynamicPropertiesSource.java | 11 ++-
.../foundation/auth/AuthHeaderProvider.java | 14 +++-
.../monitor/DefaultMonitorDataPublisher.java | 7 +-
.../servicestage/RBACBootStrapService.java | 7 +-
.../servicestage/TokenAuthHeaderProvider.java | 4 +-
.../servicestage/TokenCacheManager.java | 87 ++++++++++------------
.../servicecomb/registry/sc/SCAddressManager.java | 35 +++++----
.../servicecomb/registry/sc/SCClientUtils.java | 62 +++++++++++++--
32 files changed, 402 insertions(+), 183 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 3b346153a0..977c84ef63 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, EventBus eventBus, String region,
+ String availableZone) {
+ super(projectName, addresses, region, availableZone);
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 66d9d154fd..8ed31a5a61 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 2ab9325479..b98a7d3b2a 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 0742c11fb1..d8c069ee9b 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, EventBus eventBus, String
region, String availableZone) {
+ super(addresses, region, availableZone);
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 6533fc60e5..c8bf1f57a2 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 9dd8c6a344..6897e02acd 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, EventBus eventBus,
String region, String availableZone) {
+ super(addresses, region, availableZone);
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 71e5deedaf..fdb7a23922 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
@@ -39,7 +39,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);
@@ -63,7 +63,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 52db799f90..3c5d6214be 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,6 +17,7 @@
package org.apache.servicecomb.http.client.common;
+import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -29,6 +30,7 @@ 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 +44,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 +80,63 @@ 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());
+ }
+ }
+ }
+
+ private boolean regionAndAZMatch(String ownRegion, String ownAvailableZone,
String engineRegion,
+ String engineAvailableZone) {
+ return ownRegion.equalsIgnoreCase(engineRegion) &&
ownAvailableZone.equals(engineAvailableZone);
+ }
+
+ 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;
}
@@ -271,4 +323,26 @@ 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;
+ }
}
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 da87892929..507d8d1c55 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,17 +18,21 @@
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;
import org.apache.http.util.EntityUtils;
import org.apache.servicecomb.foundation.auth.SignRequest;
import org.apache.servicecomb.http.client.auth.RequestAuthHeaderProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Created by on 2019/10/16.
*/
public class HttpTransportImpl implements HttpTransport {
+ private static final Logger LOGGER =
LoggerFactory.getLogger(HttpTransportImpl.class);
private static final String HEADER_CONTENT_TYPE = "Content-Type";
@@ -87,7 +91,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 +102,16 @@ 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) {
+ LOGGER.error("create signRequest failed!", 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 62274519ea..69896f750e 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 b831d03249..b14d6827cb 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 a5fd128ab1..b19db919e8 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, EventBus eventBus, String region,
+ String availableZone) {
+ super(projectName, addresses, region, availableZone);
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 407fb28ac9..97aeaa9931 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 final ServiceCenterAddressManager addressManager;
public ServiceCenterClient(ServiceCenterRawClient httpClient,
ServiceCenterAddressManager addressManager) {
@@ -86,8 +83,8 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
}
public ServiceCenterClient setEventBus(EventBus eventBus) {
- this.eventBus = eventBus;
addressManager.setEventBus(eventBus);
+ this.httpClient.setEventBus(eventBus);
return this;
}
@@ -126,7 +123,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()
@@ -147,7 +143,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()
@@ -165,7 +160,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()
@@ -190,7 +184,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());
@@ -213,7 +206,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()
@@ -235,7 +227,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()
@@ -276,7 +267,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()
@@ -295,7 +285,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()
@@ -316,7 +305,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()
@@ -336,7 +324,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()
@@ -356,7 +343,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()
@@ -375,7 +361,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());
@@ -395,7 +380,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());
@@ -420,7 +404,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()
@@ -447,7 +430,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()
@@ -467,7 +449,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()
@@ -490,7 +471,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()
@@ -510,7 +490,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()
@@ -521,18 +500,12 @@ 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));
+ .postHttpRequestAbsoluteUrl("/v4/token", null,
HttpUtils.serialize(request), queryAddress);
if (response.getStatusCode() == HttpStatus.SC_OK) {
RbacTokenResponse result =
HttpUtils.deserialize(response.getContent(), RbacTokenResponse.class);
result.setStatusCode(HttpStatus.SC_OK);
@@ -573,7 +546,6 @@ public class ServiceCenterClient implements
ServiceCenterOperation {
if (response.getStatusCode() == HttpStatus.SC_OK) {
return true;
}
- sendUnAuthorizedEvent(response);
throw new OperationException(
"update service properties 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 c80e4933a0..fd39a4ce96 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
@@ -184,7 +184,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 a8dc9963b7..e233f15fb5 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;
@@ -48,37 +55,40 @@ public class ServiceCenterRawClient {
this.addressManager = addressManager;
}
+ public void setEventBus(EventBus eventBus) {
+ this.eventBus = eventBus;
+ }
+
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)
- throws IOException {
- return doHttpRequest(url, true, headers, content, HttpRequest.POST);
+ public HttpResponse postHttpRequestAbsoluteUrl(String url, Map<String,
String> headers, String content,
+ String address) throws IOException {
+ 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 +97,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 +108,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);
}
diff --git
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRegistration.java
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRegistration.java
index 7f453834b8..93988ea894 100644
---
a/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRegistration.java
+++
b/clients/service-center-client/src/main/java/org/apache/servicecomb/service/center/client/ServiceCenterRegistration.java
@@ -301,7 +301,7 @@ public class ServiceCenterRegistration extends AbstractTask
{
if (failedCount == 2) {
LOGGER.error("send heart failed, and will try again.", e);
} else {
- LOGGER.warn("send heart failed, and will try again. message [{}]",
e.getCause().getMessage());
+ LOGGER.warn("send heart failed, and will try again. message [{}]",
e.getMessage());
}
eventBus.post(new HeartBeatEvent(false, microservice,
microserviceInstance));
startTask(new BackOffSleepTask(failedCount + 1, new
SendHeartBeatTask(failedCount + 1)));
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 a68a73a49c..9f24a74a55 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,6 +17,7 @@
package org.apache.servicecomb.service.center.client;
+import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
@@ -24,6 +25,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+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;
@@ -108,7 +110,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,
@@ -122,6 +124,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 f5c316cd84..a2888cfad1 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/ServiceCenterClientTest.java
b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterClientTest.java
index 6143953f3d..c486b2bd6c 100755
---
a/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterClientTest.java
+++
b/clients/service-center-client/src/test/java/org/apache/servicecomb/service/center/client/ServiceCenterClientTest.java
@@ -53,7 +53,7 @@ public class ServiceCenterClientTest {
public ServiceCenterClientTest() {
this.addressManager = new ServiceCenterAddressManager("default",
Arrays.asList("http://127.0.0.1:30100"),
- new EventBus());
+ new EventBus(), "", "");
}
@Test
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 29337e31a4..48f3bd914c 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 50ae96db15..3b11e0582d 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/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterDynamicPropertiesSource.java
b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterDynamicPropertiesSource.java
index d1130317ec..23c0a7af19 100644
---
a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterDynamicPropertiesSource.java
+++
b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/cc/ConfigCenterDynamicPropertiesSource.java
@@ -69,7 +69,7 @@ public class ConfigCenterDynamicPropertiesSource implements
DynamicPropertiesSou
ConfigCenterConfig configCenterConfig = new
ConfigCenterConfig(environment);
configConverter = new ConfigConverter(configCenterConfig.getFileSources());
- ConfigCenterAddressManager configCenterAddressManager =
configCenterAddressManager(configCenterConfig);
+ ConfigCenterAddressManager configCenterAddressManager =
configCenterAddressManager(configCenterConfig, environment);
HttpTransport httpTransport =
createHttpTransport(configCenterAddressManager,
buildRequestConfig(configCenterConfig), environment,
configCenterConfig);
@@ -176,16 +176,18 @@ public class ConfigCenterDynamicPropertiesSource
implements DynamicPropertiesSou
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 ConfigCenterAddressManager
configCenterAddressManager(ConfigCenterConfig configCenterConfig) {
+ private ConfigCenterAddressManager
configCenterAddressManager(ConfigCenterConfig configCenterConfig, Environment
environment) {
+ String region = environment.getProperty("servicecomb.datacenter.region");
+ String availableZone =
environment.getProperty("servicecomb.datacenter.availableZone");
return new ConfigCenterAddressManager(configCenterConfig.getDomainName(),
- configCenterConfig.getServerUri(),
- EventManager.getEventBus());
+ configCenterConfig.getServerUri(), EventManager.getEventBus(), region,
availableZone);
}
@Override
diff --git
a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterAddressManagerTest.java
b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterAddressManagerTest.java
index 1642d11ff5..50d39bc19d 100644
---
a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterAddressManagerTest.java
+++
b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterAddressManagerTest.java
@@ -41,8 +41,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);
@@ -71,7 +71,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-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterConfigurationSourceImplTest.java
b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterConfigurationSourceImplTest.java
index f9424c9a2f..3298d95bb1 100644
---
a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/ConfigCenterConfigurationSourceImplTest.java
+++
b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/cc/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-kie/src/main/java/org/apache/servicecomb/config/kie/KieDynamicPropertiesSource.java
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieDynamicPropertiesSource.java
index e9819f6746..6683b84fb0 100644
---
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieDynamicPropertiesSource.java
+++
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/KieDynamicPropertiesSource.java
@@ -71,7 +71,7 @@ public class KieDynamicPropertiesSource implements
DynamicPropertiesSource {
private void init(Environment environment) {
KieConfig kieConfig = new KieConfig(environment);
configConverter = new ConfigConverter(kieConfig.getFileSources());
- KieAddressManager kieAddressManager = configKieAddressManager(kieConfig);
+ KieAddressManager kieAddressManager = configKieAddressManager(kieConfig,
environment);
RequestConfig.Builder requestBuilder =
buildRequestConfigBuilder(kieConfig);
if (kieConfig.enableLongPolling()
@@ -161,15 +161,18 @@ public class KieDynamicPropertiesSource implements
DynamicPropertiesSource {
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(KieConfig kieConfig) {
+ private KieAddressManager configKieAddressManager(KieConfig kieConfig,
Environment environment) {
+ String region = environment.getProperty("servicecomb.datacenter.region");
+ String availableZone =
environment.getProperty("servicecomb.datacenter.availableZone");
return new KieAddressManager(
- Arrays.asList(kieConfig.getServerUri().split(",")),
EventManager.getEventBus());
+ Arrays.asList(kieConfig.getServerUri().split(",")),
EventManager.getEventBus(), region, availableZone);
}
@Override
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 313c19ee5b..0e036e21a5 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 cd7d2fc10f..1209d9d853 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
@@ -84,8 +84,10 @@ public class DefaultMonitorDataPublisher implements
MonitorDataPublisher {
if (addresses.isEmpty()) {
throw new IllegalStateException("dashboard address is not configured.");
}
+ String region = environment.getProperty("servicecomb.datacenter.region");
+ String availableZone =
environment.getProperty("servicecomb.datacenter.availableZone");
- return new DashboardAddressManager(addresses, EventManager.getEventBus());
+ return new DashboardAddressManager(addresses, EventManager.getEventBus(),
region, availableZone);
}
private HttpTransport createHttpTransport(DashboardAddressManager
addressManager, RequestConfig requestConfig,
@@ -120,8 +122,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/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/RBACBootStrapService.java
b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/RBACBootStrapService.java
index 7f18cbb612..007e3e56c9 100644
---
a/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/RBACBootStrapService.java
+++
b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/RBACBootStrapService.java
@@ -42,6 +42,7 @@ import
org.apache.servicecomb.http.client.auth.DefaultRequestAuthHeaderProvider;
import
org.apache.servicecomb.http.client.common.HttpConfiguration.SSLProperties;
import org.apache.servicecomb.http.client.common.HttpTransport;
import org.apache.servicecomb.http.client.common.HttpTransportFactory;
+import org.apache.servicecomb.registry.sc.SCClientUtils;
import
org.apache.servicecomb.service.center.client.ServiceCenterAddressManager;
import org.apache.servicecomb.service.center.client.ServiceCenterClient;
import org.apache.servicecomb.service.center.client.ServiceCenterRawClient;
@@ -128,8 +129,8 @@ public class RBACBootStrapService implements
BootStrapService {
}
private ServiceCenterAddressManager createAddressManager(Environment
environment) {
- return new ServiceCenterAddressManager(getProjectName(environment),
- getRBACAddressList(environment), EventManager.getEventBus());
+ return SCClientUtils.createAddressManager(getProjectName(environment),
getRBACAddressList(environment),
+ environment);
}
private SSLProperties createSSLProperties(Environment environment) {
@@ -233,7 +234,7 @@ public class RBACBootStrapService implements
BootStrapService {
}
private List<String> getRBACAddressList(Environment environment) {
- String address = environment.getProperty(RBAC_ADDRESS,
"http://127.0.0.1:30100)");
+ String address = environment.getProperty(RBAC_ADDRESS,
"http://127.0.0.1:30100");
return Arrays.asList(address.split(","));
}
diff --git
a/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenAuthHeaderProvider.java
b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenAuthHeaderProvider.java
index 6698f99f83..19bd550602 100644
---
a/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenAuthHeaderProvider.java
+++
b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/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/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenCacheManager.java
b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenCacheManager.java
index 205f373816..b4510bb423 100644
---
a/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenCacheManager.java
+++
b/huawei-cloud/servicestage/src/main/java/org/apache/servicecomb/huaweicloud/servicestage/TokenCacheManager.java
@@ -17,19 +17,16 @@
package org.apache.servicecomb.huaweicloud.servicestage;
+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;
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.foundation.common.event.EventManager;
-import org.apache.servicecomb.http.client.event.EngineConnectChangedEvent;
-import org.apache.servicecomb.service.center.client.OperationEvents;
+import org.apache.servicecomb.http.client.event.OperationEvents;
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;
@@ -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;
@@ -128,17 +112,17 @@ public final class TokenCacheManager {
}
});
cache = CacheBuilder.newBuilder()
- .maximumSize(1)
+ .maximumSize(10)
.refreshAfterWrite(refreshTime(), TimeUnit.MILLISECONDS)
.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);
}
});
EventManager.getEventBus().register(this);
@@ -147,21 +131,22 @@ public final class TokenCacheManager {
@Subscribe
public void onNotPermittedEvent(OperationEvents.UnAuthorizedOperationEvent
event) {
- this.executorService.submit(() -> {
- if (lastStatusCode == Status.UNAUTHORIZED.getStatusCode() &&
UN_AUTHORIZED_CODE_HALF_OPEN
- .equals(lastErrorCode)) {
- cache.refresh(registryName);
- }
- });
+ 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);
@@ -169,10 +154,7 @@ public final class TokenCacheManager {
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, host);
if (Status.UNAUTHORIZED.getStatusCode() ==
rbacTokenResponse.getStatusCode()
|| Status.FORBIDDEN.getStatusCode() ==
rbacTokenResponse.getStatusCode()) {
@@ -185,8 +167,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 +182,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/registry/sc/SCAddressManager.java
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCAddressManager.java
index c650d068bc..1c8ec27c8a 100644
---
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCAddressManager.java
+++
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCAddressManager.java
@@ -49,14 +49,14 @@ public class SCAddressManager {
private static final Logger LOGGER =
LoggerFactory.getLogger(SCAddressManager.class);
- private boolean initialized = false;
-
private final ServiceCenterClient serviceCenterClient;
private final SCRegistration scRegistration;
private final SCConfigurationProperties configurationProperties;
+ private final Map<String, HashSet<String>> lastEngineEndpointsCache = new
HashMap<>();
+
public SCAddressManager(SCConfigurationProperties configurationProperties,
ServiceCenterClient serviceCenterClient,
SCRegistration scRegistration) {
@@ -68,9 +68,6 @@ public class SCAddressManager {
@Subscribe
public void onHeartBeatEvent(HeartBeatEvent event) {
- if (initialized) {
- return;
- }
if (event.isSuccess() && configurationProperties.isAutoDiscovery()) {
for (Type type : Type.values()) {
initEndPort(type.name());
@@ -79,19 +76,30 @@ public class SCAddressManager {
}
private void initEndPort(String key) {
- List<MicroserviceInstance> instances = findServiceInstance("default",
- key, "0+");
- if ("SERVICECENTER".equals(key) && !instances.isEmpty()) {
- initialized = true;
- }
- Map<String, List<String>> zoneAndRegion =
generateZoneAndRegionAddress(instances);
+ List<MicroserviceInstance> instances = findServiceInstance("default", key,
"0+");
+ HashSet<String> currentEngineEndpoints = new HashSet<>();
+ Map<String, List<String>> zoneAndRegion =
generateZoneAndRegionAddress(instances, currentEngineEndpoints);
if (zoneAndRegion == null) {
return;
}
- EventManager.post(new RefreshEndpointEvent(zoneAndRegion, key));
+ if (isEngineEndpointsChanged(lastEngineEndpointsCache.get(key),
currentEngineEndpoints)) {
+ LOGGER.info("auto discovery service [{}] addresses: [{}]", key,
zoneAndRegion);
+ lastEngineEndpointsCache.put(key, currentEngineEndpoints);
+ EventManager.post(new RefreshEndpointEvent(zoneAndRegion, key));
+ }
+ }
+
+ private boolean isEngineEndpointsChanged(Set<String> lastEngineEndpoints,
Set<String> currentEngineEndpoints) {
+ if (lastEngineEndpoints == null || lastEngineEndpoints.isEmpty()) {
+ return true;
+ }
+ HashSet<String> compareTemp = new HashSet<>(lastEngineEndpoints);
+ compareTemp.removeAll(currentEngineEndpoints);
+ return !compareTemp.isEmpty() || lastEngineEndpoints.size() !=
currentEngineEndpoints.size();
}
- private Map<String, List<String>>
generateZoneAndRegionAddress(List<MicroserviceInstance> instances) {
+ private Map<String, List<String>>
generateZoneAndRegionAddress(List<MicroserviceInstance> instances,
+ HashSet<String> currentEngineEndpoints) {
if (instances.isEmpty()) {
return null;
}
@@ -107,6 +115,7 @@ public class SCAddressManager {
} else {
sameRegion.addAll(microserviceInstance.getEndpoints());
}
+ currentEngineEndpoints.addAll(microserviceInstance.getEndpoints());
}
zoneAndRegion.put("sameZone", new ArrayList<>(sameZone));
zoneAndRegion.put("sameRegion", new ArrayList<>(sameRegion));
diff --git
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCClientUtils.java
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCClientUtils.java
index 4d29de05a2..f9371926a1 100644
---
a/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCClientUtils.java
+++
b/service-registry/registry-service-center/src/main/java/org/apache/servicecomb/registry/sc/SCClientUtils.java
@@ -17,9 +17,12 @@
package org.apache.servicecomb.registry.sc;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
@@ -50,16 +53,62 @@ import org.springframework.core.env.Environment;
public class SCClientUtils {
private static final Logger LOGGER =
LoggerFactory.getLogger(SCClientUtils.class);
- public static ServiceCenterAddressManager
createAddressManager(SCConfigurationProperties discoveryProperties) {
+ // Compatible chassis multi-registration center
+ private static final Map<String, ServiceCenterAddressManager>
serviceAddressManagers = new ConcurrentHashMap<>();
+
+ public static ServiceCenterAddressManager
createAddressManager(SCConfigurationProperties discoveryProperties,
+ Environment environment) {
List<String> addresses =
ConfigUtil.parseArrayValue(discoveryProperties.getAddress());
- LOGGER.info("initialize discovery server={}", addresses);
- return new ServiceCenterAddressManager("default", addresses,
EventManager.getEventBus());
+ return createAddressManager("default", addresses, environment);
+ }
+
+ /**
+ * Ensure that the ServiceCenterAddressManager in the client created for
RBAC authentication and registry discovery
+ * is the same. This ensures that when an error is reported due to the
registry center address being unavailable,
+ * the authentication and registry discovery remain consistent.
+ *
+ * @param projectName projectName
+ * @param addresses engine address
+ * @param environment environment
+ * @return Service Center Address Manager
+ */
+ public static ServiceCenterAddressManager createAddressManager(String
projectName, List<String> addresses,
+ Environment environment) {
+ if (getServiceCenterAddressManager(addresses) == null) {
+ synchronized (SCClientUtils.class) {
+ if (getServiceCenterAddressManager(addresses) == null) {
+ String key = String.join(",", addresses);
+ LOGGER.info("initialize discovery server={}", addresses);
+ String region =
environment.getProperty("servicecomb.datacenter.region");
+ String availableZone =
environment.getProperty("servicecomb.datacenter.availableZone");
+ ServiceCenterAddressManager addressManager = new
ServiceCenterAddressManager(projectName, addresses,
+ EventManager.getEventBus(), region, availableZone);
+ serviceAddressManagers.put(key, addressManager);
+ return addressManager;
+ }
+ }
+ }
+ return getServiceCenterAddressManager(addresses);
+ }
+
+ private static ServiceCenterAddressManager
getServiceCenterAddressManager(List<String> addresses) {
+ String forwardKey = String.join(",", addresses);
+ List<String> tempAddr = new ArrayList<>(addresses);
+ Collections.reverse(tempAddr);
+ String reverseKey = String.join(",", tempAddr);
+ if (serviceAddressManagers.get(forwardKey) != null) {
+ return serviceAddressManagers.get(forwardKey);
+ }
+ if (serviceAddressManagers.get(reverseKey) != null) {
+ return serviceAddressManagers.get(reverseKey);
+ }
+ return null;
}
// add other headers needed for registration by new ServiceCenterClient(...)
public static ServiceCenterClient
serviceCenterClient(SCConfigurationProperties discoveryProperties,
Environment environment) {
- ServiceCenterAddressManager addressManager =
createAddressManager(discoveryProperties);
+ ServiceCenterAddressManager addressManager =
createAddressManager(discoveryProperties, environment);
SSLProperties sslProperties = buildSslProperties(addressManager,
environment);
@@ -135,7 +184,7 @@ public class SCClientUtils {
public static ServiceCenterWatch
serviceCenterWatch(SCConfigurationProperties discoveryProperties,
List<AuthHeaderProvider> authHeaderProviders, Environment environment) {
- ServiceCenterAddressManager addressManager =
createAddressManager(discoveryProperties);
+ ServiceCenterAddressManager addressManager =
createAddressManager(discoveryProperties, environment);
SSLProperties sslProperties = buildSslProperties(addressManager,
environment);
return new ServiceCenterWatch(addressManager, sslProperties,
getRequestAuthHeaderProvider(authHeaderProviders),
"default", new HashMap<>(), EventManager.getEventBus());
@@ -143,8 +192,9 @@ public class SCClientUtils {
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;
};
}