Skip to content

Commit d77a009

Browse files
moriadryralf0131
authored andcommitted
[Dubbo-3846] Support nacos metadata (#4025)
1 parent 175eab1 commit d77a009

File tree

9 files changed

+356
-0
lines changed

9 files changed

+356
-0
lines changed

dubbo-all/pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,13 @@
485485
<scope>compile</scope>
486486
<optional>true</optional>
487487
</dependency>
488+
<dependency>
489+
<groupId>org.apache.dubbo</groupId>
490+
<artifactId>dubbo-metadata-report-nacos</artifactId>
491+
<version>${project.version}</version>
492+
<scope>compile</scope>
493+
<optional>true</optional>
494+
</dependency>
488495

489496
<!-- Transitive dependencies -->
490497
<dependency>
@@ -613,6 +620,7 @@
613620
<include>org.apache.dubbo:dubbo-metadata-report-zookeeper</include>
614621
<include>org.apache.dubbo:dubbo-metadata-report-consul</include>
615622
<include>org.apache.dubbo:dubbo-metadata-report-etcd</include>
623+
<include>org.apache.dubbo:dubbo-metadata-report-nacos</include>
616624
<include>org.apache.dubbo:dubbo-serialization-native-hession</include>
617625
<include>org.apache.dubbo:dubbo-rpc-native-thrift</include>
618626
</includes>

dubbo-bom/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,11 @@
382382
<artifactId>dubbo-metadata-report-etcd</artifactId>
383383
<version>${project.version}</version>
384384
</dependency>
385+
<dependency>
386+
<groupId>org.apache.dubbo</groupId>
387+
<artifactId>dubbo-metadata-report-nacos</artifactId>
388+
<version>${project.version}</version>
389+
</dependency>
385390
<dependency>
386391
<groupId>org.apache.dubbo</groupId>
387392
<artifactId>dubbo-configcenter-api</artifactId>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Licensed to the Apache Software Foundation (ASF) under one or more
4+
~ contributor license agreements. See the NOTICE file distributed with
5+
~ this work for additional information regarding copyright ownership.
6+
~ The ASF licenses this file to You under the Apache License, Version 2.0
7+
~ (the "License"); you may not use this file except in compliance with
8+
~ the License. You may obtain a copy of the License at
9+
~
10+
~ http://www.apache.org/licenses/LICENSE-2.0
11+
~
12+
~ Unless required by applicable law or agreed to in writing, software
13+
~ distributed under the License is distributed on an "AS IS" BASIS,
14+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
~ See the License for the specific language governing permissions and
16+
~ limitations under the License.
17+
-->
18+
19+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
20+
<parent>
21+
<artifactId>dubbo-metadata-report</artifactId>
22+
<groupId>org.apache.dubbo</groupId>
23+
<version>${revision}</version>
24+
</parent>
25+
<modelVersion>4.0.0</modelVersion>
26+
27+
<artifactId>dubbo-metadata-report-nacos</artifactId>
28+
29+
<dependencies>
30+
<dependency>
31+
<groupId>org.apache.dubbo</groupId>
32+
<artifactId>dubbo-metadata-report-api</artifactId>
33+
<version>${project.parent.version}</version>
34+
</dependency>
35+
<dependency>
36+
<groupId>com.alibaba.nacos</groupId>
37+
<artifactId>nacos-client</artifactId>
38+
</dependency>
39+
</dependencies>
40+
41+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dubbo.metadata.store.nacos;
19+
20+
import com.alibaba.nacos.api.NacosFactory;
21+
import com.alibaba.nacos.api.config.ConfigService;
22+
import com.alibaba.nacos.api.exception.NacosException;
23+
import org.apache.dubbo.common.URL;
24+
import org.apache.dubbo.common.logger.Logger;
25+
import org.apache.dubbo.common.logger.LoggerFactory;
26+
import org.apache.dubbo.common.utils.StringUtils;
27+
import org.apache.dubbo.metadata.identifier.MetadataIdentifier;
28+
import org.apache.dubbo.metadata.support.AbstractMetadataReport;
29+
import org.apache.dubbo.rpc.RpcException;
30+
31+
import java.util.Properties;
32+
33+
import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
34+
import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
35+
import static com.alibaba.nacos.api.PropertyKeyConst.ACCESS_KEY;
36+
import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT;
37+
import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE;
38+
import static com.alibaba.nacos.api.PropertyKeyConst.CLUSTER_NAME;
39+
import static com.alibaba.nacos.client.naming.utils.UtilAndComs.NACOS_NAMING_LOG_NAME;
40+
import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
41+
42+
/**
43+
* metadata report impl for nacos
44+
*/
45+
public class NacosMetadataReport extends AbstractMetadataReport {
46+
private static final Logger logger = LoggerFactory.getLogger(NacosMetadataReport.class);
47+
private ConfigService configService;
48+
49+
public NacosMetadataReport(URL url) {
50+
super(url);
51+
this.configService = buildConfigService(url);
52+
}
53+
54+
public ConfigService buildConfigService(URL url) {
55+
Properties nacosProperties = buildNacosProperties(url);
56+
try {
57+
configService = NacosFactory.createConfigService(nacosProperties);
58+
} catch (NacosException e) {
59+
if (logger.isErrorEnabled()) {
60+
logger.error(e.getErrMsg(), e);
61+
}
62+
throw new IllegalStateException(e);
63+
}
64+
return configService;
65+
}
66+
67+
private Properties buildNacosProperties(URL url) {
68+
Properties properties = new Properties();
69+
setServerAddr(url, properties);
70+
setProperties(url, properties);
71+
return properties;
72+
}
73+
74+
private void setServerAddr(URL url, Properties properties) {
75+
StringBuilder serverAddrBuilder =
76+
new StringBuilder(url.getHost()) // Host
77+
.append(":")
78+
.append(url.getPort()); // Port
79+
// Append backup parameter as other servers
80+
String backup = url.getParameter(BACKUP_KEY);
81+
if (backup != null) {
82+
serverAddrBuilder.append(",").append(backup);
83+
}
84+
String serverAddr = serverAddrBuilder.toString();
85+
properties.put(SERVER_ADDR, serverAddr);
86+
}
87+
88+
private void setProperties(URL url, Properties properties) {
89+
putPropertyIfAbsent(url, properties, NAMESPACE);
90+
putPropertyIfAbsent(url, properties, NACOS_NAMING_LOG_NAME);
91+
putPropertyIfAbsent(url, properties, ENDPOINT);
92+
putPropertyIfAbsent(url, properties, ACCESS_KEY);
93+
putPropertyIfAbsent(url, properties, SECRET_KEY);
94+
putPropertyIfAbsent(url, properties, CLUSTER_NAME);
95+
}
96+
97+
private void putPropertyIfAbsent(URL url, Properties properties, String propertyName) {
98+
String propertyValue = url.getParameter(propertyName);
99+
if (StringUtils.isNotEmpty(propertyValue)) {
100+
properties.setProperty(propertyName, propertyValue);
101+
}
102+
}
103+
104+
@Override
105+
protected void doStoreProviderMetadata(MetadataIdentifier providerMetadataIdentifier, String serviceDefinitions) {
106+
this.storeMetadata(providerMetadataIdentifier, serviceDefinitions);
107+
}
108+
109+
@Override
110+
protected void doStoreConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, String value) {
111+
this.storeMetadata(consumerMetadataIdentifier, value);
112+
}
113+
114+
private void storeMetadata(MetadataIdentifier identifier, String value) {
115+
try {
116+
boolean publishResult = configService.publishConfig(identifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY), identifier.getGroup(), value);
117+
if (!publishResult) {
118+
throw new RuntimeException("publish nacos metadata failed");
119+
}
120+
} catch (Throwable t) {
121+
logger.error("Failed to put " + identifier + " to nacos " + value + ", cause: " + t.getMessage(), t);
122+
throw new RpcException("Failed to put " + identifier + " to nacos " + value + ", cause: " + t.getMessage(), t);
123+
}
124+
}
125+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dubbo.metadata.store.nacos;
19+
20+
import org.apache.dubbo.common.URL;
21+
import org.apache.dubbo.metadata.store.MetadataReport;
22+
import org.apache.dubbo.metadata.support.AbstractMetadataReportFactory;
23+
24+
/**
25+
* metadata report factory impl for nacos
26+
*/
27+
public class NacosMetadataReportFactory extends AbstractMetadataReportFactory {
28+
@Override
29+
protected MetadataReport createMetadataReport(URL url) {
30+
return new NacosMetadataReport(url);
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nacos=org.apache.dubbo.metadata.store.nacos.NacosMetadataReportFactory
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.dubbo.metadata.store.nacos;
19+
20+
/**
21+
* Test interface for Nacos metadata report
22+
*/
23+
public interface NacosMetadata4TstService {
24+
25+
int getCounter();
26+
27+
void printResult(String var);
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.dubbo.metadata.store.nacos;
18+
19+
import com.alibaba.nacos.api.config.ConfigService;
20+
import com.google.gson.Gson;
21+
import org.apache.dubbo.common.Constants;
22+
import org.apache.dubbo.common.URL;
23+
import org.apache.dubbo.common.utils.NetUtils;
24+
import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
25+
import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
26+
import org.apache.dubbo.metadata.identifier.MetadataIdentifier;
27+
import org.junit.jupiter.api.AfterEach;
28+
import org.junit.jupiter.api.Assertions;
29+
import org.junit.jupiter.api.BeforeEach;
30+
import org.junit.jupiter.api.Test;
31+
import org.junit.jupiter.api.Disabled;
32+
33+
import java.util.HashMap;
34+
import java.util.Map;
35+
36+
import static org.apache.dubbo.common.constants.RegistryConstants.SESSION_TIMEOUT_KEY;
37+
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
38+
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
39+
40+
@Disabled
41+
public class NacosMetadataReportTest {
42+
private static final String TEST_SERVICE = "org.apache.dubbo.metadata.store.nacos.NacosMetadata4TstService";
43+
private NacosMetadataReport nacosMetadataReport;
44+
private NacosMetadataReportFactory nacosMetadataReportFactory;
45+
private ConfigService configService;
46+
47+
@BeforeEach
48+
public void setUp() {
49+
// timeout in 15 seconds.
50+
URL url = URL.valueOf("nacos://127.0.0.1:8848")
51+
.addParameter(SESSION_TIMEOUT_KEY, 15000);
52+
nacosMetadataReportFactory = new NacosMetadataReportFactory();
53+
this.nacosMetadataReport = (NacosMetadataReport) nacosMetadataReportFactory.createMetadataReport(url);
54+
this.configService = nacosMetadataReport.buildConfigService(url);
55+
}
56+
57+
@AfterEach
58+
public void tearDown() throws Exception {
59+
}
60+
61+
@Test
62+
public void testStoreProvider() throws Exception {
63+
String version = "1.0.0";
64+
String group = null;
65+
String application = "nacos-metdata-report-test";
66+
MetadataIdentifier providerIdentifier =
67+
storeProvider(nacosMetadataReport, TEST_SERVICE, version, group, application);
68+
String serverContent = configService.getConfig(providerIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY), group, 5000L);
69+
Assertions.assertNotNull(serverContent);
70+
71+
Gson gson = new Gson();
72+
FullServiceDefinition fullServiceDefinition = gson.fromJson(serverContent, FullServiceDefinition.class);
73+
Assertions.assertEquals(fullServiceDefinition.getParameters().get("paramTest"), "nacosTest");
74+
}
75+
76+
@Test
77+
public void testStoreConsumer() throws Exception {
78+
String version = "1.0.0";
79+
String group = null;
80+
String application = "nacos-metadata-report-consumer-test";
81+
MetadataIdentifier consumerIdentifier = storeConsumer(nacosMetadataReport, TEST_SERVICE, version, group, application);
82+
83+
String serverContent = configService.getConfig(consumerIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.UNIQUE_KEY), group, 5000L);
84+
Assertions.assertNotNull(serverContent);
85+
Assertions.assertEquals(serverContent, "{\"paramConsumerTest\":\"nacosConsumer\"}");
86+
}
87+
88+
private MetadataIdentifier storeProvider(NacosMetadataReport nacosMetadataReport, String interfaceName, String version,
89+
String group, String application)
90+
throws ClassNotFoundException, InterruptedException {
91+
URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName +
92+
"?paramTest=nacosTest&version=" + version + "&application="
93+
+ application + (group == null ? "" : "&group=" + group));
94+
95+
MetadataIdentifier providerMetadataIdentifier =
96+
new MetadataIdentifier(interfaceName, version, group, PROVIDER_SIDE, application);
97+
Class interfaceClass = Class.forName(interfaceName);
98+
FullServiceDefinition fullServiceDefinition =
99+
ServiceDefinitionBuilder.buildFullDefinition(interfaceClass, url.getParameters());
100+
101+
nacosMetadataReport.storeProviderMetadata(providerMetadataIdentifier, fullServiceDefinition);
102+
Thread.sleep(1000);
103+
return providerMetadataIdentifier;
104+
}
105+
106+
private MetadataIdentifier storeConsumer(NacosMetadataReport nacosMetadataReport, String interfaceName,
107+
String version, String group, String application) throws InterruptedException {
108+
MetadataIdentifier consumerIdentifier = new MetadataIdentifier(interfaceName, version, group, CONSUMER_SIDE, application);
109+
Map<String, String> tmp = new HashMap<>();
110+
tmp.put("paramConsumerTest", "nacosConsumer");
111+
nacosMetadataReport.storeConsumerMetadata(consumerIdentifier, tmp);
112+
Thread.sleep(1000);
113+
return consumerIdentifier;
114+
}
115+
}

dubbo-metadata-report/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<module>dubbo-metadata-definition</module>
3232
<module>dubbo-metadata-report-consul</module>
3333
<module>dubbo-metadata-report-etcd</module>
34+
<module>dubbo-metadata-report-nacos</module>
3435
</modules>
3536

3637

0 commit comments

Comments
 (0)