package org.skywalking.apm.collector.worker.tracedag;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.skywalking.apm.collector.worker.Const;
import org.skywalking.apm.collector.worker.node.NodeCompIndex;
import org.skywalking.apm.collector.worker.node.NodeMappingIndex;
import org.skywalking.apm.collector.worker.noderef.NodeRefIndex;
import java.util.HashMap;
import java.util.Map;
/**
* @author pengys5
*/
public class TraceDagDataBuilder {
private Logger logger = LogManager.getFormatterLogger(TraceDagDataBuilder.class);
private Integer nodeId = new Integer(-1);
private Map<String, String> mappingMap = new HashMap<>();
private Map<String, String> nodeCompMap = new HashMap<>();
private Map<String, Long> resSumMap = new HashMap<>();
private Map<String, Integer> nodeIdMap = new HashMap<>();
private JsonArray pointArray = new JsonArray();
private JsonArray lineArray = new JsonArray();
public JsonObject build(JsonArray nodeCompArray, JsonArray nodesMappingArray, JsonArray nodeRefsArray,
JsonArray resSumArray) {
changeMapping2Map(nodesMappingArray);
changeNodeComp2Map(nodeCompArray);
resSumMerge(resSumArray);
for (int i = 0; i < nodeRefsArray.size(); i++) {
JsonObject nodeRefJsonObj = nodeRefsArray.get(i).getAsJsonObject();
String front = nodeRefJsonObj.get(NodeRefIndex.FRONT).getAsString();
String behind = nodeRefJsonObj.get(NodeRefIndex.BEHIND).getAsString();
String behindCode = findRealCode(behind);
logger.debug("behind: %s, behindCode: %s", behind, behindCode);
JsonObject lineJsonObj = new JsonObject();
lineJsonObj.addProperty("from", findOrCreateNode(front));
lineJsonObj.addProperty("to", findOrCreateNode(behindCode));
lineJsonObj.addProperty("resSum", resSumMap.get(front + Const.ID_SPLIT + behindCode));
lineArray.add(lineJsonObj);
logger.debug("line: %s", lineJsonObj);
}
JsonObject dagJsonObj = new JsonObject();
dagJsonObj.add("nodes", pointArray);
dagJsonObj.add("nodeRefs", lineArray);
return dagJsonObj;
}
private Integer findOrCreateNode(String peers) {
if (nodeIdMap.containsKey(peers)) {
return nodeIdMap.get(peers);
} else {
nodeId++;
JsonObject nodeJsonObj = new JsonObject();
nodeJsonObj.addProperty("id", nodeId);
nodeJsonObj.addProperty("peer", peers);
if (peers.equals(Const.USER_CODE)) {
nodeJsonObj.addProperty("component", Const.USER_CODE);
} else {
nodeJsonObj.addProperty("component", nodeCompMap.get(peers));
}
pointArray.add(nodeJsonObj);
nodeIdMap.put(peers, nodeId);
logger.debug("node: %s", nodeJsonObj);
}
return nodeId;
}
private void changeMapping2Map(JsonArray nodesMappingArray) {
for (int i = 0; i < nodesMappingArray.size(); i++) {
JsonObject nodesMappingJsonObj = nodesMappingArray.get(i).getAsJsonObject();
String code = nodesMappingJsonObj.get(NodeMappingIndex.CODE).getAsString();
String peers = nodesMappingJsonObj.get(NodeMappingIndex.PEERS).getAsString();
mappingMap.put(peers, code);
}
}
private void changeNodeComp2Map(JsonArray nodeCompArray) {
for (int i = 0; i < nodeCompArray.size(); i++) {
JsonObject nodesJsonObj = nodeCompArray.get(i).getAsJsonObject();
logger.debug(nodesJsonObj);
String component = nodesJsonObj.get(NodeCompIndex.NAME).getAsString();
String peers = nodesJsonObj.get(NodeCompIndex.PEERS).getAsString();
nodeCompMap.put(peers, component);
}
}
private String findRealCode(String peers) {
if (mappingMap.containsKey(peers)) {
return mappingMap.get(peers);
} else {
return peers;
}
}
private void resSumMerge(JsonArray resSumArray) {
for (int i = 0; i < resSumArray.size(); i++) {
JsonObject resSumJsonObj = resSumArray.get(i).getAsJsonObject();
String front = resSumJsonObj.get("front").getAsString();
String behind = resSumJsonObj.get("behind").getAsString();
Long summary = resSumJsonObj.get("summary").getAsLong();
if (mappingMap.containsKey(behind)) {
behind = mappingMap.get(behind);
}
String id = front + Const.ID_SPLIT + behind;
if (resSumMap.containsKey(id)) {
resSumMap.put(id, summary + resSumMap.get(id));
} else {
resSumMap.put(id, summary);
}
}
}
}