This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git


The following commit(s) were added to refs/heads/master by this push:
     new 0f931ba  [SCB-2060]fix nocas configuration not properly handle yaml 
and properties (#1911)
0f931ba is described below

commit 0f931badaa17d393d957170a040c7b1338d8b91f
Author: bao liu <[email protected]>
AuthorDate: Fri Aug 7 16:40:34 2020 +0800

    [SCB-2060]fix nocas configuration not properly handle yaml and properties 
(#1911)
---
 demo/demo-jaxrs/jaxrs-client/pom.xml               |   7 ++
 .../demo/jaxrs/client/TestDynamicConfig.java       | 118 +++++++++++++++++++++
 .../demo/jaxrs/client/TestInvokerUtils.java        |  55 ++++++++++
 .../src/main/resources/microservice.yaml           |  28 ++++-
 .../servicecomb/config/kie/client/KieUtil.java     |  36 ++-----
 .../servicecomb/config/kie/client/TestKieUtil.java |   2 +-
 dynamic-config/config-nacos/README.md              |  41 +------
 .../sources/NacosConfigurationSourceImpl.java      |   4 +-
 .../config/nacos/client/NacosClient.java           |  89 +++++++---------
 .../config/nacos/client/NacosConfig.java           |  32 ++++--
 .../config/nacos/client/NacosClientTest.java       |   2 +-
 .../apache/servicecomb/config/parser/Parser.java   |  71 +++++++++++++
 .../config/parser/PropertiesParser.java            |  41 +++++++
 .../servicecomb/config/parser/RawParser.java       |  30 ++++++
 .../servicecomb/config/parser/YamlParser.java      |  34 ++++++
 .../servicecomb/config/parser/TestParser.java      |  60 +++++++++++
 16 files changed, 518 insertions(+), 132 deletions(-)

diff --git a/demo/demo-jaxrs/jaxrs-client/pom.xml 
b/demo/demo-jaxrs/jaxrs-client/pom.xml
index cc47a59..23a4dfc 100644
--- a/demo/demo-jaxrs/jaxrs-client/pom.xml
+++ b/demo/demo-jaxrs/jaxrs-client/pom.xml
@@ -45,6 +45,13 @@
       <groupId>org.apache.servicecomb</groupId>
       <artifactId>provider-pojo</artifactId>
     </dependency>
+    <!-- can be added in local test -->
+    <!-- This jar will add an environment version={project.version}, and may 
cause spring boot application
+       startup fail -->
+    <!--    <dependency>-->
+    <!--      <groupId>org.apache.servicecomb</groupId>-->
+    <!--      <artifactId>config-nacos</artifactId>-->
+    <!--    </dependency>-->
   </dependencies>
 
   <properties>
diff --git 
a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestDynamicConfig.java
 
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestDynamicConfig.java
new file mode 100644
index 0000000..2f275a2
--- /dev/null
+++ 
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestDynamicConfig.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.demo.jaxrs.client;
+
+import java.util.Arrays;
+
+import org.apache.servicecomb.config.inject.InjectProperties;
+import org.apache.servicecomb.config.inject.InjectProperty;
+import org.apache.servicecomb.core.BootListener;
+import org.apache.servicecomb.core.SCBEngine;
+import org.apache.servicecomb.demo.TestMgr;
+import org.springframework.stereotype.Component;
+
+@Component
+public class TestDynamicConfig implements BootListener {
+
+  @InjectProperties(prefix = "jaxrstest.jaxrsclient")
+  public class Configuration {
+    /*
+     * 方法的 prefix 属性值 "override" 会覆盖标注在类定义的 @InjectProperties
+     * 注解的 prefix 属性值。
+     *
+     * keys属性可以为一个字符串数组,下标越小优先级越高。
+     *
+     * 这里会按照如下顺序的属性名称查找配置属性,直到找到已被配置的配置属性,则停止查找:
+     * 1) jaxrstest.jaxrsclient.override.high
+     * 2) jaxrstest.jaxrsclient.override.low
+     *
+     * 测试用例:
+     * jaxrstest.jaxrsclient.override.high: hello high
+     * jaxrstest.jaxrsclient.override.low: hello low
+     * 预期:
+     * hello high
+     */
+    @InjectProperty(prefix = "jaxrstest.jaxrsclient.override", keys = {"high", 
"low"})
+    public String strValue;
+
+    /**
+     * keys支持通配符,并在可以在将配置属性注入的时候指定通配符的代入对象。
+     *
+     * 测试用例:
+     * jaxrstest.jaxrsclient.k.value: 3
+     * 预期:
+     * 3
+     */
+    @InjectProperty(keys = "${key}.value")
+    public int intValue;
+
+    /**
+     * 通配符的代入对象可以是一个字符串List,优先级遵循数组元素下标越小优先级越高策略。
+     *
+     * 测试用例:
+     * jaxrstest.jaxrsclient.l1-1: 3.0
+     * jaxrstest.jaxrsclient.l1-2: 2.0
+     *
+     * 预期:
+     * 3.0
+     */
+    @InjectProperty(keys = "${full-list}")
+    public float floatValue;
+
+    /**
+     * keys属性也支持多个通配符,优先级如下:首先通配符的优先级从左到右递减,
+     * 然后如果通配符被代入List,遵循List中元素index越小优先级越高策略。
+     *
+     * 测试用例:
+     * jaxrstest.jaxrsclient.low-1.a.high-1.b: 1
+     * jaxrstest.jaxrsclient.low-1.a.high-2.b: 2
+     * jaxrstest.jaxrsclient.low-2.a.high-1.b: 3
+     * jaxrstest.jaxrsclient.low-2.a.high-2.b: 4
+     * 预期:
+     * 1
+     */
+    @InjectProperty(keys = "${low-list}.a.${high-list}.b")
+    public long longValue;
+
+    /**
+     * 可以通过注解的defaultValue属性指定默认值。如果字段未关联任何配置属性,
+     * 定义的默认值会生效,否则默认值会被覆盖。
+     *
+     * 测试用例:
+     * 预期:
+     * abc
+     */
+    @InjectProperty(defaultValue = "abc")
+    public String strDef;
+  }
+
+  public void onAfterRegistry(BootEvent event) {
+    Configuration configuration = 
SCBEngine.getInstance().getPriorityPropertyManager()
+        .createConfigObject(Configuration.class,
+            "key", "k",
+            "low-list", Arrays.asList("low-1", "low-2"),
+            "high-list", Arrays.asList("high-1", "high-2"),
+            "full-list", Arrays.asList("l1-1", "l1-2")
+        );
+    TestMgr.check(configuration.strValue, "hello high");
+    TestMgr.check(configuration.intValue, 3);
+    TestMgr.check(configuration.floatValue, 3.0);
+    TestMgr.check(configuration.longValue, 1);
+    TestMgr.check(configuration.strDef, "abc");
+  }
+}
diff --git 
a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestInvokerUtils.java
 
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestInvokerUtils.java
new file mode 100644
index 0000000..6f1f4d0
--- /dev/null
+++ 
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/TestInvokerUtils.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.demo.jaxrs.client;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.core.provider.consumer.InvokerUtils;
+import org.apache.servicecomb.demo.CategorizedTestCase;
+import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.demo.server.User;
+import org.springframework.stereotype.Component;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+
+@Component
+public class TestInvokerUtils implements CategorizedTestCase {
+  private static final String SERVICE_NAME = "jaxrs";
+
+  private static final String SCHEMA_ID = "codeFirst";
+
+  public void testAllTransport() throws Exception {
+    testCodeFirstJaxrs();
+  }
+
+  // invoke CodeFirstJaxrs
+  private void testCodeFirstJaxrs() {
+    Map<String, Object> swaggerArguments = new HashMap<>();
+    Map<String, User> userMap = new HashMap<>();
+    User user = new User();
+    user.setName("hello");
+    userMap.put("user", user);
+    swaggerArguments.put("userMap", userMap);
+    TypeReference<Map<String, User>> type = new TypeReference<Map<String, 
User>>() {
+    };
+    Map<String, User> result = InvokerUtils.syncInvoke(SERVICE_NAME, 
SCHEMA_ID, "testUserMap", swaggerArguments,
+        type.getType());
+    TestMgr.check(result.get("user").getName(), userMap.get("user").getName());
+  }
+}
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/resources/microservice.yaml 
b/demo/demo-jaxrs/jaxrs-client/src/main/resources/microservice.yaml
index 1559f53..c824285 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/resources/microservice.yaml
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/resources/microservice.yaml
@@ -42,4 +42,30 @@ servicecomb:
         sayHello:
           timeout: 30000
         add:
-          timeout: 1000
\ No newline at end of file
+          timeout: 1000
+
+# test configurations. you can choose any implementation. default using local.
+
+  # using nacos configuration
+#  nacos:
+#    serverAddr: http://127.0.0.1:8848
+#    group: jaxrstest
+#    dataId: jaxrsclient
+#    namespace: public
+#    contentType: properties # can be properties, yaml, raw. If using raw, 
property [group].[dataId]=value.
+#    addPrefix: false # if true [group].[dataId] will added as properties/yaml 
items prefix. Will not influence raw.
+
+  # for integration test not install any config server
+jaxrstest:
+  jaxrsclient:
+    override.high: hello high
+    override.low: hello low
+    k.value: 3
+    l1-1: 3.0
+    l1-2: 2.0
+    low-1.a.high-1.b: 1
+    low-1.a.high-2.b: 2
+    low-2.a.high-1.b: 3
+    low-2.a.high-2.b: 4
+
+# test configurations.
\ No newline at end of file
diff --git 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieUtil.java
 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieUtil.java
index 74b2a4d..6e209bb 100644
--- 
a/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieUtil.java
+++ 
b/dynamic-config/config-kie/src/main/java/org/apache/servicecomb/config/kie/client/KieUtil.java
@@ -17,13 +17,11 @@
 
 package org.apache.servicecomb.config.kie.client;
 
-import java.io.StringReader;
 import java.math.BigInteger;
 import java.nio.charset.StandardCharsets;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.List;
@@ -34,10 +32,9 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.servicecomb.config.kie.model.KVDoc;
 import org.apache.servicecomb.config.kie.model.KVResponse;
 import org.apache.servicecomb.config.kie.model.ValueType;
+import org.apache.servicecomb.config.parser.Parser;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
-import org.springframework.core.io.ByteArrayResource;
 
 public class KieUtil {
 
@@ -109,32 +106,15 @@ public class KieUtil {
     return resultMap;
   }
 
-  public static Map<String, String> processValueType(KVDoc kvDoc) {
+  public static Map<String, Object> processValueType(KVDoc kvDoc) {
     ValueType valueType = parseValueType(kvDoc.getValueType());
-
-    Properties properties = new Properties();
-    Map<String, String> kvMap = new HashMap<>();
-    try {
-      if (valueType == (ValueType.YAML) || valueType == (ValueType.YML)) {
-        YamlPropertiesFactoryBean yamlFactory = new 
YamlPropertiesFactoryBean();
-        yamlFactory.setResources(new 
ByteArrayResource(kvDoc.getValue().getBytes()));
-        properties = yamlFactory.getObject();
-      } else if (valueType == (ValueType.PROPERTIES)) {
-        properties.load(new StringReader(kvDoc.getValue()));
-      } else if (valueType == (ValueType.TEXT) || valueType == 
(ValueType.STRING)) {
-        kvMap.put(kvDoc.getKey(), kvDoc.getValue());
-        return kvMap;
-      } else {
-        // ValueType.JSON
-        kvMap.put(kvDoc.getKey(), kvDoc.getValue());
-        return kvMap;
-      }
-      kvMap = toMap(kvDoc.getKey(), properties);
-      return kvMap;
-    } catch (Exception e) {
-      LOGGER.error("read config failed", e);
+    if (valueType == (ValueType.YAML) || valueType == (ValueType.YML)) {
+      return 
Parser.findParser(Parser.CONTENT_TYPE_YAML).parse(kvDoc.getValue(), 
kvDoc.getKey(), true);
+    } else if (valueType == (ValueType.PROPERTIES)) {
+      return 
Parser.findParser(Parser.CONTENT_TYPE_PROPERTIES).parse(kvDoc.getValue(), 
kvDoc.getKey(), true);
+    } else {
+      return 
Parser.findParser(Parser.CONTENT_TYPE_RAW).parse(kvDoc.getValue(), 
kvDoc.getKey(), true);
     }
-    return Collections.emptyMap();
   }
 
   private static ValueType parseValueType(String valueType) {
diff --git 
a/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieUtil.java
 
b/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieUtil.java
index a27cf31..55e991e 100644
--- 
a/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieUtil.java
+++ 
b/dynamic-config/config-kie/src/test/java/org/apache/servicecomb/config/kie/client/TestKieUtil.java
@@ -29,7 +29,7 @@ public class TestKieUtil {
     KVDoc kvDoc = new KVDoc();
     kvDoc.setKey("hello");
     kvDoc.setValue("world");
-    Map<String, String> result = KieUtil.processValueType(kvDoc);
+    Map<String, Object> result = KieUtil.processValueType(kvDoc);
     Assert.assertEquals("world", result.get("hello"));
 
     kvDoc.setValueType("text");
diff --git a/dynamic-config/config-nacos/README.md 
b/dynamic-config/config-nacos/README.md
index 16fa49d..8e817fc 100644
--- a/dynamic-config/config-nacos/README.md
+++ b/dynamic-config/config-nacos/README.md
@@ -1,40 +1,5 @@
-#config-nacos
-How to use:
-1.Download base model from http://start.servicecomb.io and add maven 
dependence:
+# Dynamic configurations implementation with 
[Nacos](https://github.com/alibaba/nacos)
 
-<dependency>
-    <groupId>org.apache.servicecomb</groupId>
-    <artifactId>config-nacos</artifactId>
-    <version>${project.version}</version>
-</dependency>
+Read [developers 
guide](https://docs.servicecomb.io/java-chassis/zh_CN/config/general-config/)
+for details. 
 
-2.Start nacos console model(git url:https://github.com/alibaba/nacos) ,both 
account and password is "nacos",after that add properties(example):
-Data ID: example
-Group: DEFAULT_GROUP
-JSON:
-    {
-    "nacos":"666"
-    }
-
-3.In base model,add info in microservice.yaml:
-nacos:
-  config:
-    serverAddr: 127.0.0.1:8848
-    dataId: example
-    group: DEFAULT_GROUP
-
-4.Then add blow code and start base model,you will get properties(If 
properties on nacos has changed, you can also get new value):
-@RestSchema(schemaId = "nacos")
-@RequestMapping(path = "/")
-public class NacosImpl {
-    /**
-    **get properties from nacos
-    */
-    @GetMapping(path = "/config")
-    @Responsebody
-    public String config() throws Exception{
-        final String config = DynamicPropertyFactory.getInstance()
-                        .getStringProperty("nacos","").getValue();
-        return JSON.toJSONString(config);
-    }
-}
\ No newline at end of file
diff --git 
a/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/archaius/sources/NacosConfigurationSourceImpl.java
 
b/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/archaius/sources/NacosConfigurationSourceImpl.java
index 27c463c..13c7eb9 100644
--- 
a/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/archaius/sources/NacosConfigurationSourceImpl.java
+++ 
b/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/archaius/sources/NacosConfigurationSourceImpl.java
@@ -47,8 +47,6 @@ public class NacosConfigurationSourceImpl implements 
ConfigCenterConfigurationSo
 
   private List<WatchedUpdateListener> listeners = new CopyOnWriteArrayList<>();
 
-  private static final String SERVER_ADDR = "nacos.config.serverAddr";
-
   public NacosConfigurationSourceImpl() {
   }
 
@@ -56,7 +54,7 @@ public class NacosConfigurationSourceImpl implements 
ConfigCenterConfigurationSo
 
   @Override
   public boolean isValidSource(Configuration localConfiguration) {
-    if (localConfiguration.getProperty(SERVER_ADDR) == null) {
+    if (localConfiguration.getProperty(NacosConfig.SERVER_ADDR) == null) {
       LOGGER.warn("Nacos configuration source is not configured!");
       return false;
     }
diff --git 
a/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/client/NacosClient.java
 
b/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/client/NacosClient.java
index dfa7eb6..290f922 100644
--- 
a/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/client/NacosClient.java
+++ 
b/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/client/NacosClient.java
@@ -21,37 +21,28 @@ import static 
org.apache.servicecomb.config.nacos.client.ConfigurationAction.CRE
 import static 
org.apache.servicecomb.config.nacos.client.ConfigurationAction.DELETE;
 import static 
org.apache.servicecomb.config.nacos.client.ConfigurationAction.SET;
 
-import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
-import java.util.concurrent.*;
-
-import com.alibaba.nacos.api.NacosFactory;
-import com.alibaba.nacos.api.config.ConfigService;
-import com.alibaba.nacos.api.config.listener.Listener;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
 
+import org.apache.commons.lang3.StringUtils;
 import 
org.apache.servicecomb.config.nacos.archaius.sources.NacosConfigurationSourceImpl.UpdateHandler;
-import org.apache.servicecomb.foundation.common.utils.JsonUtils;
+import org.apache.servicecomb.config.parser.Parser;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.fasterxml.jackson.core.type.TypeReference;
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.config.ConfigService;
+import com.alibaba.nacos.api.config.listener.Listener;
 
 public class NacosClient {
 
   private static final Logger LOGGER = 
LoggerFactory.getLogger(NacosClient.class);
 
-  private static final NacosConfig NACOS_CONFIG = NacosConfig.INSTANCE;
-
   private static final Map<String, Object> originalConfigMap = new 
ConcurrentHashMap<>();
 
-  private final String serverAddr = NACOS_CONFIG.getServerAddr();
-
-  private final String dataId = NACOS_CONFIG.getDataId();
-
-  private final String group = NACOS_CONFIG.getGroup();
-
   private final UpdateHandler updateHandler;
 
   public NacosClient(UpdateHandler updateHandler) {
@@ -59,59 +50,55 @@ public class NacosClient {
   }
 
   public void refreshNacosConfig() {
-    new ConfigRefresh(serverAddr, dataId, group).refreshConfig();
+    new ConfigRefresh().refreshConfig();
   }
 
   class ConfigRefresh {
-    private final String serverAddr;
-
-    private final String dataId;
+    Parser contentParser = 
Parser.findParser(NacosConfig.INSTANCE.getContentType());
 
-    private final String group;
+    String keyPrefix = NacosConfig.INSTANCE.getGroup() + "." +
+        NacosConfig.INSTANCE.getDataId();
 
-    ConfigRefresh(String serverAddr, String dataId, String group) {
-      this.serverAddr = serverAddr;
-      this.dataId = dataId;
-      this.group = group;
+    ConfigRefresh() {
     }
 
     @SuppressWarnings("unchecked")
     void refreshConfig() {
       Properties properties = new Properties();
-      properties.put("serverAddr", serverAddr);
-      properties.put("dataId", dataId);
-      properties.put("group", group);
+      properties.put("serverAddr", NacosConfig.INSTANCE.getServerAddr());
+      properties.put("namespace", NacosConfig.INSTANCE.getNameSpace());
+
       try {
         ConfigService configService = 
NacosFactory.createConfigService(properties);
-        String content = configService.getConfig(dataId, group, 5000);
-        Map<String, Object> body = JsonUtils.OBJ_MAPPER.readValue(content,
-            new TypeReference<Map<String, Object>>() {
+        String content = 
configService.getConfig(NacosConfig.INSTANCE.getDataId(),
+            NacosConfig.INSTANCE.getGroup(), 5000);
+        processContent(content);
+        configService.addListener(NacosConfig.INSTANCE.getDataId(),
+            NacosConfig.INSTANCE.getGroup(), new Listener() {
+              @Override
+              public void receiveConfigInfo(String configInfo) {
+                LOGGER.info("receive from nacos:" + configInfo);
+                processContent(configInfo);
+              }
+
+              @Override
+              public Executor getExecutor() {
+                return null;
+              }
             });
-        refreshConfigItems(body);
-        configService.addListener(dataId, group, new Listener() {
-          @Override
-          public void receiveConfigInfo(String configInfo) {
-            LOGGER.info("receive from nacos:" + configInfo);
-            try {
-              Map<String, Object> body = 
JsonUtils.OBJ_MAPPER.readValue(configInfo,
-                  new TypeReference<Map<String, Object>>() {
-                  });
-              refreshConfigItems(body);
-            } catch (IOException e) {
-              LOGGER.error("JsonObject parse config center response error: ", 
e);
-            }
-          }
-
-          @Override
-          public Executor getExecutor() {
-            return null;
-          }
-        });
       } catch (Exception e) {
         LOGGER.error("Receive nacos config error: ", e);
       }
     }
 
+    private void processContent(String content) {
+      if (StringUtils.isEmpty(content)) {
+        return;
+      }
+
+      refreshConfigItems(contentParser.parse(content, keyPrefix, 
NacosConfig.INSTANCE.getAddPrefix()));
+    }
+
     private void refreshConfigItems(Map<String, Object> map) {
       compareChangedConfig(originalConfigMap, map);
       originalConfigMap.clear();
diff --git 
a/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/client/NacosConfig.java
 
b/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/client/NacosConfig.java
index dc41ca8..4fb3111 100644
--- 
a/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/client/NacosConfig.java
+++ 
b/dynamic-config/config-nacos/src/main/java/org/apache/servicecomb/config/nacos/client/NacosConfig.java
@@ -24,11 +24,17 @@ public class NacosConfig {
 
   private static Configuration finalConfig;
 
-  private static final String DATA_ID = "servicecomb.nacos.dataId";
+  public static final String DATA_ID = "servicecomb.nacos.dataId";
 
-  private static final String SERVER_ADDR = "servicecomb.nacos.serverAddr";
+  public static final String SERVER_ADDR = "servicecomb.nacos.serverAddr";
 
-  private static final String GROUP = "servicecomb.nacos.group";
+  public static final String GROUP = "servicecomb.nacos.group";
+
+  public static final String ADD_PREFIX = "servicecomb.nacos.addPrefix";
+
+  public static final String NAME_SPACE = "servicecomb.nacos.namespace";
+
+  public static final String CONTENT_TYPE = "servicecomb.nacos.contentType";
 
   private NacosConfig() {
   }
@@ -37,19 +43,27 @@ public class NacosConfig {
     finalConfig = config;
   }
 
-  public Configuration getConcurrentCompositeConfiguration() {
-    return finalConfig;
-  }
-
   public String getServerAddr() {
     return finalConfig.getString(SERVER_ADDR);
   }
 
-  public String getDataId(){
+  public String getDataId() {
     return finalConfig.getString(DATA_ID);
   }
 
-  public String getGroup(){
+  public String getGroup() {
     return finalConfig.getString(GROUP);
   }
+
+  public String getNameSpace() {
+    return finalConfig.getString(NAME_SPACE, "public");
+  }
+
+  public String getContentType() {
+    return finalConfig.getString(CONTENT_TYPE, "yaml");
+  }
+
+  public boolean getAddPrefix() {
+    return finalConfig.getBoolean(ADD_PREFIX, true);
+  }
 }
diff --git 
a/dynamic-config/config-nacos/src/test/java/org/apache/servicecomb/config/nacos/client/NacosClientTest.java
 
b/dynamic-config/config-nacos/src/test/java/org/apache/servicecomb/config/nacos/client/NacosClientTest.java
index d48c11b..9484517 100644
--- 
a/dynamic-config/config-nacos/src/test/java/org/apache/servicecomb/config/nacos/client/NacosClientTest.java
+++ 
b/dynamic-config/config-nacos/src/test/java/org/apache/servicecomb/config/nacos/client/NacosClientTest.java
@@ -61,7 +61,7 @@ public class NacosClientTest {
     UpdateHandler updateHandler = impl.new UpdateHandler();
     NacosClient nacosClient = new NacosClient(updateHandler);
 
-    NacosClient.ConfigRefresh cr = nacosClient.new ConfigRefresh("","","");
+    NacosClient.ConfigRefresh cr = nacosClient.new ConfigRefresh();
 
     try {
       Deencapsulation.invoke(cr, "compareChangedConfig", before, after);
diff --git 
a/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/Parser.java
 
b/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/Parser.java
new file mode 100644
index 0000000..216253a
--- /dev/null
+++ 
b/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/Parser.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.config.parser;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.lang3.StringUtils;
+
+public interface Parser {
+  String CONTENT_TYPE_YAML = "yaml";
+  String CONTENT_TYPE_PROPERTIES = "properties";
+  String CONTENT_TYPE_RAW = "raw";
+
+  YamlParser yamlParser = new YamlParser();
+  PropertiesParser propertiesParser = new PropertiesParser();
+  RawParser rawParser = new RawParser();
+
+  Map<String, Object> parse(String content, String prefix, boolean addPrefix);
+
+  static Parser findParser(String contentType) {
+    switch (contentType) {
+      case CONTENT_TYPE_YAML:
+        return yamlParser;
+      case CONTENT_TYPE_PROPERTIES:
+        return propertiesParser;
+      case CONTENT_TYPE_RAW:
+        return rawParser;
+      default:
+        throw new IllegalArgumentException("not supported contentType=" + 
contentType);
+    }
+  }
+
+  @SuppressWarnings("unchecked")
+  static Map<String, Object> propertiesToMap(Properties properties, String 
prefix, boolean addPrefix) {
+    Map<String, Object> result = new HashMap<>();
+    Enumeration<String> keys = (Enumeration<String>) 
properties.propertyNames();
+    while (keys.hasMoreElements()) {
+      String key = keys.nextElement();
+      String value = properties.getProperty(key);
+
+      if (addPrefix && !StringUtils.isEmpty(prefix)) {
+        key = prefix + "." + key;
+      }
+
+      if (value == null) {
+        result.put(key, null);
+      } else {
+        result.put(key, value.trim());
+      }
+    }
+    return result;
+  }
+}
diff --git 
a/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/PropertiesParser.java
 
b/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/PropertiesParser.java
new file mode 100644
index 0000000..84bfae1
--- /dev/null
+++ 
b/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/PropertiesParser.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.config.parser;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Map;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class PropertiesParser implements Parser {
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(PropertiesParser.class);
+
+  @Override
+  public Map<String, Object> parse(String content, String prefix, boolean 
addPrefix) {
+    Properties properties = new Properties();
+    try {
+      properties.load(new StringReader(content));
+    } catch (IOException e) {
+      LOGGER.error("parse properties content failed, message={}", 
e.getMessage());
+    }
+    return Parser.propertiesToMap(properties, prefix, addPrefix);
+  }
+}
diff --git 
a/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/RawParser.java
 
b/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/RawParser.java
new file mode 100644
index 0000000..b22d52d
--- /dev/null
+++ 
b/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/RawParser.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.config.parser;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class RawParser implements Parser {
+  @Override
+  public Map<String, Object> parse(String content, String prefix, boolean 
addPrefix) {
+    Map<String, Object> result = new HashMap<>();
+    result.put(prefix, content);
+    return result;
+  }
+}
diff --git 
a/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/YamlParser.java
 
b/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/YamlParser.java
new file mode 100644
index 0000000..4ce5665
--- /dev/null
+++ 
b/foundations/foundation-config/src/main/java/org/apache/servicecomb/config/parser/YamlParser.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.config.parser;
+
+import java.util.Map;
+import java.util.Properties;
+
+import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
+import org.springframework.core.io.ByteArrayResource;
+
+public class YamlParser implements Parser {
+  @Override
+  public Map<String, Object> parse(String content, String prefix, boolean 
addPrefix) {
+    YamlPropertiesFactoryBean yamlFactory = new YamlPropertiesFactoryBean();
+    yamlFactory.setResources(new ByteArrayResource(content.getBytes()));
+    Properties properties = yamlFactory.getObject();
+    return Parser.propertiesToMap(properties, prefix, addPrefix);
+  }
+}
diff --git 
a/foundations/foundation-config/src/test/java/org/apache/servicecomb/config/parser/TestParser.java
 
b/foundations/foundation-config/src/test/java/org/apache/servicecomb/config/parser/TestParser.java
new file mode 100644
index 0000000..6940934
--- /dev/null
+++ 
b/foundations/foundation-config/src/test/java/org/apache/servicecomb/config/parser/TestParser.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.servicecomb.config.parser;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.catchThrowable;
+
+import org.junit.Test;
+
+public class TestParser {
+  @Test
+  public void testRawParser() {
+    Parser parser = Parser.findParser(Parser.CONTENT_TYPE_RAW);
+    assertThat(parser.parse("world", "hello", 
true)).containsKey("hello").containsValue("world");
+    assertThat(parser.parse("world", "hello", 
false)).containsKey("hello").containsValue("world");
+  }
+
+  @Test
+  public void testPropertiesParser() {
+    Parser parser = Parser.findParser(Parser.CONTENT_TYPE_PROPERTIES);
+    assertThat(parser.parse("l1-1=3.0\n"
+        + "l1-2=2.0", "hello", true)).containsKeys("hello.l1-1", "hello.l1-2")
+        .containsValues("2.0", "3.0");
+    assertThat(parser.parse("l1-1=3.0\n"
+        + "l1-2=2.0", "hello", false)).containsKeys("l1-1", "l1-2")
+        .containsValues("2.0", "3.0");
+  }
+
+  @Test
+  public void testYamlParser() {
+    Parser parser = Parser.findParser(Parser.CONTENT_TYPE_YAML);
+    assertThat(parser.parse("l1-1: 3.0\n"
+        + "l1-2: 2.0", "hello", true)).containsKeys("hello.l1-1", "hello.l1-2")
+        .containsValues("2.0", "3.0");
+    assertThat(parser.parse("l1-1: 3.0\n"
+        + "l1-2: 2.0", "false", false)).containsKeys("l1-1", "l1-2")
+        .containsValues("2.0", "3.0");
+  }
+
+  @Test
+  public void testInvalidParser() {
+    Throwable exception = catchThrowable(() -> Parser.findParser("unknown"));
+    assertThat(exception).isInstanceOf(IllegalArgumentException.class);
+  }
+}

Reply via email to