@Override public void init(DiscoveryContext context, DiscoveryTreeNode parent) { Map<String, MicroserviceInstance> instances = parent.data(); Map<String, MicroserviceInstance> filteredServers = new HashMap<>(); for (String key : instances.keySet()) { MicroserviceInstance instance = instances.get(key); if (MicroserviceInstanceStatus.UP == instance.getStatus()) { filteredServers.put(key, instance); } } if (filteredServers.isEmpty()) { return; } DiscoveryTreeNode child = new DiscoveryTreeNode().subName(parent, UP_INSTANCES).data(filteredServers); parent.child(UP_INSTANCES, child); } }
@Override protected void init(DiscoveryContext context, DiscoveryTreeNode parent) { MicroserviceInstance myself = RegistryUtils.getMicroserviceInstance(); Map<String, MicroserviceInstance> instancesRegionAndAZMatch = new HashMap<>(); Map<String, MicroserviceInstance> instancesAZMatch = new HashMap<>(); Map<String, MicroserviceInstance> instancesNoMatch = new HashMap<>(); Map<String, MicroserviceInstance> instances = parent.data(); for (String id : instances.keySet()) { MicroserviceInstance target = instances.get(id); if (regionAndAZMatch(myself, target)) { instancesRegionAndAZMatch.put(id, target); } else if (regionMatch(myself, target)) { instancesAZMatch.put(id, target); } else { instancesNoMatch.put(id, target); } } Map<String, DiscoveryTreeNode> children = new HashMap<>(); children.put(GROUP_RegionAndAZMatch, new DiscoveryTreeNode() .subName(parent, GROUP_RegionAndAZMatch) .data(instancesRegionAndAZMatch)); children.put(GROUP_instancesAZMatch, new DiscoveryTreeNode() .subName(parent, GROUP_instancesAZMatch) .data(instancesAZMatch)); children.put(GROUP_instancesNoMatch, new DiscoveryTreeNode() .subName(parent, GROUP_instancesNoMatch) .data(instancesNoMatch)); parent.children(children); }
@SuppressWarnings("unchecked") protected DiscoveryTreeNode createDiscoveryTreeNode(DiscoveryContext context, DiscoveryTreeNode parent) { String serviceName = context.getInputParameters(); List<Object> instances = new ArrayList<>(); for (MicroserviceInstance instance : ((Map<String, MicroserviceInstance>) parent.data()).values()) { for (String endpoint : instance.getEndpoints()) { String scheme = endpoint.split(":", 2)[0]; if (!scheme.equalsIgnoreCase("rest")) { LOGGER.info("Endpoint {} is not supported in Spring Cloud, ignoring.", endpoint); continue; } URIEndpointObject uri = new URIEndpointObject(endpoint); instances.add(instanceFactory.createInstance(serviceName, uri)); } } return new DiscoveryTreeNode() .subName(parent, serviceName) .data(instances); } };
@SuppressWarnings("unchecked") protected DiscoveryTreeNode createDiscoveryTreeNode(String expectTransportName, DiscoveryContext context, DiscoveryTreeNode parent) { List<Object> endpoints = new ArrayList<>(); for (MicroserviceInstance instance : ((Map<String, MicroserviceInstance>) parent.data()).values()) { for (String endpoint : instance.getEndpoints()) { try { URI uri = URI.create(endpoint); String transportName = uri.getScheme(); if (!isTransportNameMatch(transportName, expectTransportName)) { continue; } Object objEndpoint = createEndpoint(transportName, endpoint, instance); if (objEndpoint == null) { continue; } endpoints.add(objEndpoint); } catch (Exception e) { LOGGER.warn("unrecognized address find, ignore {}.", endpoint); } } } return new DiscoveryTreeNode() .subName(parent, expectTransportName) .data(endpoints); }
public DiscoveryTreeNode discovery(DiscoveryContext context, VersionedCache inputCache) { DiscoveryTreeNode tmpRoot = getOrCreateRoot(inputCache); DiscoveryTreeNode parent = tmpRoot.children() .computeIfAbsent(inputCache.name(), name -> new DiscoveryTreeNode().fromCache(inputCache)); return doDiscovery(context, parent); }
@Override protected void init(DiscoveryContext context, DiscoveryTreeNode parent) { Map<String, MicroserviceInstance> matchedInstance = new HashMap<>(); Invocation invocation = context.getInputParameters(); Map<String, MicroserviceInstance> instances = parent.data(); Map<String, String> filterOptions = Configuration.INSTANCE.getFlowsplitFilterOptions(invocation.getMicroserviceName()); for (String id : instances.keySet()) { MicroserviceInstance target = instances.get(id); if (allowVisit(target, filterOptions)) { matchedInstance.put(id, target); } } parent.child(MATCHED, new DiscoveryTreeNode() .subName(parent, MATCHED) .data(matchedInstance)); }
@Override public DiscoveryTreeNode discovery(DiscoveryContext context, DiscoveryTreeNode parent) { if (!parent.childrenInited()) { synchronized (parent) { if (!parent.childrenInited()) { init(context, parent); parent.childrenInited(true); } } } String childName = findChildName(context, parent); DiscoveryTreeNode node = parent.child(childName); if (node == null) { LOGGER.warn("discovery filter {} return null.", this.getClass().getName()); return new DiscoveryTreeNode().subName(parent, "empty").data(new HashMap<>()); } return node; }
protected Map<String, DiscoveryTreeNode> initOperationNodes(DiscoveryTreeNode parent, Map<MicroserviceVersionMeta, Map<String, MicroserviceInstance>> versionMap) { Map<String, DiscoveryTreeNode> tmpChildren = new ConcurrentHashMapEx<>(); versionMap .keySet() .stream() .sorted(Comparator.comparing(MicroserviceVersion::getVersion)) .forEach(meta -> { for (OperationMeta operationMeta : meta.getMicroserviceMeta().getOperations()) { tmpChildren.computeIfAbsent(operationMeta.getMicroserviceQualifiedName(), qualifiedName -> { VersionRule versionRule = VersionRuleUtils.getOrCreate(meta.getVersion().getVersion() + "+"); return new DiscoveryTreeNode() .attribute(VERSION_RULE, versionRule) .subName(parent, versionRule.getVersionRule()) .data(new HashMap<>()); }); } }); return tmpChildren; }
protected DiscoveryTreeNode getOrCreateRoot(VersionedCache inputCache) { DiscoveryTreeNode tmpRoot = root; if (isMatch(tmpRoot, inputCache)) { return tmpRoot; } synchronized (lock) { if (isExpired(root, inputCache)) { // not initialized or inputCache newer than root, create new root root = new DiscoveryTreeNode().cacheVersion(inputCache.cacheVersion()); return root; } if (root.isSameVersion(inputCache)) { // reuse root directly return root; } } // root newer than inputCache, it's a minimal probability event: // 1) thread 1, use v1 inputCache, run into getOrCreateRoot, but did not run any code yet, suspend and switch to thread 2 // 2) thread 2, use v2 inputCache, v2 > v1, create new root // 3) thread 1 go on, then root is newer than inputCache // but if create old children in new version root, it's a wrong logic // so just create a temporary root for the inputCache, DO NOT assign to root return new DiscoveryTreeNode().cacheVersion(inputCache.cacheVersion()); }
@Override public DiscoveryTreeNode discovery(DiscoveryContext context, DiscoveryTreeNode parent) { Map<String, MicroserviceInstance> instances = parent.data(); Invocation invocation = context.getInputParameters(); if (!Configuration.INSTANCE.isIsolationFilterOpen(invocation.getMicroserviceName())) { return parent; } Map<String, MicroserviceInstance> filteredServers = new HashMap<>(); for (String key : instances.keySet()) { MicroserviceInstance instance = instances.get(key); if (allowVisit(invocation, instance)) { filteredServers.put(key, instance); } } DiscoveryTreeNode child = new DiscoveryTreeNode(); if (filteredServers.isEmpty() && DynamicPropertyFactory.getInstance() .getBooleanProperty("servicecomb.loadbalance.filter.isolation.emptyInstanceProtectionEnabled", false).get()) { LOGGER.warn("All servers have been isolated, allow one of them based on load balance rule."); child.data(instances); } else { child.data(filteredServers); } parent.child("filterred", child); return child; }
@Override protected void init(DiscoveryContext context, DiscoveryTreeNode parent) { MicroserviceInstance myself = RegistryUtils.getMicroserviceInstance(); Map<String, MicroserviceInstance> instancesRegionAndAZMatch = new HashMap<>(); Map<String, MicroserviceInstance> instancesAZMatch = new HashMap<>(); Map<String, MicroserviceInstance> instancesNoMatch = new HashMap<>(); Map<String, MicroserviceInstance> instances = parent.data(); for (String id : instances.keySet()) { MicroserviceInstance target = instances.get(id); if (regionAndAZMatch(myself, target)) { instancesRegionAndAZMatch.put(id, target); } else if (regionMatch(myself, target)) { instancesAZMatch.put(id, target); } else { instancesNoMatch.put(id, target); } } Map<String, DiscoveryTreeNode> children = new HashMap<>(); children.put(GROUP_RegionAndAZMatch, new DiscoveryTreeNode() .subName(parent, GROUP_RegionAndAZMatch) .data(instancesRegionAndAZMatch)); children.put(GROUP_instancesAZMatch, new DiscoveryTreeNode() .subName(parent, GROUP_instancesAZMatch) .data(instancesAZMatch)); children.put(GROUP_instancesNoMatch, new DiscoveryTreeNode() .subName(parent, GROUP_instancesNoMatch) .data(instancesNoMatch)); parent.children(children); }
@SuppressWarnings("unchecked") protected DiscoveryTreeNode createDiscoveryTreeNode(String expectTransportName, DiscoveryContext context, DiscoveryTreeNode parent) { List<Object> endpoints = new ArrayList<>(); for (MicroserviceInstance instance : ((Map<String, MicroserviceInstance>) parent.data()).values()) { for (String endpoint : instance.getEndpoints()) { try { URI uri = URI.create(endpoint); String transportName = uri.getScheme(); if (!isTransportNameMatch(transportName, expectTransportName)) { continue; } Object objEndpoint = createEndpoint(transportName, endpoint, instance); if (objEndpoint == null) { continue; } endpoints.add(objEndpoint); } catch (Exception e) { LOGGER.warn("unrecognized address find, ignore {}.", endpoint); } } } return new DiscoveryTreeNode() .subName(parent, expectTransportName) .data(endpoints); }
@SuppressWarnings("unchecked") protected DiscoveryTreeNode createDiscoveryTreeNode(DiscoveryContext context, DiscoveryTreeNode parent) { String serviceName = context.getInputParameters(); List<Object> instances = new ArrayList<>(); for (MicroserviceInstance instance : ((Map<String, MicroserviceInstance>) parent.data()).values()) { for (String endpoint : instance.getEndpoints()) { String scheme = endpoint.split(":", 2)[0]; if (!scheme.equalsIgnoreCase("rest")) { LOGGER.info("Endpoint {} is not supported in Spring Cloud, ignoring.", endpoint); continue; } URIEndpointObject uri = new URIEndpointObject(endpoint); instances.add(instanceFactory.createInstance(serviceName, uri)); } } return new DiscoveryTreeNode() .subName(parent, serviceName) .data(instances); } };
public DiscoveryTreeNode discovery(DiscoveryContext context, VersionedCache inputCache) { DiscoveryTreeNode tmpRoot = getOrCreateRoot(inputCache); DiscoveryTreeNode parent = tmpRoot.children() .computeIfAbsent(inputCache.name(), name -> new DiscoveryTreeNode().fromCache(inputCache)); return doDiscovery(context, parent); }
@Override public DiscoveryTreeNode discovery(DiscoveryContext context, DiscoveryTreeNode parent) { Map<String, MicroserviceInstance> instances = parent.data(); Invocation invocation = context.getInputParameters(); if (!Configuration.INSTANCE.isIsolationFilterOpen(invocation.getMicroserviceName())) { return parent; } Map<String, MicroserviceInstance> filteredServers = new HashMap<>(); for (String key : instances.keySet()) { MicroserviceInstance instance = instances.get(key); if (allowVisit(invocation, instance)) { filteredServers.put(key, instance); } } DiscoveryTreeNode child = new DiscoveryTreeNode().data(filteredServers); parent.child("filterred", child); return child; }
@Override protected void init(DiscoveryContext context, DiscoveryTreeNode parent) { Map<String, MicroserviceInstance> matchedInstance = new HashMap<>(); Invocation invocation = context.getInputParameters(); Map<String, MicroserviceInstance> instances = parent.data(); Map<String, String> filterOptions = Configuration.INSTANCE.getFlowsplitFilterOptions(invocation.getMicroserviceName()); for (String id : instances.keySet()) { MicroserviceInstance target = instances.get(id); if (allowVisit(target, filterOptions)) { matchedInstance.put(id, target); } } parent.child(MATCHED, new DiscoveryTreeNode() .subName(parent, MATCHED) .data(matchedInstance)); }
protected Map<String, DiscoveryTreeNode> initOperationNodes(DiscoveryTreeNode parent, Map<MicroserviceVersionMeta, Map<String, MicroserviceInstance>> versionMap) { Map<String, DiscoveryTreeNode> tmpChildren = new ConcurrentHashMapEx<>(); versionMap .keySet() .stream() .sorted(Comparator.comparing(MicroserviceVersion::getVersion)) .forEach(meta -> { for (OperationMeta operationMeta : meta.getMicroserviceMeta().getOperations()) { tmpChildren.computeIfAbsent(operationMeta.getMicroserviceQualifiedName(), qualifiedName -> { VersionRule versionRule = VersionRuleUtils.getOrCreate(meta.getVersion().getVersion() + "+"); return new DiscoveryTreeNode() .attribute(VERSION_RULE, versionRule) .subName(parent, versionRule.getVersionRule()) .data(new HashMap<>()); }); } }); return tmpChildren; }
protected DiscoveryTreeNode getOrCreateRoot(VersionedCache inputCache) { DiscoveryTreeNode tmpRoot = root; if (isMatch(tmpRoot, inputCache)) { return tmpRoot; } synchronized (lock) { if (isExpired(root, inputCache)) { // not initialized or inputCache newer than root, create new root root = new DiscoveryTreeNode().cacheVersion(inputCache.cacheVersion()); return root; } if (root.isSameVersion(inputCache)) { // reuse root directly return root; } } // root newer than inputCache, it's a minimal probability event: // 1) thread 1, use v1 inputCache, run into getOrCreateRoot, but did not run any code yet, suspend and switch to thread 2 // 2) thread 2, use v2 inputCache, v2 > v1, create new root // 3) thread 1 go on, then root is newer than inputCache // but if create old children in new version root, it's a wrong logic // so just create a temporary root for the inputCache, DO NOT assign to root return new DiscoveryTreeNode().cacheVersion(inputCache.cacheVersion()); }