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 ffb28bc85e Introduce get address command (#11682)
ffb28bc85e is described below

commit ffb28bc85e44a16d7aff61954e753b625cc9bab4
Author: Albumen Kevin <[email protected]>
AuthorDate: Tue Apr 11 14:19:43 2023 +0800

    Introduce get address command (#11682)
    
    * Introduce get address command
    
    * Fix import
---
 .../apache/dubbo/qos/command/impl/GetAddress.java  | 222 +++++++++++++++++++++
 .../internal/org.apache.dubbo.qos.api.BaseCommand  |   1 +
 .../dubbo/qos/command/util/CommandHelperTest.java  |   2 +
 3 files changed, 225 insertions(+)

diff --git 
a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetAddress.java
 
b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetAddress.java
new file mode 100644
index 0000000000..c65c11b47a
--- /dev/null
+++ 
b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/GetAddress.java
@@ -0,0 +1,222 @@
+/*
+ * 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.URL;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.utils.JsonUtils;
+import org.apache.dubbo.qos.api.BaseCommand;
+import org.apache.dubbo.qos.api.Cmd;
+import org.apache.dubbo.qos.api.CommandContext;
+import org.apache.dubbo.qos.api.PermissionLevel;
+import org.apache.dubbo.registry.Registry;
+import org.apache.dubbo.registry.client.migration.MigrationInvoker;
+import org.apache.dubbo.registry.client.migration.model.MigrationStep;
+import org.apache.dubbo.rpc.RpcContext;
+import org.apache.dubbo.rpc.cluster.ClusterInvoker;
+import org.apache.dubbo.rpc.cluster.Directory;
+import org.apache.dubbo.rpc.cluster.directory.AbstractDirectory;
+import org.apache.dubbo.rpc.model.ConsumerModel;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+import org.apache.dubbo.rpc.model.FrameworkServiceRepository;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+@Cmd(name = "getAddress",
+    summary = "Get service available address ",
+    example = {"getAddress com.example.DemoService", "getAddress 
group/com.example.DemoService"},
+    requiredPermissionLevel = PermissionLevel.PRIVATE)
+public class GetAddress implements BaseCommand {
+    public final FrameworkServiceRepository serviceRepository;
+
+    public GetAddress(FrameworkModel frameworkModel) {
+        this.serviceRepository = frameworkModel.getServiceRepository();
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public String execute(CommandContext commandContext, String[] args) {
+        if (args == null || args.length != 1) {
+            return "Invalid parameters, please input like getAddress 
com.example.DemoService";
+        }
+
+        String serviceName = args[0];
+
+        StringBuilder plainOutput = new StringBuilder();
+        Map<String, Object> jsonOutput = new HashMap<>();
+
+        for (ConsumerModel consumerModel : 
serviceRepository.allConsumerModels()) {
+            if (serviceName.equals(consumerModel.getServiceKey())) {
+                appendConsumer(plainOutput, jsonOutput, consumerModel);
+            }
+        }
+
+        if (commandContext.isHttp()) {
+            return JsonUtils.getJson().toJson(jsonOutput);
+        } else {
+            return plainOutput.toString();
+        }
+    }
+
+    private static void appendConsumer(StringBuilder plainOutput, Map<String, 
Object> jsonOutput, ConsumerModel consumerModel) {
+        plainOutput.append("ConsumerModel: ")
+            .append(consumerModel.getServiceKey())
+            .append("@")
+            
.append(Integer.toHexString(System.identityHashCode(consumerModel)))
+            .append("\n\n");
+        Map<String, Object> consumerMap = new HashMap<>();
+        jsonOutput.put(consumerModel.getServiceKey() + "@" + 
Integer.toHexString(System.identityHashCode(consumerModel)), consumerMap);
+
+        Object object = 
consumerModel.getServiceMetadata().getAttribute(CommonConstants.CURRENT_CLUSTER_INVOKER_KEY);
+        Map<Registry, MigrationInvoker<?>> invokerMap;
+        if (object instanceof Map) {
+            invokerMap = (Map<Registry, MigrationInvoker<?>>) object;
+            for (Map.Entry<Registry, MigrationInvoker<?>> entry : 
invokerMap.entrySet()) {
+                appendInvokers(plainOutput, consumerMap, entry);
+            }
+        }
+    }
+
+    private static void appendInvokers(StringBuilder plainOutput, Map<String, 
Object> consumerMap, Map.Entry<Registry, MigrationInvoker<?>> entry) {
+        URL registryUrl = entry.getKey().getUrl();
+
+        plainOutput.append("Registry: ")
+            .append(registryUrl)
+            .append("\n");
+        Map<String, Object> registryMap = new HashMap<>();
+        consumerMap.put(registryUrl.toString(), registryMap);
+
+        MigrationInvoker<?> migrationInvoker = entry.getValue();
+
+        MigrationStep migrationStep = migrationInvoker.getMigrationStep();
+        plainOutput.append("MigrationStep: ")
+            .append(migrationStep)
+            .append("\n\n");
+        registryMap.put("MigrationStep", migrationStep);
+
+        Map<String, Object> invokersMap = new HashMap<>();
+        registryMap.put("Invokers", invokersMap);
+
+        URL originConsumerUrl = 
RpcContext.getServiceContext().getConsumerUrl();
+        
RpcContext.getServiceContext().setConsumerUrl(migrationInvoker.getConsumerUrl());
+
+        appendInterfaceLevel(plainOutput, migrationInvoker, invokersMap);
+        appendAppLevel(plainOutput, migrationInvoker, invokersMap);
+
+        RpcContext.getServiceContext().setConsumerUrl(originConsumerUrl);
+    }
+
+    private static void appendAppLevel(StringBuilder plainOutput, 
MigrationInvoker<?> migrationInvoker, Map<String, Object> invokersMap) {
+        Map<String, Object> appMap = new HashMap<>();
+        invokersMap.put("Application-Level", appMap);
+        Optional.ofNullable(migrationInvoker.getServiceDiscoveryInvoker())
+            .ifPresent(i -> plainOutput.append("Application-Level: \n"));
+        Optional.ofNullable(migrationInvoker.getServiceDiscoveryInvoker())
+            .map(ClusterInvoker::getDirectory)
+            .map(Directory::getAllInvokers)
+            .ifPresent(invokers -> {
+                List<String> invokerUrls = new LinkedList<>();
+                plainOutput.append("All Invokers: \n");
+                for (org.apache.dubbo.rpc.Invoker<?> invoker : invokers) {
+                    invokerUrls.add(invoker.getUrl().toFullString());
+                    
plainOutput.append(invoker.getUrl().toFullString()).append("\n");
+                }
+                plainOutput.append("\n");
+                appMap.put("All", invokerUrls);
+            });
+        Optional.ofNullable(migrationInvoker.getServiceDiscoveryInvoker())
+            .map(ClusterInvoker::getDirectory)
+            .map(s -> (AbstractDirectory<?>) s)
+            .map(AbstractDirectory::getValidInvokers)
+            .ifPresent(invokers -> {
+                List<String> invokerUrls = new LinkedList<>();
+                plainOutput.append("Valid Invokers: \n");
+                for (org.apache.dubbo.rpc.Invoker<?> invoker : invokers) {
+                    invokerUrls.add(invoker.getUrl().toFullString());
+                    
plainOutput.append(invoker.getUrl().toFullString()).append("\n");
+                }
+                plainOutput.append("\n");
+                appMap.put("Valid", invokerUrls);
+            });
+        Optional.ofNullable(migrationInvoker.getServiceDiscoveryInvoker())
+            .map(ClusterInvoker::getDirectory)
+            .map(s -> (AbstractDirectory<?>) s)
+            .map(AbstractDirectory::getDisabledInvokers)
+            .ifPresent(invokers -> {
+                List<String> invokerUrls = new LinkedList<>();
+                plainOutput.append("Disabled Invokers: \n");
+                for (org.apache.dubbo.rpc.Invoker<?> invoker : invokers) {
+                    invokerUrls.add(invoker.getUrl().toFullString());
+                    
plainOutput.append(invoker.getUrl().toFullString()).append("\n");
+                }
+                plainOutput.append("\n");
+                appMap.put("Disabled", invokerUrls);
+            });
+    }
+
+    private static void appendInterfaceLevel(StringBuilder plainOutput, 
MigrationInvoker<?> migrationInvoker, Map<String, Object> invokersMap) {
+        Map<String, Object> interfaceMap = new HashMap<>();
+        invokersMap.put("Interface-Level", interfaceMap);
+        Optional.ofNullable(migrationInvoker.getInvoker())
+            .ifPresent(i -> plainOutput.append("Interface-Level: \n"));
+        Optional.ofNullable(migrationInvoker.getInvoker())
+            .map(ClusterInvoker::getDirectory)
+            .map(Directory::getAllInvokers)
+            .ifPresent(invokers -> {
+                List<String> invokerUrls = new LinkedList<>();
+                plainOutput.append("All Invokers: \n");
+                for (org.apache.dubbo.rpc.Invoker<?> invoker : invokers) {
+                    invokerUrls.add(invoker.getUrl().toFullString());
+                    
plainOutput.append(invoker.getUrl().toFullString()).append("\n");
+                }
+                plainOutput.append("\n");
+                interfaceMap.put("All", invokerUrls);
+            });
+        Optional.ofNullable(migrationInvoker.getInvoker())
+            .map(ClusterInvoker::getDirectory)
+            .map(s -> (AbstractDirectory<?>) s)
+            .map(AbstractDirectory::getValidInvokers)
+            .ifPresent(invokers -> {
+                List<String> invokerUrls = new LinkedList<>();
+                plainOutput.append("Valid Invokers: \n");
+                for (org.apache.dubbo.rpc.Invoker<?> invoker : invokers) {
+                    invokerUrls.add(invoker.getUrl().toFullString());
+                    
plainOutput.append(invoker.getUrl().toFullString()).append("\n");
+                }
+                plainOutput.append("\n");
+                interfaceMap.put("Valid", invokerUrls);
+            });
+        Optional.ofNullable(migrationInvoker.getInvoker())
+            .map(ClusterInvoker::getDirectory)
+            .map(s -> (AbstractDirectory<?>) s)
+            .map(AbstractDirectory::getDisabledInvokers)
+            .ifPresent(invokers -> {
+                List<String> invokerUrls = new LinkedList<>();
+                plainOutput.append("Disabled Invokers: \n");
+                for (org.apache.dubbo.rpc.Invoker<?> invoker : invokers) {
+                    invokerUrls.add(invoker.getUrl().toFullString());
+                    
plainOutput.append(invoker.getUrl().toFullString()).append("\n");
+                }
+                plainOutput.append("\n");
+                interfaceMap.put("Disabled", invokerUrls);
+            });
+    }
+}
diff --git 
a/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.api.BaseCommand
 
b/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.api.BaseCommand
index c28bf0d97b..78825644ed 100644
--- 
a/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.api.BaseCommand
+++ 
b/dubbo-plugin/dubbo-qos/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.qos.api.BaseCommand
@@ -35,3 +35,4 @@ 
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
+getAddress=org.apache.dubbo.qos.command.impl.GetAddress
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 b7f519ee42..a06a76408c 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
@@ -25,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.GetAddress;
 import org.apache.dubbo.qos.command.impl.GetConfig;
 import org.apache.dubbo.qos.command.impl.GetEnabledRouterSnapshot;
 import org.apache.dubbo.qos.command.impl.GetRecentRouterSnapshot;
@@ -121,6 +122,7 @@ class CommandHelperTest {
         expectedClasses.add(SerializeCheckStatus.class);
         expectedClasses.add(SerializeWarnedClasses.class);
         expectedClasses.add(GetConfig.class);
+        expectedClasses.add(GetAddress.class);
         assertThat(classes, containsInAnyOrder(expectedClasses.toArray(new 
Class<?>[0])));
     }
 

Reply via email to