Skip to content

Commit 725bb9d

Browse files
fix: copy NacosDiscoveryProperties to avoid sharing mutable state (#4303)
1 parent 1854d61 commit 725bb9d

2 files changed

Lines changed: 151 additions & 1 deletion

File tree

spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosDiscoveryProperties.java

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,50 @@ else if (IPV6.equalsIgnoreCase(ipType)) {
326326
applicationEventPublisher
327327
.publishEvent(new NacosDiscoveryInfoChangedEvent(this));
328328
}
329-
nacosServiceManager.setNacosDiscoveryProperties(this);
329+
nacosServiceManager.setNacosDiscoveryProperties(copyNacosDiscoveryProperties());
330+
}
331+
332+
/**
333+
* copy {@link NacosDiscoveryProperties} .
334+
* @return NacosDiscoveryProperties
335+
*/
336+
private NacosDiscoveryProperties copyNacosDiscoveryProperties() {
337+
NacosDiscoveryProperties nacosDiscoveryProperties = new NacosDiscoveryProperties();
338+
nacosDiscoveryProperties.endpoint = this.endpoint;
339+
nacosDiscoveryProperties.namespace = this.namespace;
340+
nacosDiscoveryProperties.logName = this.logName;
341+
nacosDiscoveryProperties.weight = this.weight;
342+
nacosDiscoveryProperties.clusterName = this.clusterName;
343+
nacosDiscoveryProperties.service = this.service;
344+
nacosDiscoveryProperties.registerEnabled = this.registerEnabled;
345+
nacosDiscoveryProperties.ip = this.ip;
346+
nacosDiscoveryProperties.ipType = this.ipType;
347+
nacosDiscoveryProperties.networkInterface = this.networkInterface;
348+
nacosDiscoveryProperties.port = this.port;
349+
nacosDiscoveryProperties.secure = this.secure;
350+
nacosDiscoveryProperties.metadata = new HashMap<>(this.metadata);
351+
nacosDiscoveryProperties.serverAddr = this.serverAddr;
352+
nacosDiscoveryProperties.accessKey = this.accessKey;
353+
nacosDiscoveryProperties.secretKey = this.secretKey;
354+
nacosDiscoveryProperties.heartBeatInterval = this.heartBeatInterval;
355+
nacosDiscoveryProperties.heartBeatTimeout = this.heartBeatTimeout;
356+
nacosDiscoveryProperties.ipDeleteTimeout = this.ipDeleteTimeout;
357+
nacosDiscoveryProperties.namingLoadCacheAtStart = this.namingLoadCacheAtStart;
358+
nacosDiscoveryProperties.watchDelay = this.watchDelay;
359+
nacosDiscoveryProperties.group = this.group;
360+
nacosDiscoveryProperties.username = this.username;
361+
nacosDiscoveryProperties.password = this.password;
362+
nacosDiscoveryProperties.instanceEnabled = this.instanceEnabled;
363+
nacosDiscoveryProperties.ephemeral = this.ephemeral;
364+
nacosDiscoveryProperties.failureToleranceEnabled = this.failureToleranceEnabled;
365+
nacosDiscoveryProperties.failFast = this.failFast;
366+
nacosDiscoveryProperties.gracefulShutdownWaitTime = this.gracefulShutdownWaitTime;
367+
nacosDiscoveryProperties.inetIPv6Utils = this.inetIPv6Utils;
368+
nacosDiscoveryProperties.inetUtils = this.inetUtils;
369+
nacosDiscoveryProperties.environment = this.environment;
370+
nacosDiscoveryProperties.nacosServiceManager = this.nacosServiceManager;
371+
nacosDiscoveryProperties.applicationEventPublisher = this.applicationEventPublisher;
372+
return nacosDiscoveryProperties;
330373
}
331374

332375
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright 2026-2026 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.alibaba.cloud.nacos;
18+
19+
import java.util.UUID;
20+
21+
import com.alibaba.cloud.nacos.discovery.NacosDiscoveryClientConfiguration;
22+
import com.alibaba.cloud.nacos.event.NacosDiscoveryInfoChangedEvent;
23+
import com.alibaba.cloud.nacos.registry.NacosServiceRegistryAutoConfiguration;
24+
import org.junit.jupiter.api.Test;
25+
26+
import org.springframework.beans.factory.annotation.Autowired;
27+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
28+
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
29+
import org.springframework.boot.test.context.SpringBootTest;
30+
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
31+
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration;
32+
import org.springframework.context.annotation.Configuration;
33+
import org.springframework.context.event.EventListener;
34+
35+
import static com.alibaba.cloud.nacos.NacosDiscoveryPropertiesTests.TestConfig;
36+
import static org.assertj.core.api.Assertions.assertThat;
37+
38+
/**
39+
* @author xuxiaowei
40+
*/
41+
@EnableDiscoveryClient(autoRegister = false)
42+
@SpringBootTest(classes = TestConfig.class,
43+
properties = {
44+
"spring.application.name=app",
45+
"spring.cloud.nacos.discovery.server-addr=321.321.321.321:8848",
46+
"spring.cloud.nacos.server-addr=123.123.123.123:8848" })
47+
class NacosDiscoveryPropertiesTests {
48+
49+
private static final String KEY = UUID.randomUUID().toString();
50+
51+
@Autowired
52+
private NacosDiscoveryProperties properties;
53+
54+
@Test
55+
public void testGetServerAddr() {
56+
assertThat(properties.getServerAddr()).isEqualTo("321.321.321.321:8848");
57+
}
58+
59+
@Test
60+
public void testNacosDiscoveryInfoChangedEvent() throws Exception {
61+
TestConfig.eventPublished = false;
62+
// modify some property
63+
String password = UUID.randomUUID().toString();
64+
String value = UUID.randomUUID().toString();
65+
properties.setPassword(password);
66+
properties.getMetadata().put(KEY, value);
67+
// trigger init
68+
properties.init();
69+
// check if event is published
70+
assertThat(TestConfig.eventPublished).isTrue();
71+
assertThat(TestConfig.password).isEqualTo(password);
72+
assertThat(TestConfig.metadataValue).isEqualTo(value);
73+
}
74+
75+
@Configuration
76+
@EnableAutoConfiguration
77+
@ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class,
78+
NacosDiscoveryClientConfiguration.class,
79+
NacosServiceRegistryAutoConfiguration.class })
80+
public static class TestConfig {
81+
82+
/**
83+
* eventPublished.
84+
*/
85+
public static boolean eventPublished = false;
86+
87+
/**
88+
* password.
89+
*/
90+
public static String password;
91+
92+
/**
93+
* metadataValue.
94+
*/
95+
public static String metadataValue;
96+
97+
@EventListener
98+
public void onEvent(NacosDiscoveryInfoChangedEvent event) {
99+
eventPublished = true;
100+
password = event.getSource().getPassword();
101+
metadataValue = event.getSource().getMetadata().get(KEY);
102+
}
103+
104+
}
105+
106+
}
107+

0 commit comments

Comments
 (0)