/* * Copyright 2014 NAVER Corp. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.navercorp.pinpoint.test; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import com.google.common.collect.Maps; import com.navercorp.pinpoint.profiler.sender.EnhancedDataSender; import com.navercorp.pinpoint.rpc.FutureListener; import com.navercorp.pinpoint.rpc.ResponseMessage; import com.navercorp.pinpoint.rpc.client.PinpointClientReconnectEventListener; import com.navercorp.pinpoint.thrift.dto.TApiMetaData; import com.navercorp.pinpoint.thrift.dto.TSqlMetaData; import com.navercorp.pinpoint.thrift.dto.TStringMetaData; import org.apache.thrift.TBase; import java.io.PrintStream; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.NoSuchElementException; /** * @author Jongho Moon * @author jaehong.kim */ public class TestTcpDataSender implements EnhancedDataSender { private final List<TBase<?, ?>> datas = Collections.synchronizedList(new ArrayList<TBase<?, ?>>()); private final BiMap<Integer, String> apiIdMap = newSynchronizedBiMap(); private final BiMap<Integer, String> sqlIdMap = newSynchronizedBiMap(); private final BiMap<Integer, String> stringIdMap = newSynchronizedBiMap(); private static final Comparator<Map.Entry<Integer, String>> COMPARATOR = new Comparator<Map.Entry<Integer, String>>() { @Override public int compare(Entry<Integer, String> o1, Entry<Integer, String> o2) { return o1.getKey() > o2.getKey() ? 1 : (o1.getKey() < o2.getKey() ? -1 : 0); } }; private <K, V> BiMap<K, V> newSynchronizedBiMap() { BiMap<K, V> hashBiMap = HashBiMap.create(); return Maps.synchronizedBiMap(hashBiMap); } @Override public boolean send(TBase<?, ?> data) { addData(data); return false; } private void addData(TBase<?, ?> data) { if (data instanceof TApiMetaData) { TApiMetaData md = (TApiMetaData)data; final String javaMethodDescriptor = toJavaMethodDescriptor(md); apiIdMap.put(md.getApiId(), javaMethodDescriptor); } else if (data instanceof TSqlMetaData) { TSqlMetaData md = (TSqlMetaData)data; int id = md.getSqlId(); String sql = md.getSql(); sqlIdMap.put(id, sql); } else if (data instanceof TStringMetaData) { TStringMetaData md = (TStringMetaData)data; int id = md.getStringId(); String string = md.getStringValue(); stringIdMap.put(id, string); } datas.add(data); } private String toJavaMethodDescriptor(TApiMetaData apiMetaData) { // 1st method type check // int type = apiMetaData.getType(); // if (type != MethodType.DEFAULT) { // return apiMetaData.getApiInfo(); // } // 2st Descriptor check String apiInfo = apiMetaData.getApiInfo(); if (apiInfo.indexOf('(') == -1) { // exceptional case // eg : async or internal tag api return apiInfo; } return MethodDescriptionUtils.toJavaMethodDescriptor(apiInfo); } @Override public void stop() { // do nothing } @Override public boolean request(TBase<?, ?> data) { addData(data); return true; } @Override public boolean request(TBase<?, ?> data, int retry) { addData(data); return true; } @Override public boolean request(TBase<?, ?> data, FutureListener<ResponseMessage> listener) { addData(data); return true; } @Override public boolean addReconnectEventListener(PinpointClientReconnectEventListener eventListener) { return false; } @Override public boolean removeReconnectEventListener(PinpointClientReconnectEventListener eventListener) { return false; } public String getApiDescription(int id) { return apiIdMap.get(id); } public int getApiId(String description) { BiMap<String, Integer> apiDescriptionMap = apiIdMap.inverse(); Integer id = apiDescriptionMap.get(description); if (id == null) { throw new NoSuchElementException(description); } return id; } public String getString(int id) { return stringIdMap.get(id); } public int getStringId(String string) { BiMap<String, Integer> stringMap = stringIdMap.inverse(); Integer id = stringMap.get(string); if (id == null) { throw new NoSuchElementException(string); } return id; } public String getSql(int id) { return sqlIdMap.get(id); } public int getSqlId(String sql) { BiMap<String, Integer> sqlMap = sqlIdMap.inverse(); Integer id = sqlMap.get(sql); if (id == null) { throw new NoSuchElementException(sql); } return id; } public List<TBase<?, ?>> getDatas() { return datas; } public void clear() { datas.clear(); } public void printDatas(PrintStream out) { out.println("API(" + apiIdMap.size() + "):"); printApis(out); out.println("SQL(" + sqlIdMap.size() + "):"); printSqls(out); out.println("STRING(" + stringIdMap.size() + "):"); printStrings(out); } public void printApis(PrintStream out) { List<Map.Entry<Integer, String>> apis = new ArrayList<Map.Entry<Integer, String>>(apiIdMap.entrySet()); printEntries(out, apis); } public void printStrings(PrintStream out) { List<Map.Entry<Integer, String>> strings = new ArrayList<Map.Entry<Integer, String>>(stringIdMap.entrySet()); printEntries(out, strings); } public void printSqls(PrintStream out) { List<Map.Entry<Integer, String>> sqls = new ArrayList<Map.Entry<Integer, String>>(sqlIdMap.entrySet()); printEntries(out, sqls); } private void printEntries(PrintStream out, List<Map.Entry<Integer, String>> entries) { Collections.sort(entries, COMPARATOR); for (Map.Entry<Integer, String> e : entries) { out.println(e.getKey() + ": " + e.getValue()); } } }