Fix notice and opt registry source (#913)

* update year

* fix search

* add relation support

* disable swagger
diff --git a/NOTICE b/NOTICE
index 6367c40..9776704 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,5 +1,5 @@
 Apache Dubbo Admin
-Copyright 2018-2021 The Apache Software Foundation
+Copyright 2018-2022 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
diff --git a/dubbo-admin-distribution/src/NOTICE b/dubbo-admin-distribution/src/NOTICE
index df92423..05c73d6 100644
--- a/dubbo-admin-distribution/src/NOTICE
+++ b/dubbo-admin-distribution/src/NOTICE
@@ -1,5 +1,5 @@
 Apache Dubbo Admin
-Copyright 2018-2021 The Apache Software Foundation
+Copyright 2018-2022 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
@@ -100,7 +100,7 @@
 
 ========================================================================
 Apache Dubbo
-Copyright 2018-2021 The Apache Software Foundation
+Copyright 2018-2022 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/SyncUtils.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/SyncUtils.java
index 7a36c0b..1c8188b 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/SyncUtils.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/common/util/SyncUtils.java
@@ -57,7 +57,7 @@
         p.setService(service);
         p.setAddress(url.getAddress());
         p.setApplication(url.getParameter(Constants.APPLICATION_KEY));
-        p.setUrl(url.toIdentityString());
+        p.setUrl(url.toFullString());
         p.setParameters(url.toParameterString());
 
         p.setDynamic(url.getParameter("dynamic", true));
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/SwaggerConfiguration.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/SwaggerConfiguration.java
index 7f773a4..ef44250 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/SwaggerConfiguration.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/config/SwaggerConfiguration.java
@@ -30,7 +30,7 @@
 
 @Configuration
 @EnableSwagger2
-@ConditionalOnProperty(name = "swagger.enable", havingValue = "true", matchIfMissing = true)
+@ConditionalOnProperty(name = "swagger.enable", havingValue = "true")
 public class SwaggerConfiguration {
     @Bean
     public Docket createRestApi() {
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Entity.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Entity.java
index 3982d62..9778d1b 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Entity.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Entity.java
@@ -19,10 +19,10 @@
 import java.io.Serializable;
 import java.util.Date;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Entity
- *
  */
 public abstract class Entity implements Serializable {
 
@@ -128,4 +128,20 @@
         this.miss = miss;
     }
 
+    @java.lang.Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        Entity entity = (Entity) o;
+        return miss == entity.miss && Objects.equals(ids, entity.ids) && Objects.equals(id, entity.id) && Objects.equals(hash, entity.hash) && Objects.equals(created, entity.created) && Objects.equals(modified, entity.modified) && Objects.equals(now, entity.now) && Objects.equals(operator, entity.operator) && Objects.equals(operatorAddress, entity.operatorAddress);
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+        return Objects.hash(ids, id, hash, created, modified, now, operator, operatorAddress, miss);
+    }
 }
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Provider.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Provider.java
index 2de0ad0..182225b 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Provider.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/Provider.java
@@ -23,10 +23,10 @@
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 
 /**
  * Provider
- *
  */
 public class Provider extends Entity {
 
@@ -221,4 +221,33 @@
         return url;
     }
 
+    public boolean equalsWithoutRegistry(Provider provider) {
+        if (this == provider) {
+            return true;
+        }
+        if (!super.equals(provider)) {
+            return false;
+        }
+        return dynamic == provider.dynamic && enabled == provider.enabled && weight == provider.weight && alived == provider.alived && Objects.equals(service, provider.service) && Objects.equals(parameters, provider.parameters) && Objects.equals(address, provider.address) && Objects.equals(registry, provider.registry) && Objects.equals(application, provider.application) && Objects.equals(username, provider.username) && Objects.equals(expired, provider.expired) && Objects.equals(override, provider.override) && Objects.equals(overrides, provider.overrides);
+    }
+
+    @java.lang.Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        if (!super.equals(o)) {
+            return false;
+        }
+        Provider provider = (Provider) o;
+        return dynamic == provider.dynamic && enabled == provider.enabled && weight == provider.weight && alived == provider.alived && Objects.equals(service, provider.service) && Objects.equals(url, provider.url) && Objects.equals(parameters, provider.parameters) && Objects.equals(address, provider.address) && Objects.equals(registry, provider.registry) && Objects.equals(application, provider.application) && Objects.equals(username, provider.username) && Objects.equals(expired, provider.expired) && Objects.equals(override, provider.override) && Objects.equals(overrides, provider.overrides) && registrySource == provider.registrySource;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), service, url, parameters, address, registry, dynamic, enabled, weight, application, username, expired, alived, override, overrides, registrySource);
+    }
 }
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/RegistrySource.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/RegistrySource.java
index e54644c..a6a9939 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/RegistrySource.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/model/domain/RegistrySource.java
@@ -19,6 +19,8 @@
 
 public enum RegistrySource {
 
+    ALL,
+
     INTERFACE,
 
     INSTANCE
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/AdminMappingListener.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/AdminMappingListener.java
index d6ffcc7..40b36da 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/AdminMappingListener.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/mapping/AdminMappingListener.java
@@ -115,6 +115,7 @@
                 List<InstanceAddressURL> instanceAddressUrls = urls.stream().map(url -> (InstanceAddressURL) url).collect(Collectors.toList());
                 serviceMap.put(serviceKey, instanceAddressUrls);
             }
+            instanceRegistryCache.refreshConsumer(false);
         }
 
         private String removeProtocol(String protocolServiceKey) {
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/metadata/impl/NacosMetaDataCollector.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/metadata/impl/NacosMetaDataCollector.java
index 4379eca..f03ca39 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/metadata/impl/NacosMetaDataCollector.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/registry/metadata/impl/NacosMetaDataCollector.java
@@ -110,8 +110,11 @@
 
     private String getMetaData(MetadataIdentifier identifier) {
         try {
-            return configService.getConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY),
-                    group, 1000 * 10);
+            String fromDubboGroup = configService.getConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY),
+                    "dubbo", 1000 * 10);
+            return org.apache.dubbo.common.utils.StringUtils.isNotEmpty(fromDubboGroup) ? fromDubboGroup :
+                    configService.getConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY),
+                            group, 1000 * 10);
         } catch (NacosException e) {
             logger.warn("Failed to get " + identifier + " from nacos, cause: " + e.getMessage(), e);
         }
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ConsumerServiceImpl.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ConsumerServiceImpl.java
index 0d0f2e5..8395026 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ConsumerServiceImpl.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ConsumerServiceImpl.java
@@ -24,6 +24,8 @@
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
+
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.util.HashMap;
@@ -33,15 +35,22 @@
 @Component
 public class ConsumerServiceImpl extends AbstractService implements ConsumerService {
 
+    @Autowired
+    private InstanceRegistryQueryHelper instanceRegistryQueryHelper;
+
     @Override
     public List<Consumer> findByService(String service) {
-        return SyncUtils.url2ConsumerList(findConsumerUrlByService(service));
+        List<Consumer> consumers = SyncUtils.url2ConsumerList(findConsumerUrlByService(service));
+        consumers.addAll(instanceRegistryQueryHelper.findConsumerByService(service));
+        return consumers;
     }
 
 
     @Override
     public List<Consumer> findAll() {
-        return SyncUtils.url2ConsumerList(findAllConsumerUrl());
+        List<Consumer> consumers = SyncUtils.url2ConsumerList(findAllConsumerUrl());
+        consumers.addAll(instanceRegistryQueryHelper.findAllConsumer());
+        return consumers;
     }
 
     @Override
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryCache.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryCache.java
index 9f1b5ac..520f0db 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryCache.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryCache.java
@@ -17,16 +17,29 @@
 
 package org.apache.dubbo.admin.service.impl;
 
+import org.apache.dubbo.admin.common.util.Constants;
 import org.apache.dubbo.admin.service.RegistryCache;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.NamedThreadFactory;
+import org.apache.dubbo.metadata.MetadataService;
 import org.apache.dubbo.registry.client.InstanceAddressURL;
+import org.apache.dubbo.registry.client.metadata.MetadataUtils;
+import org.apache.dubbo.rpc.service.Destroyable;
 
 import org.springframework.stereotype.Component;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.function.Function;
+import java.util.stream.Collectors;
 
 /**
  * instance registry url {@link InstanceAddressURL} cache
@@ -37,6 +50,10 @@
 
     private final ConcurrentMap<String, ConcurrentMap<String, Map<String, List<InstanceAddressURL>>>> registryCache = new ConcurrentHashMap<>();
 
+    private final Map<String, Map<String, List<URL>>> subscribedCache = new ConcurrentHashMap<>();
+
+    private final AtomicBoolean startRefresh = new AtomicBoolean(false);
+
     @Override
     public void put(String key, ConcurrentMap<String, Map<String, List<InstanceAddressURL>>> value) {
         registryCache.put(key, value);
@@ -52,4 +69,44 @@
                                                                                         Function<? super String, ? extends ConcurrentMap<String, Map<String, List<InstanceAddressURL>>>> mappingFunction) {
         return registryCache.computeIfAbsent(key, mappingFunction);
     }
+
+    public Map<String, Map<String, List<URL>>> getSubscribedCache() {
+        return subscribedCache;
+    }
+
+    public synchronized void refreshConsumer(boolean refreshAll) {
+        if (startRefresh.compareAndSet(false, true)) {
+            ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("Consumer-Refresh"));
+            executorService.scheduleAtFixedRate(() -> refreshConsumer(true), 60, 60, TimeUnit.MINUTES);
+        }
+
+        Map<String, Map<String, List<URL>>> origin;
+
+        if (refreshAll) {
+            origin = new ConcurrentHashMap<>();
+        } else {
+            origin = subscribedCache;
+        }
+
+        Map<String, List<InstanceAddressURL>> providers = get(Constants.PROVIDERS_CATEGORY).values().stream()
+                .flatMap((e) -> e.values().stream())
+                .flatMap(Collection::stream)
+                .collect(Collectors.groupingBy(InstanceAddressURL::getAddress));
+
+        // remove cached
+        origin.keySet().forEach(providers::remove);
+
+        for (List<InstanceAddressURL> instanceAddressURLs : providers.values()) {
+            MetadataService metadataService = MetadataUtils.referProxy(instanceAddressURLs.get(0).getInstance());
+            try {
+                Set<String> subscribedURLs = metadataService.getSubscribedURLs();
+
+                Map<String, List<URL>> subscribed = subscribedURLs.stream().map(URL::valueOf).collect(Collectors.groupingBy(URL::getServiceKey));
+                origin.put(instanceAddressURLs.get(0).getAddress(), subscribed);
+            } catch (Throwable ignored) {
+
+            }
+            ((Destroyable) metadataService).$destroy();
+        }
+    }
 }
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryQueryHelper.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryQueryHelper.java
index aae6e65..36793b7 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryQueryHelper.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/InstanceRegistryQueryHelper.java
@@ -18,17 +18,24 @@
 package org.apache.dubbo.admin.service.impl;
 
 import org.apache.dubbo.admin.common.util.Constants;
+import org.apache.dubbo.admin.common.util.Pair;
+import org.apache.dubbo.admin.common.util.SyncUtils;
+import org.apache.dubbo.admin.model.domain.Consumer;
 import org.apache.dubbo.admin.model.domain.Provider;
 import org.apache.dubbo.admin.model.domain.RegistrySource;
+import org.apache.dubbo.common.URLBuilder;
+import org.apache.dubbo.common.url.component.ServiceConfigURL;
 import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.metadata.MetadataInfo;
 import org.apache.dubbo.registry.client.InstanceAddressURL;
 import org.apache.dubbo.registry.client.ServiceInstance;
+import org.apache.dubbo.rpc.RpcContext;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import org.springframework.stereotype.Component;
 
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -85,6 +92,23 @@
                 .collect(Collectors.toList());
     }
 
+    public List<Consumer> findAllConsumer() {
+        return instanceRegistryCache.getSubscribedCache().values().stream()
+                .flatMap(m -> m.values().stream())
+                .flatMap(Collection::stream)
+                .map(m -> new Pair<>(m.toFullString(), m))
+                .map(SyncUtils::url2Consumer)
+                .collect(Collectors.toList());
+    }
+
+    public List<Consumer> findConsumerByService(String serviceName) {
+        return instanceRegistryCache.getSubscribedCache().values().stream().filter(m -> m.containsKey(serviceName))
+                .flatMap(m -> m.get(serviceName).stream())
+                .map(m -> new Pair<>(m.toFullString(), m))
+                .map(SyncUtils::url2Consumer)
+                .collect(Collectors.toList());
+    }
+
     public List<Provider> findByAddress(String providerAddress) {
         ConcurrentMap<String, Map<String, List<InstanceAddressURL>>> appInterfaceMap = instanceRegistryCache.get(Constants.PROVIDERS_CATEGORY);
         if (appInterfaceMap == null) {
@@ -136,18 +160,30 @@
             MetadataInfo metadataInfo = url.getMetadataInfo();
 
             metadataInfo.getServices().forEach((serviceKey, serviceInfo) -> {
+                // build consumer url
+
+                ServiceConfigURL consumerUrl = new URLBuilder()
+                        .setProtocol(serviceInfo.getProtocol())
+                        .setPath(serviceInfo.getPath())
+                        .addParameter("group", serviceInfo.getGroup())
+                        .addParameter("version", serviceInfo.getVersion())
+                        .build();
+                RpcContext.getServiceContext().setConsumerUrl(consumerUrl);
+
                 Provider p = new Provider();
                 String service = serviceInfo.getServiceKey();
                 p.setService(service);
                 p.setAddress(url.getAddress());
                 p.setApplication(instance.getServiceName());
-                p.setUrl(url.toParameterString());
+                p.setUrl(url.toFullString());
                 p.setDynamic(url.getParameter("dynamic", true));
                 p.setEnabled(url.getParameter(Constants.ENABLED_KEY, true));
                 p.setWeight(url.getParameter(Constants.WEIGHT_KEY, Constants.DEFAULT_WEIGHT));
                 p.setUsername(url.getParameter("owner"));
                 p.setRegistrySource(RegistrySource.INSTANCE);
                 providers.add(p);
+
+                RpcContext.getServiceContext().setConsumerUrl(null);
             });
         });
         return providers;
diff --git a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ProviderServiceImpl.java b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ProviderServiceImpl.java
index 1defce7..5e09ed7 100644
--- a/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ProviderServiceImpl.java
+++ b/dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/impl/ProviderServiceImpl.java
@@ -21,10 +21,12 @@
 import org.apache.dubbo.admin.common.util.SyncUtils;
 import org.apache.dubbo.admin.common.util.Tool;
 import org.apache.dubbo.admin.model.domain.Provider;
+import org.apache.dubbo.admin.model.domain.RegistrySource;
 import org.apache.dubbo.admin.model.dto.ServiceDTO;
 import org.apache.dubbo.admin.service.ProviderService;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
+
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -292,19 +294,40 @@
      */
     public Set<ServiceDTO> convertProviders2DTO(List<Provider> providers) {
         Set<ServiceDTO> result = new TreeSet<>();
-        for (Provider provider : providers) {
-            String app = provider.getApplication();
-            String service = provider.getService();
+        Map<String, List<Provider>> providerMap = providers.stream().collect(Collectors.groupingBy(Provider::getService));
+        for (Map.Entry<String, List<Provider>> entry : providerMap.entrySet()) {
+            String service = entry.getKey();
             String group = Tool.getGroup(service);
             String version = Tool.getVersion(service);
             String interfaze = Tool.getInterface(service);
-            ServiceDTO s = new ServiceDTO();
-            s.setAppName(app);
-            s.setService(interfaze);
-            s.setGroup(group);
-            s.setVersion(version);
-            s.setRegistrySource(provider.getRegistrySource());
-            result.add(s);
+
+            List<Provider> value = entry.getValue();
+            if (value.size() == 1) {
+                Provider provider = value.get(0);
+                ServiceDTO s = new ServiceDTO();
+                s.setAppName(provider.getApplication());
+                s.setService(interfaze);
+                s.setGroup(group);
+                s.setVersion(version);
+                s.setRegistrySource(provider.getRegistrySource());
+                result.add(s);
+            } else {
+                String app = value.stream().map(Provider::getApplication).distinct().collect(Collectors.joining(", "));
+                RegistrySource registrySource = value.get(0).getRegistrySource();
+
+                boolean matchInterface = value.stream().map(Provider::getRegistrySource).anyMatch(e -> e.equals(RegistrySource.INTERFACE));
+                boolean matchInstance = value.stream().map(Provider::getRegistrySource).anyMatch(e -> e.equals(RegistrySource.INSTANCE));
+                if (matchInterface && matchInstance) {
+                    registrySource = RegistrySource.ALL;
+                }
+                ServiceDTO s = new ServiceDTO();
+                s.setAppName(app);
+                s.setService(interfaze);
+                s.setGroup(group);
+                s.setVersion(version);
+                s.setRegistrySource(registrySource);
+                result.add(s);
+            }
         }
         return result;
     }
diff --git a/dubbo-admin-ui/src/components/ServiceDetail.vue b/dubbo-admin-ui/src/components/ServiceDetail.vue
index 79fa779..3f9121e 100644
--- a/dubbo-admin-ui/src/components/ServiceDetail.vue
+++ b/dubbo-admin-ui/src/components/ServiceDetail.vue
@@ -211,6 +211,7 @@
               this.providerDetails = response.data.providers
               const instanceRegistry = this.$t('instanceRegistry')
               const interfaceRegistry = this.$t('interfaceRegistry')
+              const allRegistry = this.$t('allRegistry')
               for (let i = 0; i < this.providerDetails.length; i++) {
                 if (this.providerDetails[i].registrySource === 'INSTANCE') {
                   this.providerDetails[i].registrySource = instanceRegistry
@@ -218,6 +219,9 @@
                 if (this.providerDetails[i].registrySource === 'INTERFACE') {
                   this.providerDetails[i].registrySource = interfaceRegistry
                 }
+                if (this.providerDetails[i].registrySource === 'ALL') {
+                  this.providerDetails[i].registrySource = allRegistry
+                }
                 console.log(this.providerDetails[i])
                 this.$set(this.providerDetails[i], 'hint', 'url')
               }
diff --git a/dubbo-admin-ui/src/components/public/Footers.vue b/dubbo-admin-ui/src/components/public/Footers.vue
index 6ad8ae6..08e4016 100644
--- a/dubbo-admin-ui/src/components/public/Footers.vue
+++ b/dubbo-admin-ui/src/components/public/Footers.vue
@@ -18,7 +18,7 @@
 <template>
   <v-footer inset height="auto" class="pa-3 footer-border-top">
     <v-spacer></v-spacer>
-    <span class="caption mr-1"><strong>Copyright</strong> &copy;2018-2021 <strong>The Apache Software Foundation.</strong></span>
+    <span class="caption mr-1"><strong>Copyright</strong> &copy;2018-2022 <strong>The Apache Software Foundation.</strong></span>
   </v-footer>
 </template>
 <script>
diff --git a/dubbo-admin-ui/src/lang/en.js b/dubbo-admin-ui/src/lang/en.js
index c84fd7a..f534e81 100644
--- a/dubbo-admin-ui/src/lang/en.js
+++ b/dubbo-admin-ui/src/lang/en.js
@@ -49,6 +49,7 @@
   registrySource: 'Registry Source',
   instanceRegistry: 'Instance Registry',
   interfaceRegistry: 'Interface Registry',
+  allRegistry: 'Instance / Interface Registry',
   operation: 'Operation',
   searchResult: 'Search Result',
   search: 'Search',
diff --git a/dubbo-admin-ui/src/lang/zh.js b/dubbo-admin-ui/src/lang/zh.js
index fa979c4..2b97382 100644
--- a/dubbo-admin-ui/src/lang/zh.js
+++ b/dubbo-admin-ui/src/lang/zh.js
@@ -49,6 +49,7 @@
   registrySource: '注册来源',
   instanceRegistry: '应用级',
   interfaceRegistry: '接口级',
+  allRegistry: '应用级/接口级',
   operation: '操作',
   searchResult: '查询结果',
   search: '搜索',