jeho0815 closed pull request #565: [SCB-355]If auth failed,sc/cc will not connect server to reduce server pressure URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/565
This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/client/ConfigCenterClient.java b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/client/ConfigCenterClient.java index 0ca5668e9..d059dd53c 100644 --- a/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/client/ConfigCenterClient.java +++ b/dynamic-config/config-cc/src/main/java/org/apache/servicecomb/config/client/ConfigCenterClient.java @@ -108,6 +108,8 @@ private boolean isWatching = false; + private boolean authFailed = false; + private static final ServiceLoader<AuthHeaderProvider> authHeaderProviders = ServiceLoader.load(AuthHeaderProvider.class); @@ -312,6 +314,9 @@ private void sendHeartbeat(WebSocket ws) { } public void refreshConfig(String configcenter) { + if (authFailed) { + return; + } clientMgr.findThreadBindClientPool().runOnContext(client -> { String path = URIConst.ITEMS + "?dimensionsInfo=" + StringUtils.deleteWhitespace(serviceName); IpPort ipPort = NetUtils.parseIpPortFromURI(configcenter); @@ -331,6 +336,10 @@ public void refreshConfig(String configcenter) { }); } else { rsp.bodyHandler(buf -> { + if (rsp.statusCode() == HttpResponseStatus.UNAUTHORIZED.code()) { + LOGGER.error("**Auth fail, maybe ak/sk is error, will not try again***!"); + authFailed = true; + } LOGGER.error("fetch config fail: " + buf); }); EventManager.post(new ConnFailEvent("fetch config fail")); diff --git a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/client/TestConfigCenterClient.java b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/client/TestConfigCenterClient.java index 0f9013c59..8798732a7 100644 --- a/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/client/TestConfigCenterClient.java +++ b/dynamic-config/config-cc/src/test/java/org/apache/servicecomb/config/client/TestConfigCenterClient.java @@ -17,6 +17,7 @@ package org.apache.servicecomb.config.client; +import java.lang.reflect.Field; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -231,4 +232,52 @@ public void runOnContext(RunHandler handler) { refresh.run(); Assert.assertEquals("Succ event trigger", map.get("result")); } + + @SuppressWarnings("unchecked") + @Test + public void testConfigRefreshAuthFail() { + ConfigCenterConfigurationSourceImpl impl = new ConfigCenterConfigurationSourceImpl(); + impl.init(ConfigUtil.createLocalConfig()); + UpdateHandler updateHandler = impl.new UpdateHandler(); + HttpClientRequest request = Mockito.mock(HttpClientRequest.class); + Mockito.when(request.headers()).thenReturn(MultiMap.caseInsensitiveMultiMap()); + Buffer rsp = Mockito.mock(Buffer.class); + Mockito.when(rsp.toString()) + .thenReturn("{\"requestid\":{\"test123\"}"); + + HttpClientResponse event = Mockito.mock(HttpClientResponse.class); + Mockito.when(event.bodyHandler(Mockito.any(Handler.class))).then(invocation -> { + Handler<Buffer> handler = invocation.getArgumentAt(0, Handler.class); + handler.handle(rsp); + return null; + }); + Mockito.when(event.statusCode()).thenReturn(401); + HttpClient httpClient = Mockito.mock(HttpClient.class); + Mockito.when( + httpClient.get(Mockito.anyInt(), Mockito.anyString(), Mockito.anyString(), Mockito.any(Handler.class))) + .then(invocation -> { + Handler<HttpClientResponse> handler = invocation.getArgumentAt(3, Handler.class); + handler.handle(event); + return request; + }); + new MockUp<HttpClientWithContext>() { + @Mock + public void runOnContext(RunHandler handler) { + handler.run(httpClient); + } + }; + ConfigCenterClient cc = new ConfigCenterClient(updateHandler); + ParseConfigUtils parseConfigUtils = new ParseConfigUtils(updateHandler); + MemberDiscovery memberdis = new MemberDiscovery(Arrays.asList("http://configcentertest:30103")); + ConfigRefresh refresh = cc.new ConfigRefresh(parseConfigUtils, memberdis); + refresh.run(); + try { + Field filed = cc.getClass().getDeclaredField("authFailed"); + filed.setAccessible(true); + boolean auth = (boolean) filed.get(cc); + Assert.assertTrue(auth); + } catch (Exception e) { + e.printStackTrace(); + } + } } diff --git a/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java b/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java index d48d0bc07..f0ad4980d 100644 --- a/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java +++ b/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/client/http/ServiceRegistryClientImpl.java @@ -59,6 +59,7 @@ import com.google.common.annotations.VisibleForTesting; +import io.netty.handler.codec.http.HttpResponseStatus; import io.netty.handler.codec.http.HttpStatusClass; import io.vertx.core.Handler; import io.vertx.core.buffer.Buffer; @@ -112,6 +113,17 @@ private void retry(RequestContext requestContext, Handler<RestResponse> response return; } + if (HttpStatusClass.CLIENT_ERROR.equals(HttpStatusClass.valueOf(response.statusCode()))) { + String errorCode = bodyBuffer.toJsonObject().getString("errorCode"); + if (response.statusCode() == HttpResponseStatus.UNAUTHORIZED.code() + || cls.getName().equals(GetExistenceResponse.class.getName()) && "401002".equals(errorCode)) { + GetExistenceResponse resp = new GetExistenceResponse(); + resp.setServiceId("SC_AUTH_FAILED_401002"); + holder.value = (T) resp; + countDownLatch.countDown(); + return; + } + } // no need to support 304 in this place if (!HttpStatusClass.SUCCESS.equals(HttpStatusClass.valueOf(response.statusCode()))) { LOGGER.warn("get response for {} failed, {}:{}, {}", diff --git a/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/task/MicroserviceInstanceRegisterTask.java b/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/task/MicroserviceInstanceRegisterTask.java index 37039b059..acf8bd034 100644 --- a/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/task/MicroserviceInstanceRegisterTask.java +++ b/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/task/MicroserviceInstanceRegisterTask.java @@ -56,6 +56,11 @@ public void onMicroserviceRegisterTask(MicroserviceRegisterTask task) { @Override protected boolean doRegister() { + if (microserviceInstance.getServiceId() == null) { + LOGGER.warn( + "***This instance lack of micro service id, maybe auth failed, please check it***! This time we will not go on."); + return false; + } LOGGER.info("running microservice instance register task."); String hostName = ""; if (serviceRegistryConfig.isPreferIpAddress()) { diff --git a/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/task/MicroserviceRegisterTask.java b/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/task/MicroserviceRegisterTask.java index a0610f4de..dcee3dcdb 100644 --- a/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/task/MicroserviceRegisterTask.java +++ b/service-registry/src/main/java/org/apache/servicecomb/serviceregistry/task/MicroserviceRegisterTask.java @@ -59,6 +59,17 @@ protected boolean doRegister() { microservice.getServiceName(), microservice.getVersion()); if (!StringUtils.isEmpty(serviceId)) { + // if return auth failed code, don't do this task again! + if ("SC_AUTH_FAILED_401002".equals(serviceId)) { + LOGGER.warn( + "***Server auth failed, no need to register***. appId={}, name={}, version={}", + microservice.getAppId(), + microservice.getServiceName(), + microservice.getVersion()); + this.taskStatus = TaskStatus.FINISHED; + this.registered = false; + return false; + } // ?????????????? microservice.setServiceId(serviceId); LOGGER.info( diff --git a/service-registry/src/test/java/org/apache/servicecomb/serviceregistry/client/http/TestServiceRegistryClientImpl.java b/service-registry/src/test/java/org/apache/servicecomb/serviceregistry/client/http/TestServiceRegistryClientImpl.java index 56af6d2bc..1aa5e303e 100644 --- a/service-registry/src/test/java/org/apache/servicecomb/serviceregistry/client/http/TestServiceRegistryClientImpl.java +++ b/service-registry/src/test/java/org/apache/servicecomb/serviceregistry/client/http/TestServiceRegistryClientImpl.java @@ -187,6 +187,56 @@ void doRun(java.util.List<LoggingEvent> events) { }.run(); } + @SuppressWarnings("unchecked") + @Test + public void testRegisterAuthFailedResponse() { + HttpClientResponse response = Mockito.mock(HttpClientResponse.class); + Mockito.when(response.statusCode()).then(invocation -> { + return 400; + }); + Mockito.when(response.bodyHandler(Mockito.any(Handler.class))).then(invocation -> { + Handler<Buffer> handler = invocation.getArgumentAt(0, Handler.class); + Buffer bodyBuffer = Buffer.buffer("{\"errorCode\":\"401002\"}"); + handler.handle(bodyBuffer); + return null; + }); + + new MockUp<RestUtils>() { + @Mock + void httpDo(RequestContext requestContext, Handler<RestResponse> responseHandler) { + responseHandler.handle(new RestResponse(requestContext, response)); + } + }; + + String serviceId = oClient.getMicroserviceId("test", "service", "latest"); + Assert.assertEquals("SC_AUTH_FAILED_401002", serviceId); + } + + @SuppressWarnings("unchecked") + @Test + public void testRegisterAuthFailedResponseAPIGW() { + HttpClientResponse response = Mockito.mock(HttpClientResponse.class); + Mockito.when(response.statusCode()).then(invocation -> { + return 401; + }); + Mockito.when(response.bodyHandler(Mockito.any(Handler.class))).then(invocation -> { + Handler<Buffer> handler = invocation.getArgumentAt(0, Handler.class); + Buffer bodyBuffer = Buffer.buffer("{\"requestid\":\"xxxxx\"}"); + handler.handle(bodyBuffer); + return null; + }); + + new MockUp<RestUtils>() { + @Mock + void httpDo(RequestContext requestContext, Handler<RestResponse> responseHandler) { + responseHandler.handle(new RestResponse(requestContext, response)); + } + }; + + String serviceId = oClient.getMicroserviceId("test", "service", "latest"); + Assert.assertEquals("SC_AUTH_FAILED_401002", serviceId); + } + @Test public void testRegisterSchemaErrorResponse() { new MockUp<ServiceRegistryClientImpl>() { diff --git a/service-registry/src/test/java/org/apache/servicecomb/serviceregistry/task/TestMicroserviceInstanceRegisterTask.java b/service-registry/src/test/java/org/apache/servicecomb/serviceregistry/task/TestMicroserviceInstanceRegisterTask.java index 897e409c9..cd50a0fba 100644 --- a/service-registry/src/test/java/org/apache/servicecomb/serviceregistry/task/TestMicroserviceInstanceRegisterTask.java +++ b/service-registry/src/test/java/org/apache/servicecomb/serviceregistry/task/TestMicroserviceInstanceRegisterTask.java @@ -65,8 +65,9 @@ public void onEvent(MicroserviceInstanceRegisterTask task) { microservice.setAppId("app"); microservice.setServiceName("ms"); microservice.setServiceId("serviceId"); - - microservice.setInstance(new MicroserviceInstance()); + MicroserviceInstance instance = new MicroserviceInstance(); + instance.setServiceId("001"); + microservice.setInstance(instance); HealthCheck healthCheck = new HealthCheck(); healthCheck.setMode(HealthCheckMode.HEARTBEAT); @@ -84,10 +85,23 @@ public void microserviceNotRegistered() { Assert.assertEquals(false, registerTask.isRegistered()); Assert.assertEquals(0, taskList.size()); } + + @Test + public void microserviceInstanceNotExist() { + microservice.getInstance().setServiceId(null); + + MicroserviceInstanceRegisterTask registerTask = + new MicroserviceInstanceRegisterTask(eventBus, serviceRegistryConfig, null, microservice); + registerTask.run(); + + Assert.assertEquals(false, registerTask.isRegistered()); + Assert.assertEquals(0, taskList.size()); + } @Test public void registerIpSuccess() { MicroserviceInstance instance = microservice.getInstance(); + instance.setServiceId("instance001"); new Expectations(RegistryUtils.class) { { RegistryUtils.getPublishAddress(); @@ -118,6 +132,7 @@ public void registerIpSuccess() { @Test public void registerHostSuccess() { MicroserviceInstance instance = microservice.getInstance(); + instance.setServiceId("instance001"); new Expectations(RegistryUtils.class) { { RegistryUtils.getPublishHostName(); @@ -148,6 +163,7 @@ public void registerHostSuccess() { @Test public void registerIpFailed() { MicroserviceInstance instance = microservice.getInstance(); + instance.setServiceId("instance001"); new Expectations(RegistryUtils.class) { { RegistryUtils.getPublishAddress(); diff --git a/service-registry/src/test/java/org/apache/servicecomb/serviceregistry/task/TestMicroserviceRegisterTask.java b/service-registry/src/test/java/org/apache/servicecomb/serviceregistry/task/TestMicroserviceRegisterTask.java index 736b75972..88c08e315 100644 --- a/service-registry/src/test/java/org/apache/servicecomb/serviceregistry/task/TestMicroserviceRegisterTask.java +++ b/service-registry/src/test/java/org/apache/servicecomb/serviceregistry/task/TestMicroserviceRegisterTask.java @@ -78,6 +78,23 @@ public void testNewRegisterFailed(@Mocked ServiceRegistryClient srClient) { Assert.assertEquals(1, taskList.size()); } + @Test + public void testRegisterAuthFailed(@Mocked ServiceRegistryClient srClient) { + new Expectations() { + { + srClient.getMicroserviceId(anyString, anyString, anyString); + result = "SC_AUTH_FAILED_401002"; + } + }; + + MicroserviceRegisterTask registerTask = new MicroserviceRegisterTask(eventBus, srClient, microservice); + registerTask.run(); + + Assert.assertEquals(false, registerTask.isRegistered()); + Assert.assertEquals(TaskStatus.FINISHED, registerTask.getTaskStatus()); + Assert.assertEquals(null, microservice.getServiceId()); + } + @Test public void testNewRegisterSuccess(@Mocked ServiceRegistryClient srClient) { new Expectations() { ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services