-
Notifications
You must be signed in to change notification settings - Fork 828
[#5013] Fixing the issue where microservices cannot be registered when enabling RBAC authentication in a dual-engine disaster recovery scenario. #5019
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
874cbd8
9c566de
53d177e
c638be2
8dad6b2
39ae78f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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.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); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. addresses items will duplicate? or else change to Set , if order is not needed
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. need order, and duplicate addresses are acceptable. |
||
| 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()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. toString is not Recommendation, the result will changed when the class field added.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The toString method in URLEndPoint has been overridden, and properties can be added when needed.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the availableZone mean always not changed when URLEndPoint add properties?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. URLEndPoint is just a utility class, the SC address only requires the protocol+ip+port |
||
| } 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 List<String> getIsolationAddresses() { | |
| 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; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 HttpResponse doRequest(HttpRequest httpRequest) throws IOException { | |
| 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 HttpResponse doRequest(HttpRequest httpRequest) throws IOException { | |
| 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; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. log it , when exception
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fixed |
||
| } | ||
| } | ||
|
|
||
| @Override | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
consider https?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Used only to determine whether an protocol is included, not to determine the type of protocol.