public void notify()

in dubbo-admin-server/src/main/java/org/apache/dubbo/admin/service/RegistryServerSync.java [94:181]


    public void notify(List<URL> urls) {
        if (urls == null || urls.isEmpty()) {
            return;
        }
        // Map<category, Map<servicename, Map<Long, URL>>>
        final Map<String, Map<String, Map<String, URL>>> categories = new HashMap<>();
        String interfaceName = null;
        for (URL url : urls) {
            if (url instanceof InstanceAddressURL) {
                continue;
            }
            String category = url.getUrlParam().getParameter(Constants.CATEGORY_KEY);
            if (category == null) {
                // Assign an initial value to category according to the information in url
                if (Constants.CONSUMER_SIDE.equals(url.getSide()) || Constants.CONSUMER_PROTOCOL.equals(url.getProtocol())) {
                    category = Constants.CONSUMERS_CATEGORY;
                } else {
                    category = Constants.PROVIDERS_CATEGORY;
                }
            }
            // NOTE: group and version in empty protocol is *
            if (Constants.EMPTY_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
                ConcurrentMap<String, Map<String, URL>> services = interfaceRegistryCache.get(category);
                if (services != null) {
                    String group = url.getUrlParam().getParameter(Constants.GROUP_KEY);
                    String version = url.getUrlParam().getParameter(Constants.VERSION_KEY);
                    // NOTE: group and version in empty protocol is *
                    if (!Constants.ANY_VALUE.equals(group) && !Constants.ANY_VALUE.equals(version)) {
                        services.remove(getServiceInterface(url));
                    } else {
                        for (Map.Entry<String, Map<String, URL>> serviceEntry : services.entrySet()) {
                            String service = serviceEntry.getKey();
                            if (Tool.getInterface(service).equals(getServiceInterface(url))
                                    && (Constants.ANY_VALUE.equals(group) || StringUtils.isEquals(group, Tool.getGroup(service)))
                                    && (Constants.ANY_VALUE.equals(version) || StringUtils.isEquals(version, Tool.getVersion(service)))) {
                                services.remove(service);
                            }
                        }
                    }
                }
            } else {
                if (StringUtils.isEmpty(interfaceName)) {
                    interfaceName = getServiceInterface(url);
                }
                Map<String, Map<String, URL>> services = categories.get(category);
                if (services == null) {
                    services = new HashMap<>();
                    categories.put(category, services);
                }
                String group = url.getUrlParam().getParameter(Constants.GROUP_KEY);
                String version = url.getUrlParam().getParameter(Constants.VERSION_KEY);
                String service = BaseServiceMetadata.buildServiceKey(getServiceInterface(url), group, version);
                Map<String, URL> ids = services.get(service);
                if (ids == null) {
                    ids = new HashMap<>();
                    services.put(service, ids);
                }

                // Make sure we use the same ID for the same URL
                if (URL_IDS_MAPPER.containsKey(url.toFullString())) {
                    ids.put(URL_IDS_MAPPER.get(url.toFullString()), url);
                } else {
                    String md5 = CoderUtil.MD5_16bit(url.toFullString());
                    ids.put(md5, url);
                    URL_IDS_MAPPER.putIfAbsent(url.toFullString(), md5);
                }
            }
        }
        if (categories.size() == 0) {
            return;
        }
        for (Map.Entry<String, Map<String, Map<String, URL>>> categoryEntry : categories.entrySet()) {
            String category = categoryEntry.getKey();
            ConcurrentMap<String, Map<String, URL>> services = interfaceRegistryCache.get(category);
            if (services == null) {
                services = new ConcurrentHashMap<>();
                interfaceRegistryCache.put(category, services);
            } else {// Fix map can not be cleared when service is unregistered: when a unique “group/service:version” service is unregistered, but we still have the same services with different version or group, so empty protocols can not be invoked.
                Set<String> keys = new HashSet<>(services.keySet());
                for (String key : keys) {
                    if (Tool.getInterface(key).equals(interfaceName) && !categoryEntry.getValue().containsKey(key)) {
                        services.remove(key);
                    }
                }
            }
            services.putAll(categoryEntry.getValue());
        }
    }