mirror of https://github.com/alibaba/nacos.git
fix(auth): add AI gRPC resource parser and enable auth for MCP/Agent requests (#13827)
Resolves #13824 This commit adds support for authentication of AI-related gRPC requests (AbstractMcpRequest and AbstractAgentRequest) in the Nacos auth module. Key changes: - Implement AiGrpcResourceParser to extract namespace, group and resource name from AI protocol requests. - Register AiGrpcResourceParser under SignType.AI in GrpcProtocolAuthService. - Add comprehensive unit tests using parameterized testing to cover both MCP and Agent request types, including edge cases (null/empty fields). - Fix missing security token refresh in AiGrpcClient by initializing SecurityProxy with scheduled login task. Ensures that all incoming AI gRPC requests are properly authenticated when security is enabled, closing a previous authorization gap.
This commit is contained in:
parent
f1af11a50f
commit
006ffca559
|
@ -16,33 +16,39 @@
|
||||||
|
|
||||||
package com.alibaba.nacos.auth.parser.grpc;
|
package com.alibaba.nacos.auth.parser.grpc;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.ai.constant.AiConstants;
|
||||||
import com.alibaba.nacos.api.ai.remote.request.AbstractAgentRequest;
|
import com.alibaba.nacos.api.ai.remote.request.AbstractAgentRequest;
|
||||||
import com.alibaba.nacos.api.ai.remote.request.AbstractMcpRequest;
|
import com.alibaba.nacos.api.ai.remote.request.AbstractMcpRequest;
|
||||||
import com.alibaba.nacos.api.ai.remote.request.ReleaseAgentCardRequest;
|
import com.alibaba.nacos.api.ai.remote.request.ReleaseAgentCardRequest;
|
||||||
import com.alibaba.nacos.api.ai.remote.request.ReleaseMcpServerRequest;
|
import com.alibaba.nacos.api.ai.remote.request.ReleaseMcpServerRequest;
|
||||||
|
import com.alibaba.nacos.api.common.Constants;
|
||||||
import com.alibaba.nacos.api.remote.request.Request;
|
import com.alibaba.nacos.api.remote.request.Request;
|
||||||
import com.alibaba.nacos.common.utils.StringUtils;
|
import com.alibaba.nacos.common.utils.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ai Grpc resource parser.
|
* AI Grpc resource parser.
|
||||||
*
|
*
|
||||||
* @author xiweng.yy
|
* @author hongye.nhy xiweng.yy
|
||||||
*/
|
*/
|
||||||
public class AiGrpcResourceParser extends AbstractGrpcResourceParser {
|
public class AiGrpcResourceParser extends AbstractGrpcResourceParser {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getNamespaceId(Request request) {
|
protected String getNamespaceId(Request request) {
|
||||||
if (request instanceof AbstractMcpRequest) {
|
String namespaceId = null;
|
||||||
return ((AbstractMcpRequest) request).getNamespaceId();
|
if (request instanceof AbstractMcpRequest) {
|
||||||
|
namespaceId = ((AbstractMcpRequest) request).getNamespaceId();
|
||||||
} else if (request instanceof AbstractAgentRequest) {
|
} else if (request instanceof AbstractAgentRequest) {
|
||||||
return ((AbstractAgentRequest) request).getNamespaceId();
|
namespaceId = ((AbstractAgentRequest) request).getNamespaceId();
|
||||||
}
|
}
|
||||||
return StringUtils.EMPTY;
|
if (StringUtils.isBlank(namespaceId)) {
|
||||||
|
namespaceId = AiConstants.Mcp.MCP_DEFAULT_NAMESPACE;
|
||||||
|
}
|
||||||
|
return namespaceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getGroup(Request request) {
|
protected String getGroup(Request request) {
|
||||||
return StringUtils.EMPTY;
|
return Constants.DEFAULT_GROUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
package com.alibaba.nacos.auth;
|
package com.alibaba.nacos.auth;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.ai.remote.request.AbstractAgentRequest;
|
||||||
|
import com.alibaba.nacos.api.ai.remote.request.AbstractMcpRequest;
|
||||||
|
import com.alibaba.nacos.api.common.Constants;
|
||||||
import com.alibaba.nacos.api.config.remote.request.ConfigPublishRequest;
|
import com.alibaba.nacos.api.config.remote.request.ConfigPublishRequest;
|
||||||
import com.alibaba.nacos.api.naming.remote.request.AbstractNamingRequest;
|
import com.alibaba.nacos.api.naming.remote.request.AbstractNamingRequest;
|
||||||
import com.alibaba.nacos.auth.annotation.Secured;
|
import com.alibaba.nacos.auth.annotation.Secured;
|
||||||
|
@ -35,9 +38,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
@ -55,14 +56,20 @@ class GrpcProtocolAuthServiceTest {
|
||||||
|
|
||||||
private AbstractNamingRequest namingRequest;
|
private AbstractNamingRequest namingRequest;
|
||||||
|
|
||||||
|
private AbstractMcpRequest mcpRequest;
|
||||||
|
|
||||||
|
private AbstractAgentRequest agentRequest;
|
||||||
|
|
||||||
private GrpcProtocolAuthService protocolAuthService;
|
private GrpcProtocolAuthService protocolAuthService;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() throws Exception {
|
void setUp() throws Exception {
|
||||||
protocolAuthService = new GrpcProtocolAuthService(authConfig);
|
protocolAuthService = new GrpcProtocolAuthService(authConfig);
|
||||||
protocolAuthService.initialize();
|
protocolAuthService.initialize();
|
||||||
mockConfigRequest();
|
mockConfigRequest();
|
||||||
mockNamingRequest();
|
mockNamingRequest();
|
||||||
|
mockMcpRequest();
|
||||||
|
mockAgentRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mockConfigRequest() {
|
private void mockConfigRequest() {
|
||||||
|
@ -79,6 +86,20 @@ class GrpcProtocolAuthServiceTest {
|
||||||
namingRequest.setGroupName("testNG");
|
namingRequest.setGroupName("testNG");
|
||||||
namingRequest.setServiceName("testS");
|
namingRequest.setServiceName("testS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void mockMcpRequest() {
|
||||||
|
mcpRequest = new AbstractMcpRequest() {
|
||||||
|
};
|
||||||
|
mcpRequest.setNamespaceId("testNNs");
|
||||||
|
mcpRequest.setMcpName("testS");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mockAgentRequest() {
|
||||||
|
agentRequest = new AbstractAgentRequest() {
|
||||||
|
};
|
||||||
|
agentRequest.setNamespaceId("testNNs");
|
||||||
|
agentRequest.setAgentName("testS");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Secured(resource = "testResource")
|
@Secured(resource = "testResource")
|
||||||
|
@ -132,6 +153,30 @@ class GrpcProtocolAuthServiceTest {
|
||||||
assertEquals("testCG", actual.getGroup());
|
assertEquals("testCG", actual.getGroup());
|
||||||
assertNotNull(actual.getProperties());
|
assertNotNull(actual.getProperties());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Secured(signType = SignType.AI)
|
||||||
|
void testParseResourceWithMcpType() throws NoSuchMethodException {
|
||||||
|
Secured secured = getMethodSecure("testParseResourceWithMcpType");
|
||||||
|
Resource actual = protocolAuthService.parseResource(mcpRequest, secured);
|
||||||
|
assertEquals(SignType.AI, actual.getType());
|
||||||
|
assertEquals(mcpRequest.getMcpName(), actual.getName());
|
||||||
|
assertEquals(mcpRequest.getNamespaceId(), actual.getNamespaceId());
|
||||||
|
assertEquals(Constants.DEFAULT_GROUP, actual.getGroup());
|
||||||
|
assertNotNull(actual.getProperties());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Secured(signType = SignType.AI)
|
||||||
|
void testParseResourceWithAgentType() throws NoSuchMethodException {
|
||||||
|
Secured secured = getMethodSecure("testParseResourceWithAgentType");
|
||||||
|
Resource actual = protocolAuthService.parseResource(agentRequest, secured);
|
||||||
|
assertEquals(SignType.AI, actual.getType());
|
||||||
|
assertEquals(agentRequest.getAgentName(), actual.getName());
|
||||||
|
assertEquals(agentRequest.getNamespaceId(), actual.getNamespaceId());
|
||||||
|
assertEquals(Constants.DEFAULT_GROUP, actual.getGroup());
|
||||||
|
assertNotNull(actual.getProperties());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testParseIdentity() {
|
void testParseIdentity() {
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
* Copyright 1999-2021 Alibaba Group Holding Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.alibaba.nacos.auth.parser.grpc;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.ai.constant.AiConstants;
|
||||||
|
import com.alibaba.nacos.api.ai.model.a2a.AgentCard;
|
||||||
|
import com.alibaba.nacos.api.ai.remote.request.AbstractAgentRequest;
|
||||||
|
import com.alibaba.nacos.api.ai.remote.request.AbstractMcpRequest;
|
||||||
|
import com.alibaba.nacos.api.ai.remote.request.ReleaseAgentCardRequest;
|
||||||
|
import com.alibaba.nacos.api.common.Constants;
|
||||||
|
import com.alibaba.nacos.api.naming.remote.request.NotifySubscriberRequest;
|
||||||
|
import com.alibaba.nacos.api.remote.request.Request;
|
||||||
|
import com.alibaba.nacos.auth.annotation.Secured;
|
||||||
|
import com.alibaba.nacos.plugin.auth.api.Resource;
|
||||||
|
import com.alibaba.nacos.plugin.auth.constant.SignType;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
class AiGrpcResourceParserTest {
|
||||||
|
|
||||||
|
private AiGrpcResourceParser resourceParser;
|
||||||
|
|
||||||
|
private static Stream<Arguments> fulContextRequests() {
|
||||||
|
Arguments case1 = Arguments.of(mockMcpRequest("testNs", "testName"), "testNs", "testName",
|
||||||
|
MockMcpRequest.class.getSimpleName());
|
||||||
|
Arguments case2 = Arguments.of(mockAgentRequest("testNs", "testName"), "testNs", "testName",
|
||||||
|
MockAgentRequest.class.getSimpleName());
|
||||||
|
Arguments case3 = Arguments.of(makeReleaseAgentCardRequest("testNs", "testName", "testCardName"), "testNs", "testCardName",
|
||||||
|
ReleaseAgentCardRequest.class.getSimpleName());
|
||||||
|
Arguments case4 = Arguments.of(mockOtherRequest("testNs", "testName"),
|
||||||
|
AiConstants.Mcp.MCP_DEFAULT_NAMESPACE, "", NotifySubscriberRequest.class.getSimpleName());
|
||||||
|
return Stream.of(case1, case2, case3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<Arguments> withoutNamespaceRequests() {
|
||||||
|
Arguments case1 = Arguments.of(mockMcpRequest("", "testName"),
|
||||||
|
AiConstants.Mcp.MCP_DEFAULT_NAMESPACE, "testName", MockMcpRequest.class.getSimpleName());
|
||||||
|
Arguments case2 = Arguments.of(mockAgentRequest(null, "testName"),
|
||||||
|
AiConstants.Mcp.MCP_DEFAULT_NAMESPACE, "testName", MockAgentRequest.class.getSimpleName());
|
||||||
|
Arguments case3 = Arguments.of(mockOtherRequest(null, "testName"),
|
||||||
|
AiConstants.Mcp.MCP_DEFAULT_NAMESPACE, "", NotifySubscriberRequest.class.getSimpleName());
|
||||||
|
return Stream.of(case1, case2, case3);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Stream<Arguments> withoutNameRequests() {
|
||||||
|
Arguments case1 = Arguments.of(mockMcpRequest("testNs", ""), "testNs", "",
|
||||||
|
MockMcpRequest.class.getSimpleName());
|
||||||
|
Arguments case2 = Arguments.of(mockAgentRequest("testNs", null), "testNs", "",
|
||||||
|
MockAgentRequest.class.getSimpleName());
|
||||||
|
Arguments case3 = Arguments.of(mockOtherRequest("testNs", ""),
|
||||||
|
AiConstants.Mcp.MCP_DEFAULT_NAMESPACE, "", NotifySubscriberRequest.class.getSimpleName());
|
||||||
|
return Stream.of(case1, case2, case3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() throws Exception {
|
||||||
|
resourceParser = new AiGrpcResourceParser();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource({"fulContextRequests", "withoutNamespaceRequests", "withoutNameRequests"})
|
||||||
|
@Secured(signType = SignType.AI)
|
||||||
|
void testParse(Request request, String expectedNamespaceId, String expectedName, String expectedRequestClassName) throws NoSuchMethodException {
|
||||||
|
Secured secured = getMethodSecure();
|
||||||
|
Resource actual = resourceParser.parse(request, secured);
|
||||||
|
assertEquals(expectedNamespaceId, actual.getNamespaceId());
|
||||||
|
assertEquals(Constants.DEFAULT_GROUP, actual.getGroup());
|
||||||
|
assertEquals(expectedName, actual.getName());
|
||||||
|
assertEquals(SignType.AI, actual.getType());
|
||||||
|
assertEquals(expectedRequestClassName, actual.getProperties()
|
||||||
|
.getProperty(com.alibaba.nacos.plugin.auth.constant.Constants.Resource.REQUEST_CLASS));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AbstractMcpRequest mockMcpRequest(String testNs, String testS) {
|
||||||
|
MockMcpRequest result = new MockMcpRequest();
|
||||||
|
result.setNamespaceId(testNs);
|
||||||
|
result.setMcpName(testS);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MockAgentRequest mockAgentRequest(String testNs, String testS) {
|
||||||
|
MockAgentRequest result = new MockAgentRequest();
|
||||||
|
result.setNamespaceId(testNs);
|
||||||
|
result.setAgentName(testS);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReleaseAgentCardRequest makeReleaseAgentCardRequest(String testNs, String agentName, String cardName) {
|
||||||
|
ReleaseAgentCardRequest result = new ReleaseAgentCardRequest();
|
||||||
|
result.setNamespaceId(testNs);
|
||||||
|
result.setAgentName(agentName);
|
||||||
|
AgentCard agentCard = new AgentCard();
|
||||||
|
agentCard.setName(cardName);
|
||||||
|
result.setAgentCard(agentCard);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Request mockOtherRequest(String testNs, String testS) {
|
||||||
|
NotifySubscriberRequest result = new NotifySubscriberRequest();
|
||||||
|
result.setNamespace(testNs);
|
||||||
|
result.setGroupName("");
|
||||||
|
result.setServiceName(testS);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Secured(signType = SignType.AI)
|
||||||
|
void forSecureAnnotationMethod() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Secured getMethodSecure() throws NoSuchMethodException {
|
||||||
|
Method method = AiGrpcResourceParserTest.class.getDeclaredMethod("forSecureAnnotationMethod");
|
||||||
|
return method.getAnnotation(Secured.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MockMcpRequest extends AbstractMcpRequest {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MockAgentRequest extends AbstractAgentRequest {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -57,6 +57,7 @@ import com.alibaba.nacos.client.naming.core.NamingServerListManager;
|
||||||
import com.alibaba.nacos.client.naming.remote.http.NamingHttpClientManager;
|
import com.alibaba.nacos.client.naming.remote.http.NamingHttpClientManager;
|
||||||
import com.alibaba.nacos.client.security.SecurityProxy;
|
import com.alibaba.nacos.client.security.SecurityProxy;
|
||||||
import com.alibaba.nacos.client.utils.AppNameUtils;
|
import com.alibaba.nacos.client.utils.AppNameUtils;
|
||||||
|
import com.alibaba.nacos.common.executor.NameThreadFactory;
|
||||||
import com.alibaba.nacos.common.lifecycle.Closeable;
|
import com.alibaba.nacos.common.lifecycle.Closeable;
|
||||||
import com.alibaba.nacos.common.remote.ConnectionType;
|
import com.alibaba.nacos.common.remote.ConnectionType;
|
||||||
import com.alibaba.nacos.common.remote.client.RpcClient;
|
import com.alibaba.nacos.common.remote.client.RpcClient;
|
||||||
|
@ -64,13 +65,19 @@ import com.alibaba.nacos.common.remote.client.RpcClientConfigFactory;
|
||||||
import com.alibaba.nacos.common.remote.client.RpcClientFactory;
|
import com.alibaba.nacos.common.remote.client.RpcClientFactory;
|
||||||
import com.alibaba.nacos.common.remote.client.grpc.GrpcClientConfig;
|
import com.alibaba.nacos.common.remote.client.grpc.GrpcClientConfig;
|
||||||
import com.alibaba.nacos.common.utils.StringUtils;
|
import com.alibaba.nacos.common.utils.StringUtils;
|
||||||
|
import com.alibaba.nacos.common.utils.ThreadUtils;
|
||||||
import com.alibaba.nacos.plugin.auth.api.RequestResource;
|
import com.alibaba.nacos.plugin.auth.api.RequestResource;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static com.alibaba.nacos.client.constant.Constants.Security.SECURITY_INFO_REFRESH_INTERVAL_MILLS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nacos AI GRPC protocol client.
|
* Nacos AI GRPC protocol client.
|
||||||
|
@ -92,13 +99,17 @@ public class AiGrpcClient implements Closeable {
|
||||||
private final AbstractServerListManager serverListManager;
|
private final AbstractServerListManager serverListManager;
|
||||||
|
|
||||||
private final AiGrpcRedoService redoService;
|
private final AiGrpcRedoService redoService;
|
||||||
|
|
||||||
|
private final NacosClientProperties properties;
|
||||||
|
|
||||||
private SecurityProxy securityProxy;
|
private SecurityProxy securityProxy;
|
||||||
|
|
||||||
private NacosMcpServerCacheHolder mcpServerCacheHolder;
|
private NacosMcpServerCacheHolder mcpServerCacheHolder;
|
||||||
|
|
||||||
private NacosAgentCardCacheHolder agentCardCacheHolder;
|
private NacosAgentCardCacheHolder agentCardCacheHolder;
|
||||||
|
|
||||||
|
private ScheduledThreadPoolExecutor executorService;
|
||||||
|
|
||||||
public AiGrpcClient(String namespaceId, NacosClientProperties properties) {
|
public AiGrpcClient(String namespaceId, NacosClientProperties properties) {
|
||||||
this.namespaceId = namespaceId;
|
this.namespaceId = namespaceId;
|
||||||
this.uuid = UUID.randomUUID().toString();
|
this.uuid = UUID.randomUUID().toString();
|
||||||
|
@ -106,6 +117,7 @@ public class AiGrpcClient implements Closeable {
|
||||||
this.rpcClient = buildRpcClient(properties);
|
this.rpcClient = buildRpcClient(properties);
|
||||||
this.serverListManager = new NamingServerListManager(properties, namespaceId);
|
this.serverListManager = new NamingServerListManager(properties, namespaceId);
|
||||||
this.redoService = new AiGrpcRedoService(properties, this);
|
this.redoService = new AiGrpcRedoService(properties, this);
|
||||||
|
this.properties = properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RpcClient buildRpcClient(NacosClientProperties properties) {
|
private RpcClient buildRpcClient(NacosClientProperties properties) {
|
||||||
|
@ -133,6 +145,16 @@ public class AiGrpcClient implements Closeable {
|
||||||
this.rpcClient.start();
|
this.rpcClient.start();
|
||||||
this.securityProxy = new SecurityProxy(this.serverListManager,
|
this.securityProxy = new SecurityProxy(this.serverListManager,
|
||||||
NamingHttpClientManager.getInstance().getNacosRestTemplate());
|
NamingHttpClientManager.getInstance().getNacosRestTemplate());
|
||||||
|
initSecurityProxy(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initSecurityProxy(NacosClientProperties properties) {
|
||||||
|
this.executorService = new ScheduledThreadPoolExecutor(1,
|
||||||
|
new NameThreadFactory("com.alibaba.nacos.client.ai.security"));
|
||||||
|
final Properties nacosClientPropertiesView = properties.asProperties();
|
||||||
|
this.securityProxy.login(nacosClientPropertiesView);
|
||||||
|
this.executorService.scheduleWithFixedDelay(() -> securityProxy.login(nacosClientPropertiesView), 0,
|
||||||
|
SECURITY_INFO_REFRESH_INTERVAL_MILLS, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -542,5 +564,8 @@ public class AiGrpcClient implements Closeable {
|
||||||
if (null != securityProxy) {
|
if (null != securityProxy) {
|
||||||
securityProxy.shutdown();
|
securityProxy.shutdown();
|
||||||
}
|
}
|
||||||
|
if (null != executorService) {
|
||||||
|
ThreadUtils.shutdownThreadPool(executorService, LOGGER);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue