in oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/ServiceTopologyBuilder.java [88:227]
Topology build(List<Call.CallDetail> serviceRelationClientCalls, List<Call.CallDetail> serviceRelationServerCalls) {
Map<String, Node> nodes = new HashMap<>();
List<Call> calls = new LinkedList<>();
HashMap<String, Call> callMap = new HashMap<>();
for (Call.CallDetail clientCall : serviceRelationClientCalls) {
final IDManager.ServiceID.ServiceIDDefinition sourceService = IDManager.ServiceID.analysisId(
clientCall.getSource());
String sourceServiceId = clientCall.getSource();
IDManager.ServiceID.ServiceIDDefinition destService = IDManager.ServiceID.analysisId(
clientCall.getTarget());
String targetServiceId = clientCall.getTarget();
/*
* Use the alias name to make topology relationship accurate.
*/
if (networkAddressAliasCache.get(destService.getName()) != null) {
/*
* If alias exists, mean this network address is representing a real service.
*/
final NetworkAddressAlias networkAddressAlias = networkAddressAliasCache.get(destService.getName());
destService = IDManager.ServiceID.analysisId(
networkAddressAlias.getRepresentServiceId());
targetServiceId = IDManager.ServiceID.buildId(destService.getName(), true);
}
/*
* Set the conjectural node type.
*/
if (!nodes.containsKey(targetServiceId)) {
final Node conjecturalNode = buildNode(targetServiceId, destService);
nodes.put(targetServiceId, conjecturalNode);
if (!conjecturalNode.isReal() && StringUtil.isEmpty(conjecturalNode.getType())) {
conjecturalNode.setType(
componentLibraryCatalogService.getServerNameBasedOnComponent(clientCall.getComponentId()));
}
}
if (!nodes.containsKey(sourceServiceId)) {
nodes.put(sourceServiceId, buildNode(sourceServiceId, sourceService));
}
final String relationId = IDManager.ServiceID.buildRelationId(
new IDManager.ServiceID.ServiceRelationDefine(sourceServiceId, targetServiceId));
if (!callMap.containsKey(relationId)) {
Call call = new Call();
callMap.put(relationId, call);
call.setSource(sourceServiceId);
call.setTarget(targetServiceId);
call.setId(relationId);
call.addDetectPoint(DetectPoint.CLIENT);
call.addSourceComponent(componentLibraryCatalogService.getComponentName(clientCall.getComponentId()));
calls.add(call);
} else {
Call call = callMap.get(relationId);
call.addSourceComponent(componentLibraryCatalogService.getComponentName(clientCall.getComponentId()));
}
}
for (Call.CallDetail serverCall : serviceRelationServerCalls) {
final IDManager.ServiceID.ServiceIDDefinition sourceService = IDManager.ServiceID.analysisId(
serverCall.getSource());
IDManager.ServiceID.ServiceIDDefinition destService = IDManager.ServiceID.analysisId(
serverCall.getTarget());
/*
* Create the client node if it hasn't been created in client side call.
*/
Node clientSideNode = nodes.get(serverCall.getSource());
if (clientSideNode == null) {
clientSideNode = buildNode(serverCall.getSource(), sourceService);
nodes.put(serverCall.getSource(), clientSideNode);
}
/*
* conjectural node type.
*/
if (!clientSideNode.isReal()) {
clientSideNode.setType(
componentLibraryCatalogService.getServerNameBasedOnComponent(serverCall.getComponentId()));
}
/*
* Format the User name type.
*/
if (userID.equals(serverCall.getSource())) {
nodes.get(userID).setType(Const.USER_SERVICE_NAME.toUpperCase());
}
/*
* Create the server node if it hasn't been created.
*/
if (!nodes.containsKey(serverCall.getTarget())) {
final Node node = buildNode(serverCall.getTarget(), destService);
nodes.put(serverCall.getTarget(), node);
}
/*
* Set the node type due to service side component id has higher priority
*/
final Node serverSideNode = nodes.get(serverCall.getTarget());
final String nodeType = serverSideNode.getType();
if (nodeType == null || !serverSideNode.hasSetOnceAtServerSide()) {
serverSideNode.setTypeFromServerSide(
componentLibraryCatalogService.getComponentName(serverCall.getComponentId()));
} else {
final Integer componentId = componentLibraryCatalogService.getComponentId(nodeType);
if (componentId != null) {
if (componentLibraryCatalogService.compare(componentId, serverCall.getComponentId())) {
serverSideNode.setTypeFromServerSide(
componentLibraryCatalogService.getComponentName(serverCall.getComponentId()));
} else {
//Do nothing, as the current value has higher priority
}
} else {
serverSideNode.setTypeFromServerSide(
componentLibraryCatalogService.getComponentName(serverCall.getComponentId()));
}
}
if (!callMap.containsKey(serverCall.getId())) {
Call call = new Call();
callMap.put(serverCall.getId(), call);
call.setSource(serverCall.getSource());
call.setTarget(serverCall.getTarget());
call.setId(serverCall.getId());
call.addDetectPoint(DetectPoint.SERVER);
call.addTargetComponent(componentLibraryCatalogService.getComponentName(serverCall.getComponentId()));
calls.add(call);
} else {
Call call = callMap.get(serverCall.getId());
call.addDetectPoint(DetectPoint.SERVER);
call.addTargetComponent(componentLibraryCatalogService.getComponentName(serverCall.getComponentId()));
}
}
Topology topology = new Topology();
topology.getCalls().addAll(calls);
topology.getNodes().addAll(nodes.values());
return topology;
}