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

albumenj pushed a commit to branch 3.2
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.2 by this push:
     new c4d6f94b2c Introduce getConfig QoS Command (#11664)
c4d6f94b2c is described below

commit c4d6f94b2ce16ead95880265749b2ffb9701ecc3
Author: Albumen Kevin <[email protected]>
AuthorDate: Mon Feb 27 12:33:04 2023 +0800

    Introduce getConfig QoS Command (#11664)
    
    * Introduce getConfig QoS Command
    
    * Fix NPE
    
    * Fix NPE
---
 .../org/apache/dubbo/config/AbstractConfig.java    |   6 +
 .../dubbo/config/AbstractInterfaceConfig.java      |  23 +--
 .../apache/dubbo/config/AbstractMethodConfig.java  |   4 +
 .../apache/dubbo/config/AbstractServiceConfig.java |   2 +
 .../apache/dubbo/config/ReferenceConfigBase.java   |   3 +
 .../org/apache/dubbo/config/ServiceConfigBase.java |   6 +-
 .../java/org/apache/dubbo/config/SslConfig.java    |   7 +
 .../dubbo/config/nested/AggregationConfig.java     |   4 +-
 .../dubbo/config/nested/PrometheusConfig.java      |   8 +-
 .../org/apache/dubbo/config/ReferenceConfig.java   |   4 +
 .../org/apache/dubbo/config/ServiceConfig.java     |   2 +
 .../apache/dubbo/qos/command/impl/GetConfig.java   | 200 +++++++++++++++++++++
 .../org.apache.dubbo.qos.command.BaseCommand       |   1 +
 .../dubbo/qos/command/impl/GetConfigTest.java      | 140 +++++++++++++++
 .../dubbo/qos/command/util/CommandHelperTest.java  |   9 +-
 15 files changed, 401 insertions(+), 18 deletions(-)

diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java 
b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
index 01108fadb1..6247a02bd4 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
@@ -539,10 +539,12 @@ public abstract class AbstractConfig implements 
Serializable {
      * @see AbstractConfig#checkDefault()
      * @see AbstractConfig#appendParameters(Map, Object, String)
      */
+    @Transient
     public Map<String, String> getMetaData() {
         return getMetaData(null);
     }
 
+    @Transient
     public Map<String, String> getMetaData(String prefix) {
         Map<String, String> metaData = new HashMap<>();
         appendAttributes(metaData, this, prefix);
@@ -569,6 +571,7 @@ public abstract class AbstractConfig implements 
Serializable {
     }
 
     @Parameter(excluded = true, attribute = false)
+    @Transient
     public List<String> getPrefixes() {
         List<String> prefixes = new ArrayList<>();
         if (StringUtils.hasText(this.getId())) {
@@ -595,6 +598,7 @@ public abstract class AbstractConfig implements 
Serializable {
         return CommonConstants.DUBBO + "." + getTagName(cls);
     }
 
+    @Transient
     public ConfigMode getConfigMode() {
         return 
getApplicationModel().getApplicationConfigManager().getConfigMode();
     }
@@ -1030,6 +1034,7 @@ public abstract class AbstractConfig implements 
Serializable {
         return hashCode;
     }
 
+    @Transient
     private List<Method> getAttributedMethods() {
         Class<? extends AbstractConfig> cls = this.getClass();
         return ConcurrentHashMapUtils.computeIfAbsent(attributedMethodCache, 
cls, (key) -> computeAttributedMethods());
@@ -1063,6 +1068,7 @@ public abstract class AbstractConfig implements 
Serializable {
         return methods;
     }
 
+    @Transient
     protected ConfigManager getConfigManager() {
         return getApplicationModel().getApplicationConfigManager();
     }
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
index 3993ad7ea2..6fd828d998 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
@@ -16,15 +16,6 @@
  */
 package org.apache.dubbo.config;
 
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.Version;
 import org.apache.dubbo.common.config.ConfigurationUtils;
@@ -43,6 +34,16 @@ import org.apache.dubbo.rpc.model.ScopeModel;
 import org.apache.dubbo.rpc.model.ScopeModelUtil;
 import org.apache.dubbo.rpc.model.ServiceMetadata;
 
+import java.beans.Transient;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
 import static 
org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
 import static 
org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
 import static 
org.apache.dubbo.common.constants.CommonConstants.INVOKER_LISTENER_KEY;
@@ -207,8 +208,9 @@ public abstract class AbstractInterfaceConfig extends 
AbstractMethodConfig {
     /**
      * The url of the reference service
      */
-    protected final List<URL> urls = new ArrayList<URL>();
+    protected transient final List<URL> urls = new ArrayList<URL>();
 
+    @Transient
     public List<URL> getExportedUrls() {
         return urls;
     }
@@ -903,6 +905,7 @@ public abstract class AbstractInterfaceConfig extends 
AbstractMethodConfig {
         this.interfaceName = interfaceName;
     }
 
+    @Transient
     public ClassLoader getInterfaceClassLoader() {
         return interfaceClassLoader;
     }
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java 
b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java
index bfbce7c244..d1978f62c4 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractMethodConfig.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.ModuleModel;
 import org.apache.dubbo.rpc.model.ScopeModel;
 
+import java.beans.Transient;
 import java.util.Map;
 
 /**
@@ -108,11 +109,13 @@ public abstract class AbstractMethodConfig extends 
AbstractConfig {
     }
 
     @Override
+    @Transient
     public ModuleModel getScopeModel() {
         return (ModuleModel) super.getScopeModel();
     }
 
     @Override
+    @Transient
     protected ScopeModel getDefaultModel() {
         return ApplicationModel.defaultModel().getDefaultModule();
     }
@@ -127,6 +130,7 @@ public abstract class AbstractMethodConfig extends 
AbstractConfig {
         }
     }
 
+    @Transient
     protected ModuleConfigManager getModuleConfigManager() {
         return getScopeModel().getConfigManager();
     }
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java 
b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java
index 1f2ae28a72..474c362cfe 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java
@@ -21,6 +21,7 @@ import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.config.support.Parameter;
 import org.apache.dubbo.rpc.model.ModuleModel;
 
+import java.beans.Transient;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -371,6 +372,7 @@ public abstract class AbstractServiceConfig extends 
AbstractInterfaceConfig {
     }
 
     @Parameter(key = SERVICE_EXECUTOR)
+    @Transient
     public Executor getExecutor() {
         return executor;
     }
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java 
b/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java
index 4ef903f395..867e195561 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java
@@ -29,6 +29,7 @@ import org.apache.dubbo.rpc.model.ServiceMetadata;
 import org.apache.dubbo.rpc.service.GenericService;
 import org.apache.dubbo.rpc.support.ProtocolUtils;
 
+import java.beans.Transient;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -294,6 +295,7 @@ public abstract class ReferenceConfigBase<T> extends 
AbstractReferenceConfig {
         this.unloadClusterRelated = unloadClusterRelated;
     }
 
+    @Transient
     public ServiceMetadata getServiceMetadata() {
         return serviceMetadata;
     }
@@ -365,6 +367,7 @@ public abstract class ReferenceConfigBase<T> extends 
AbstractReferenceConfig {
         return shouldReferAsync;
     }
 
+    @Transient
     public abstract T get();
 
     public void destroy() {
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java 
b/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java
index d80b008d90..57f850c18c 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java
@@ -28,6 +28,7 @@ import org.apache.dubbo.rpc.model.ServiceMetadata;
 import org.apache.dubbo.rpc.service.GenericService;
 import org.apache.dubbo.rpc.support.ProtocolUtils;
 
+import java.beans.Transient;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -59,7 +60,7 @@ public abstract class ServiceConfigBase<T> extends 
AbstractServiceConfig {
     /**
      * The reference of the interface implementation
      */
-    protected T ref;
+    protected transient T ref;
 
     /**
      * The service name
@@ -296,6 +297,7 @@ public abstract class ServiceConfigBase<T> extends 
AbstractServiceConfig {
         }
     }
 
+    @Transient
     public T getRef() {
         return ref;
     }
@@ -346,11 +348,13 @@ public abstract class ServiceConfigBase<T> extends 
AbstractServiceConfig {
         }
     }
 
+    @Transient
     public ServiceMetadata getServiceMetadata() {
         return serviceMetadata;
     }
 
     @Override
+    @Transient
     @Parameter(excluded = true, attribute = false)
     public List<String> getPrefixes() {
         List<String> prefixes = new ArrayList<>();
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java 
b/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java
index 62e03edbce..0dc9557246 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/SslConfig.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.common.utils.IOUtils;
 import org.apache.dubbo.config.support.Parameter;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
+import java.beans.Transient;
 import java.io.IOException;
 import java.io.InputStream;
 
@@ -142,6 +143,7 @@ public class SslConfig extends AbstractConfig {
         this.clientTrustCertCollectionPath = clientTrustCertCollectionPath;
     }
 
+    @Transient
     public InputStream getServerKeyCertChainPathStream() throws IOException {
         if (serverKeyCertChainPath != null) {
             serverKeyCertChainPathStream = 
IOUtils.getURL(serverKeyCertChainPath).openStream();
@@ -153,6 +155,7 @@ public class SslConfig extends AbstractConfig {
         this.serverKeyCertChainPathStream = serverKeyCertChainPathStream;
     }
 
+    @Transient
     public InputStream getServerPrivateKeyPathStream() throws IOException {
         if (serverPrivateKeyPath != null) {
             serverPrivateKeyPathStream = 
IOUtils.getURL(serverPrivateKeyPath).openStream();
@@ -164,6 +167,7 @@ public class SslConfig extends AbstractConfig {
         this.serverPrivateKeyPathStream = serverPrivateKeyPathStream;
     }
 
+    @Transient
     public InputStream getServerTrustCertCollectionPathStream() throws 
IOException {
         if (serverTrustCertCollectionPath != null) {
             serverTrustCertCollectionPathStream = 
IOUtils.getURL(serverTrustCertCollectionPath).openStream();
@@ -175,6 +179,7 @@ public class SslConfig extends AbstractConfig {
         this.serverTrustCertCollectionPathStream = 
serverTrustCertCollectionPathStream;
     }
 
+    @Transient
     public InputStream getClientKeyCertChainPathStream() throws IOException {
         if (clientKeyCertChainPath != null) {
             clientKeyCertChainPathStream = 
IOUtils.getURL(clientKeyCertChainPath).openStream();
@@ -186,6 +191,7 @@ public class SslConfig extends AbstractConfig {
         this.clientKeyCertChainPathStream = clientKeyCertChainPathStream;
     }
 
+    @Transient
     public InputStream getClientPrivateKeyPathStream() throws IOException {
         if (clientPrivateKeyPath != null) {
             clientPrivateKeyPathStream = 
IOUtils.getURL(clientPrivateKeyPath).openStream();
@@ -197,6 +203,7 @@ public class SslConfig extends AbstractConfig {
         this.clientPrivateKeyPathStream = clientPrivateKeyPathStream;
     }
 
+    @Transient
     public InputStream getClientTrustCertCollectionPathStream() throws 
IOException {
         if (clientTrustCertCollectionPath != null) {
             clientTrustCertCollectionPathStream = 
IOUtils.getURL(clientTrustCertCollectionPath).openStream();
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/AggregationConfig.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/AggregationConfig.java
index da0a6ce94e..81a767d1a1 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/AggregationConfig.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/AggregationConfig.java
@@ -16,7 +16,9 @@
  */
 package org.apache.dubbo.config.nested;
 
-public class AggregationConfig {
+import java.io.Serializable;
+
+public class AggregationConfig implements Serializable {
 
     /**
      * Enable local aggregation or not
diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/PrometheusConfig.java
 
b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/PrometheusConfig.java
index 98da33cbd4..70310a7bba 100644
--- 
a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/PrometheusConfig.java
+++ 
b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/PrometheusConfig.java
@@ -18,7 +18,9 @@ package org.apache.dubbo.config.nested;
 
 import org.apache.dubbo.config.support.Nested;
 
-public class PrometheusConfig {
+import java.io.Serializable;
+
+public class PrometheusConfig implements Serializable {
 
     /**
      * Prometheus exporter configuration
@@ -48,7 +50,7 @@ public class PrometheusConfig {
         this.pushgateway = pushgateway;
     }
 
-    public static class Exporter {
+    public static class Exporter implements Serializable {
 
         /**
          * Enable prometheus exporter
@@ -116,7 +118,7 @@ public class PrometheusConfig {
         }
     }
 
-    public static class Pushgateway {
+    public static class Pushgateway implements Serializable {
 
         /**
          * Enable publishing via a Prometheus Pushgateway
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index e48caf5ffb..86796a9139 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
@@ -52,6 +52,7 @@ import org.apache.dubbo.rpc.service.GenericService;
 import org.apache.dubbo.rpc.stub.StubSuppliers;
 import org.apache.dubbo.rpc.support.ProtocolUtils;
 
+import java.beans.Transient;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
@@ -217,6 +218,7 @@ public class ReferenceConfig<T> extends 
ReferenceConfigBase<T> {
     }
 
     @Override
+    @Transient
     public T get() {
         if (destroyed) {
             throw new IllegalStateException("The invoker of ReferenceConfig(" 
+ url + ") has already destroyed!");
@@ -765,10 +767,12 @@ public class ReferenceConfig<T> extends 
ReferenceConfigBase<T> {
      * @return
      */
     @Deprecated
+    @Transient
     public Invoker<?> getInvoker() {
         return invoker;
     }
 
+    @Transient
     public Runnable getDestroyRunner() {
         return this::destroy;
     }
diff --git 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
index 473fd988e5..204d09777d 100644
--- 
a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
+++ 
b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
@@ -50,6 +50,7 @@ import org.apache.dubbo.rpc.model.ScopeModel;
 import org.apache.dubbo.rpc.model.ServiceDescriptor;
 import org.apache.dubbo.rpc.service.GenericService;
 
+import java.beans.Transient;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -927,6 +928,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
         }
     }
 
+    @Transient
     public Runnable getDestroyRunner() {
         return this::unexport;
     }
diff --git 
a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetConfig.java
 
b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetConfig.java
new file mode 100644
index 0000000000..0fa00839f7
--- /dev/null
+++ 
b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetConfig.java
@@ -0,0 +1,200 @@
+/*
+ * 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.dubbo.qos.command.impl;
+
+import org.apache.dubbo.common.utils.JsonUtils;
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ConfigCenterConfig;
+import org.apache.dubbo.config.ConsumerConfig;
+import org.apache.dubbo.config.MetadataReportConfig;
+import org.apache.dubbo.config.MetricsConfig;
+import org.apache.dubbo.config.ModuleConfig;
+import org.apache.dubbo.config.MonitorConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.ProviderConfig;
+import org.apache.dubbo.config.ReferenceConfigBase;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfigBase;
+import org.apache.dubbo.config.SslConfig;
+import org.apache.dubbo.config.context.ConfigManager;
+import org.apache.dubbo.config.context.ModuleConfigManager;
+import org.apache.dubbo.qos.command.BaseCommand;
+import org.apache.dubbo.qos.command.CommandContext;
+import org.apache.dubbo.qos.command.annotation.Cmd;
+import org.apache.dubbo.qos.permission.PermissionLevel;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+import org.apache.dubbo.rpc.model.ModuleModel;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+@Cmd(name = "getConfig",
+    summary = "Get current running config.",
+    example = {"getConfig ReferenceConfig com.example.DemoService", "getConfig 
ApplicationConfig"},
+    requiredPermissionLevel = PermissionLevel.PRIVATE)
+public class GetConfig implements BaseCommand {
+    private final FrameworkModel frameworkModel;
+
+    public GetConfig(FrameworkModel frameworkModel) {
+        this.frameworkModel = frameworkModel;
+    }
+
+    @Override
+    public String execute(CommandContext commandContext, String[] args) {
+        boolean http = commandContext.isHttp();
+        StringBuilder plainOutput = new StringBuilder();
+        Map<String, Object> frameworkMap = new HashMap<>();
+
+        appendFrameworkConfig(args, plainOutput, frameworkMap);
+
+        if (http) {
+            return JsonUtils.getJson().toJson(frameworkMap);
+        } else {
+            return plainOutput.toString();
+        }
+    }
+
+    private void appendFrameworkConfig(String[] args, StringBuilder 
plainOutput, Map<String, Object> frameworkMap) {
+        for (ApplicationModel applicationModel : 
frameworkModel.getApplicationModels()) {
+            Map<String, Object> applicationMap = new HashMap<>();
+            frameworkMap.put(applicationModel.getDesc(), applicationMap);
+            plainOutput.append("ApplicationModel: ")
+                .append(applicationModel.getDesc())
+                .append("\n");
+
+            ConfigManager configManager = 
applicationModel.getApplicationConfigManager();
+
+            appendApplicationConfigs(args, plainOutput, applicationModel, 
applicationMap, configManager);
+        }
+    }
+
+    private static void appendApplicationConfigs(String[] args, StringBuilder 
plainOutput, ApplicationModel applicationModel, Map<String, Object> 
applicationMap, ConfigManager configManager) {
+        Optional<ApplicationConfig> applicationConfig = 
configManager.getApplication();
+        applicationConfig.ifPresent(config -> 
appendConfig("ApplicationConfig", config.getName(), config, plainOutput, 
applicationMap, args));
+
+        for (ProtocolConfig protocol : configManager.getProtocols()) {
+            appendConfigs("ProtocolConfig", protocol.getName(), protocol, 
plainOutput, applicationMap, args);
+        }
+
+        for (RegistryConfig registry : configManager.getRegistries()) {
+            appendConfigs("RegistryConfig", registry.getId(), registry, 
plainOutput, applicationMap, args);
+        }
+
+        for (MetadataReportConfig metadataConfig : 
configManager.getMetadataConfigs()) {
+            appendConfigs("MetadataReportConfig", metadataConfig.getId(), 
metadataConfig, plainOutput, applicationMap, args);
+        }
+
+        for (ConfigCenterConfig configCenter : 
configManager.getConfigCenters()) {
+            appendConfigs("ConfigCenterConfig", configCenter.getId(), 
configCenter, plainOutput, applicationMap, args);
+        }
+
+        Optional<MetricsConfig> metricsConfig = configManager.getMetrics();
+        metricsConfig.ifPresent(config -> appendConfig("MetricsConfig", 
config.getId(), config, plainOutput, applicationMap, args));
+
+        Optional<MonitorConfig> monitorConfig = configManager.getMonitor();
+        monitorConfig.ifPresent(config -> appendConfig("MonitorConfig", 
config.getId(), config, plainOutput, applicationMap, args));
+
+        Optional<SslConfig> sslConfig = configManager.getSsl();
+        sslConfig.ifPresent(config -> appendConfig("SslConfig", 
config.getId(), config, plainOutput, applicationMap, args));
+
+        for (ModuleModel moduleModel : applicationModel.getModuleModels()) {
+            Map<String, Object> moduleMap = new HashMap<>();
+            applicationMap.put(moduleModel.getDesc(), moduleMap);
+            plainOutput.append("ModuleModel: ")
+                .append(moduleModel.getDesc())
+                .append("\n");
+
+            ModuleConfigManager moduleConfigManager = 
moduleModel.getConfigManager();
+
+            appendModuleConfigs(args, plainOutput, moduleMap, 
moduleConfigManager);
+        }
+    }
+
+    private static void appendModuleConfigs(String[] args, StringBuilder 
plainOutput, Map<String, Object> moduleMap, ModuleConfigManager 
moduleConfigManager) {
+        for (ProviderConfig provider : moduleConfigManager.getProviders()) {
+            appendConfigs("ProviderConfig", provider.getId(), provider, 
plainOutput, moduleMap, args);
+        }
+
+        for (ConsumerConfig consumer : moduleConfigManager.getConsumers()) {
+            appendConfigs("ConsumerConfig", consumer.getId(), consumer, 
plainOutput, moduleMap, args);
+        }
+
+        Optional<ModuleConfig> moduleConfig = moduleConfigManager.getModule();
+        moduleConfig.ifPresent(config -> appendConfig("ModuleConfig", 
config.getId(), config, plainOutput, moduleMap, args));
+
+        for (ServiceConfigBase<?> service : moduleConfigManager.getServices()) 
{
+            appendConfigs("ServiceConfig", service.getUniqueServiceName(), 
service, plainOutput, moduleMap, args);
+        }
+
+        for (ReferenceConfigBase<?> reference : 
moduleConfigManager.getReferences()) {
+            appendConfigs("ReferenceConfig", reference.getUniqueServiceName(), 
reference, plainOutput, moduleMap, args);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private static void appendConfigs(String type, String id, Object config, 
StringBuilder plainOutput, Map<String, Object> map, String[] args) {
+        if (!isMatch(type, id, args)) {
+            return;
+        }
+
+        plainOutput.append(type).append(": ")
+            .append(id)
+            .append("\n")
+            .append(config)
+            .append("\n\n");
+
+        Map<String, Object> typeMap = (Map<String, Object>) 
map.computeIfAbsent(type, k -> new HashMap<String, Object>());
+        typeMap.put(id, config);
+    }
+
+    private static void appendConfig(String type, String id, Object config, 
StringBuilder plainOutput, Map<String, Object> map, String[] args) {
+        if (!isMatch(type, id, args)) {
+            return;
+        }
+
+        plainOutput.append(type).append(": ")
+            .append(id)
+            .append("\n")
+            .append(config)
+            .append("\n\n");
+
+        map.put(type, config);
+    }
+
+    private static boolean isMatch(String type, String id, String[] args) {
+        if (args == null) {
+            return true;
+        }
+        switch (args.length) {
+            case 1:
+                if (!Objects.equals(args[0], type)) {
+                    return false;
+                }
+                break;
+            case 2:
+                if (!Objects.equals(args[0], type) || !Objects.equals(args[1], 
id)) {
+                    return false;
+                }
+                break;
+            default:
+        }
+        return true;
+    }
+}
diff --git 
a/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand
 
b/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand
index aec45f93ac..c28bf0d97b 100644
--- 
a/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand
+++ 
b/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand
@@ -34,3 +34,4 @@ switchLogger=org.apache.dubbo.qos.command.impl.SwitchLogger
 switchLogLevel=org.apache.dubbo.qos.command.impl.SwitchLogLevel
 serializeCheckStatus=org.apache.dubbo.qos.command.impl.SerializeCheckStatus
 serializeWarnedClasses=org.apache.dubbo.qos.command.impl.SerializeWarnedClasses
+getConfig=org.apache.dubbo.qos.command.impl.GetConfig
diff --git 
a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/GetConfigTest.java
 
b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/GetConfigTest.java
new file mode 100644
index 0000000000..bbdc5c255a
--- /dev/null
+++ 
b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/impl/GetConfigTest.java
@@ -0,0 +1,140 @@
+/*
+ * 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.dubbo.qos.command.impl;
+
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ConfigCenterConfig;
+import org.apache.dubbo.config.ConsumerConfig;
+import org.apache.dubbo.config.MetadataReportConfig;
+import org.apache.dubbo.config.MetricsConfig;
+import org.apache.dubbo.config.ModuleConfig;
+import org.apache.dubbo.config.MonitorConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.ProviderConfig;
+import org.apache.dubbo.config.ReferenceConfig;
+import org.apache.dubbo.config.RegistryConfig;
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.SslConfig;
+import org.apache.dubbo.metadata.MetadataService;
+import org.apache.dubbo.qos.command.CommandContext;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+import org.apache.dubbo.rpc.model.ModuleModel;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class GetConfigTest {
+    @Test
+    void testAll(){
+        FrameworkModel frameworkModel = new FrameworkModel();
+        ApplicationModel applicationModel1 = frameworkModel.newApplication();
+
+        applicationModel1.getApplicationConfigManager().setApplication(new 
ApplicationConfig("app1"));
+        applicationModel1.getApplicationConfigManager().addProtocol(new 
ProtocolConfig("dubbo", 12345));
+        applicationModel1.getApplicationConfigManager().addRegistry(new 
RegistryConfig("zookeeper://127.0.0.1:2181"));
+        applicationModel1.getApplicationConfigManager().addMetadataReport(new 
MetadataReportConfig("zookeeper://127.0.0.1:2181"));
+        ConfigCenterConfig configCenterConfig = new ConfigCenterConfig();
+        configCenterConfig.setAddress("zookeeper://127.0.0.1:2181");
+        
applicationModel1.getApplicationConfigManager().addConfigCenter(configCenterConfig);
+        applicationModel1.getApplicationConfigManager().setMetrics(new 
MetricsConfig());
+        applicationModel1.getApplicationConfigManager().setMonitor(new 
MonitorConfig());
+        applicationModel1.getApplicationConfigManager().setSsl(new 
SslConfig());
+
+        ModuleModel moduleModel = applicationModel1.newModule();
+        moduleModel.getConfigManager().setModule(new ModuleConfig());
+        moduleModel.getConfigManager().addConsumer(new ConsumerConfig());
+        moduleModel.getConfigManager().addProvider(new ProviderConfig());
+        ReferenceConfig<Object> referenceConfig = new ReferenceConfig<>();
+        referenceConfig.setInterface(MetadataService.class);
+        moduleModel.getConfigManager().addReference(referenceConfig);
+        ServiceConfig<Object> serviceConfig = new ServiceConfig<>();
+        serviceConfig.setInterface(MetadataService.class);
+        moduleModel.getConfigManager().addService(serviceConfig);
+
+        CommandContext commandContext = new CommandContext("getConfig");
+        commandContext.setHttp(true);
+
+        Assertions.assertNotNull(new 
GetConfig(frameworkModel).execute(commandContext, null));
+    }
+
+    @Test
+    void testFilter1(){
+        FrameworkModel frameworkModel = new FrameworkModel();
+        ApplicationModel applicationModel1 = frameworkModel.newApplication();
+
+        applicationModel1.getApplicationConfigManager().setApplication(new 
ApplicationConfig("app1"));
+        applicationModel1.getApplicationConfigManager().addProtocol(new 
ProtocolConfig("dubbo", 12345));
+        applicationModel1.getApplicationConfigManager().addRegistry(new 
RegistryConfig("zookeeper://127.0.0.1:2181"));
+        applicationModel1.getApplicationConfigManager().addMetadataReport(new 
MetadataReportConfig("zookeeper://127.0.0.1:2181"));
+        ConfigCenterConfig configCenterConfig = new ConfigCenterConfig();
+        configCenterConfig.setAddress("zookeeper://127.0.0.1:2181");
+        
applicationModel1.getApplicationConfigManager().addConfigCenter(configCenterConfig);
+        applicationModel1.getApplicationConfigManager().setMetrics(new 
MetricsConfig());
+        applicationModel1.getApplicationConfigManager().setMonitor(new 
MonitorConfig());
+        applicationModel1.getApplicationConfigManager().setSsl(new 
SslConfig());
+
+        ModuleModel moduleModel = applicationModel1.newModule();
+        moduleModel.getConfigManager().setModule(new ModuleConfig());
+        moduleModel.getConfigManager().addConsumer(new ConsumerConfig());
+        moduleModel.getConfigManager().addProvider(new ProviderConfig());
+        ReferenceConfig<Object> referenceConfig = new ReferenceConfig<>();
+        referenceConfig.setInterface(MetadataService.class);
+        moduleModel.getConfigManager().addReference(referenceConfig);
+        ServiceConfig<Object> serviceConfig = new ServiceConfig<>();
+        serviceConfig.setInterface(MetadataService.class);
+        moduleModel.getConfigManager().addService(serviceConfig);
+
+        CommandContext commandContext = new CommandContext("getConfig");
+        commandContext.setHttp(true);
+
+        Assertions.assertNotNull(new 
GetConfig(frameworkModel).execute(commandContext, new 
String[]{"ApplicationConfig"}));
+    }
+
+    @Test
+    void testFilter2(){
+        FrameworkModel frameworkModel = new FrameworkModel();
+        ApplicationModel applicationModel1 = frameworkModel.newApplication();
+
+        applicationModel1.getApplicationConfigManager().setApplication(new 
ApplicationConfig("app1"));
+        applicationModel1.getApplicationConfigManager().addProtocol(new 
ProtocolConfig("dubbo", 12345));
+        applicationModel1.getApplicationConfigManager().addRegistry(new 
RegistryConfig("zookeeper://127.0.0.1:2181"));
+        applicationModel1.getApplicationConfigManager().addMetadataReport(new 
MetadataReportConfig("zookeeper://127.0.0.1:2181"));
+        ConfigCenterConfig configCenterConfig = new ConfigCenterConfig();
+        configCenterConfig.setAddress("zookeeper://127.0.0.1:2181");
+        
applicationModel1.getApplicationConfigManager().addConfigCenter(configCenterConfig);
+        applicationModel1.getApplicationConfigManager().setMetrics(new 
MetricsConfig());
+        applicationModel1.getApplicationConfigManager().setMonitor(new 
MonitorConfig());
+        applicationModel1.getApplicationConfigManager().setSsl(new 
SslConfig());
+
+        ModuleModel moduleModel = applicationModel1.newModule();
+        moduleModel.getConfigManager().setModule(new ModuleConfig());
+        moduleModel.getConfigManager().addConsumer(new ConsumerConfig());
+        moduleModel.getConfigManager().addProvider(new ProviderConfig());
+        ReferenceConfig<Object> referenceConfig = new ReferenceConfig<>();
+        referenceConfig.setInterface(MetadataService.class);
+        moduleModel.getConfigManager().addReference(referenceConfig);
+        ServiceConfig<Object> serviceConfig = new ServiceConfig<>();
+        serviceConfig.setInterface(MetadataService.class);
+        moduleModel.getConfigManager().addService(serviceConfig);
+
+        CommandContext commandContext = new CommandContext("getConfig");
+        commandContext.setHttp(true);
+
+        Assertions.assertNotNull(new 
GetConfig(frameworkModel).execute(commandContext, new 
String[]{"ProtocolConfig", "dubbo"}));
+    }
+}
diff --git 
a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java
 
b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java
index 92c4fdea1c..a98333af29 100644
--- 
a/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java
+++ 
b/dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/command/util/CommandHelperTest.java
@@ -16,9 +16,6 @@
  */
 package org.apache.dubbo.qos.command.util;
 
-import java.util.LinkedList;
-import java.util.List;
-
 import org.apache.dubbo.qos.command.GreetingCommand;
 import org.apache.dubbo.qos.command.impl.ChangeTelnet;
 import org.apache.dubbo.qos.command.impl.CountTelnet;
@@ -28,6 +25,7 @@ import 
org.apache.dubbo.qos.command.impl.DisableSimpleProfiler;
 import org.apache.dubbo.qos.command.impl.EnableDetailProfiler;
 import org.apache.dubbo.qos.command.impl.EnableRouterSnapshot;
 import org.apache.dubbo.qos.command.impl.EnableSimpleProfiler;
+import org.apache.dubbo.qos.command.impl.GetConfig;
 import org.apache.dubbo.qos.command.impl.GetEnabledRouterSnapshot;
 import org.apache.dubbo.qos.command.impl.GetRecentRouterSnapshot;
 import org.apache.dubbo.qos.command.impl.GetRouterSnapshot;
@@ -57,8 +55,12 @@ import org.apache.dubbo.qos.command.impl.SwitchLogLevel;
 import org.apache.dubbo.qos.command.impl.SwitchLogger;
 import org.apache.dubbo.qos.command.impl.Version;
 import org.apache.dubbo.rpc.model.FrameworkModel;
+
 import org.junit.jupiter.api.Test;
 
+import java.util.LinkedList;
+import java.util.List;
+
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.containsInAnyOrder;
 import static org.hamcrest.Matchers.equalTo;
@@ -118,6 +120,7 @@ class CommandHelperTest {
         expectedClasses.add(SwitchLogLevel.class);
         expectedClasses.add(SerializeCheckStatus.class);
         expectedClasses.add(SerializeWarnedClasses.class);
+        expectedClasses.add(GetConfig.class);
         assertThat(classes, containsInAnyOrder(expectedClasses.toArray(new 
Class<?>[0])));
     }
 


Reply via email to