package io.mycat.performance; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Random; /** * genarate random test data * such as * values ('$date{yyyyMMddHHmmsss-[2014-2015]y}/psn$date{yyyy}s/$int(0-9999)/16767:20725','$char(2,0-99) OPP_$enum(BJ,SH,GZ,SZ)_$int(0-9)',$int(10,11),$int(400,420,500,600,800),$int(0-1000),$int(0-100),Sint(0-10),$int(0-99),'201408040028317067b41c0db-4a93-4360-9eb4-e159d1dbef45',$phone,2,2014071715,2315998,1397,152317998,1395,'0000'); * @author wuzhih * */ /** * * @author wuzhih * */ public class RandomDataValueUtil { /** * eval template contains random vars and replace them with real value alues * ( * '${date(yyyyMMddHHmmsss-[2014-2015]y)}/psn${date(yyyy)}s/${int(0-9999)}/1 * 6 7 6 7 : 2 0 7 2 5 ' , ' $ { s t r i n g ( 2 , 0 - 9 9 )} * OPP_${enum(BJ,SH,GZ,SZ)}_${int(0-9)} * ',${int(10,11)},$int(400,420,500,600,800),$int(0-1000),$int(0-100),$int(0-10),$int(0-99),'201408040028317067b41c0db-4a93-4360-9eb4-e159d1 * d b e f 4 5 ' , $ p h o n e , 2 , 2 0 1 4 0 7 1 7 1 5 , 2 3 1 5 9 9 8 , 1 * 3 9 7 , 1 5 2 3 1 7 9 9 8 , 1 3 9 5 , ' 0 0 0 0 ' ) * * @param templateStr * @return * @throws IllegalAccessException * @throws InstantiationException */ public static LinkedList<StringItem> parselRandVarTemplateString( String templateStr) throws Exception { char[] chars = templateStr.toCharArray(); LinkedList<StringItem> stringItems = new LinkedList<StringItem>(); int curPos = 0; int prevPattenEndPos = 0; while (curPos < chars.length) { char c = chars[curPos]; if (c == '$' && curPos + 1 < chars.length && chars[curPos + 1] == '{') { int start = curPos; curPos += 2; int end = -1; if (curPos < chars.length) { for (int i = curPos; i < chars.length; i++) { if (chars[i] == '}') { end = i; // found pattern if (prevPattenEndPos < start) {// some constant // string chars StringItem item = new StringItem(); item.initString(templateStr.substring( prevPattenEndPos, start)); stringItems.add(item); } // add variable pattern item stringItems.add(StringItemFactory .parseVarPattern(templateStr.substring( curPos, end))); prevPattenEndPos = end + 1; curPos = end + 1; break; } } if (end == -1) { // not found pattern end throw new RuntimeException( "can't find var patten end pos ,start at " + start); } } else { curPos++; } } else { curPos++; } } // add last if (prevPattenEndPos < templateStr.length()) { StringItem item = new StringItem(); item.initString(templateStr.substring(prevPattenEndPos, templateStr.length())); stringItems.add(item); } return stringItems; } public static Properties loadFromPropertyFile(String sqlFile) throws IOException { java.util.Properties pros = new Properties(); FileInputStream fin = null; fin = new FileInputStream(sqlFile); pros.load(fin); fin.close(); return pros; } public static String evalRandValueString(LinkedList<StringItem> items) { StringBuilder sb = new StringBuilder(); for (StringItem item : items) { sb.append(item.getValue()); } return sb.toString(); } public static void main(String[] args) throws Exception { String sqlTemplate = "insert into opp_call (logthread, instanceid,callresult,partner, app_id,api_id,apiversion,format,token , phone,calltype, calldate,callminutes,callcost,ecipcalltime,ecipcallcost ,respcode) values ('${date(yyyyMMddHHmmssSSS-[2014-2015]y)}/psn2002s/${int(0-9999)}/${int(1111-9999)}:20725','${char([0-9]2:2)} OPP_${enum(BJ,SH,WU,GZ)}_1',10,${int(10-999)},${int(10-99)},100,3,15,'${date(yyyyMMddHHmmssSSS-[2014-2015]y}${char([a-f,0-9]8:8)}-${char([a-f,0-9]4:4)}-${char([0-9]4:4)}-9eb4-${char([a-f,0-9]12:12)}',${phone(139-189)},2,${date(yyyyMMddHH-[2014-2015]y},2315998,1397,${date(HHmmssSSS)},${int(100-1000)},'${enum(0000,0001,0002)}');"; System.out.println("SQL template:\r\n" + sqlTemplate); LinkedList<StringItem> allItems = parselRandVarTemplateString(sqlTemplate); // for (StringItem item : allItems) { // System.out.println(item); // } System.out.println("Random SQLs "); int total = 5; for (int i = 0; i < total; i++) { System.out.println(evalRandValueString(allItems)); } } } class StringItemFactory { private static final Map<String, Class<? extends StringItem>> strItemsMap = new HashMap<String, Class<? extends StringItem>>(); static { strItemsMap.put("date", DateVarItem.class); strItemsMap.put("int", IntVarItem.class); strItemsMap.put("char", CharVarItem.class); strItemsMap.put("enum", EnumVarItem.class); strItemsMap.put("phone", PhoneVarItem.class); } public static StringItem parseVarPattern(String content) throws InstantiationException, IllegalAccessException { String name = content.substring(0, content.indexOf('(')); Class<? extends StringItem> cls = strItemsMap.get(name); if (cls == null) { throw new RuntimeException("not find var type of " + name); } StringItem obj = cls.newInstance(); obj.initString(content); return obj; } } class PhoneVarItem extends StringItem { // long[] rang = { 13900000000L, 19900000000L }; public void initString(String content) { int start = content.indexOf('('); int end = content.indexOf(')'); String range = content.substring(start + 1, end); String[] items = range.split("-"); rang[0] = Long.valueOf(patchLenth(items[0], 11 - items[0].length())); rang[1] = Long.valueOf(patchLenth(items[1], 11 - items[1].length())); } public static String patchLenth(String origin, int patchlen) { StringBuffer sb = new StringBuffer(); sb.append(origin); for (int i = 0; i < patchlen; i++) { sb.append('0'); } return sb.toString(); } public String getValue() { long span = rang[1] - rang[0] + 1; return Math.abs(rand.nextInt()) % span + rang[0] + ""; } @Override public String toString() { return "PhoneVarItem [rang=" + Arrays.toString(rang) + "]"; } } class EnumVarItem extends StringItem { // {enum(BJ,SH,GZ,SZ) String[] enums = {}; public void initString(String content) { int start = content.indexOf('('); int end = content.indexOf(')'); String range = content.substring(start + 1, end); String[] items = range.split(","); enums = items; } public String getValue() { return enums[Math.abs(rand.nextInt()) % enums.length]; } @Override public String toString() { return "EnumarItem [enums=" + Arrays.toString(enums) + "]"; } } class CharVarItem extends StringItem { List<char[]> rang = new ArrayList<char[]>(); int minLen = 1; int maxLen = 256; public void initString(String content) { // char([a-z]1:3) int start = content.indexOf('['); int end = content.indexOf(']'); String[] items = content.substring(start + 1, end).split(","); for (String itemStr : items) { if (itemStr.indexOf('-') > 0) { String[] pair = itemStr.split("-"); char[] curRange = new char[2]; curRange[0] = pair[0].charAt(0); curRange[1] = pair[1].charAt(0); rang.add(curRange); } } int splitPos = content.indexOf(':'); if (splitPos > 0) { int splitStart = (end == -1) ? content.indexOf('(') : end; int splitEnd = content.indexOf(')'); String[] pair = content.substring(splitStart + 1, splitEnd).split( ":"); minLen = Integer.valueOf(pair[0]); maxLen = Integer.valueOf(pair[1]); } } public String getValue() { int lenth = Math.abs(rand.nextInt()) % (maxLen - minLen + 1) + minLen; char[] chars = new char[lenth]; for (int i = 0; i < chars.length; i++) { int randInt = Math.abs(rand.nextInt()); int choise = randInt % rang.size(); char[] choisedRange = rang.get(choise); char randChar = (char) (randInt % (choisedRange[1] - choisedRange[0] + 1) + choisedRange[0]); chars[i] = randChar; } return new String(chars); } @Override public String toString() { return "CharVarItem [rang=" + rang + ", minLen=" + minLen + ", maxLen=" + maxLen + "]"; } } class StringItem { protected static final Random rand = new Random(); public String content; public StringItem() { } public String getValue() { return content; } public void initString(String content) { this.content = content; } @Override public String toString() { return "StringItem [content=" + content + "]"; } } class IntVarItem extends StringItem { long[] rang = { 0, Integer.MAX_VALUE }; long[] enums = {}; boolean isEnumInt = false; public void initString(String content) { int start = content.indexOf('('); int end = content.indexOf(')'); if (content.indexOf('-') > 0) { String range = content.substring(start + 1, end); String[] items = range.split("-"); rang[0] = Integer.valueOf(items[0]); rang[1] = Integer.valueOf(items[1]); } else { isEnumInt = true; String range = content.substring(start + 1, end); String[] items = range.split(","); enums = new long[items.length]; for (int i = 0; i < enums.length; i++) { enums[i] = Long.valueOf(items[i]); } } } public String getValue() { if (isEnumInt) { return enums[Math.abs(rand.nextInt()) % enums.length] + ""; } else { long span = rang[1] - rang[0] + 1; return Math.abs(rand.nextInt()) % span + rang[0] + ""; } } @Override public String toString() { return "IntVarItem [rang=" + Arrays.toString(rang) + ", enums=" + Arrays.toString(enums) + ", isEnumInt=" + isEnumInt + "]"; } } class DateVarItem extends StringItem { String format; int[] yearRang = { 1970, 2999 }; int[] monRang = { 1, 12 }; int[] dayRang = { 1, 31 }; int[] hourRang = { 0, 23 }; int[] minuteRang = { 0, 59 }; int[] secondRang = { 0, 59 }; int[] sssRang = { 0, 999 }; public DateVarItem() { } public void initString(String content) { int fmtEndPos = content.indexOf('-'); if (fmtEndPos == -1) { fmtEndPos = content.indexOf(')'); } format = content.substring(5, fmtEndPos); int yearP = content.indexOf("]y", fmtEndPos); if (yearP > 0) { yearRang = getRangeofPattern(content, yearP); } int monthP = content.indexOf("]M", fmtEndPos); if (monthP > 0) { monRang = getRangeofPattern(content, monthP); } int dayP = content.indexOf("]d", fmtEndPos); if (dayP > 0) { dayRang = getRangeofPattern(content, dayP); } int hourP = content.indexOf("]H", fmtEndPos); if (hourP > 0) { hourRang = getRangeofPattern(content, hourP); } int minuteP = content.indexOf("]m", fmtEndPos); if (minuteP > 0) { minuteRang = getRangeofPattern(content, minuteP); } int secondP = content.indexOf("]s", fmtEndPos); if (secondP > 0) { secondRang = getRangeofPattern(content, secondP); } int millisS = content.indexOf("]S", fmtEndPos); if (millisS > 0) { sssRang = getRangeofPattern(content, millisS); } } private static final int[] getRangeofPattern(String theString, int endPos) { String subString = theString.substring(0, endPos); int start = subString.lastIndexOf('['); String range = subString.substring(start + 1, endPos); String[] items = range.split("-"); int[] values = new int[2]; values[0] = Integer.valueOf(items[0]); values[1] = Integer.valueOf(items[1]); return values; } public String getValue() { int yearSpan = yearRang[1] - yearRang[0] + 1; int year = Math.abs(rand.nextInt()) % yearSpan + yearRang[0]; int monthSpan = monRang[1] - monRang[0] + 1; int month = Math.abs(rand.nextInt()) % monthSpan + monRang[0]; int daySpan = dayRang[1] - dayRang[0] + 1; int day = Math.abs(rand.nextInt()) % daySpan + dayRang[0]; int hourSpan = hourRang[1] - hourRang[0] + 1; int hour = Math.abs(rand.nextInt()) % hourSpan + hourRang[0]; int minuteSpan = minuteRang[1] - minuteRang[0] + 1; int minute = Math.abs(rand.nextInt()) % minuteSpan + minuteRang[0]; int secondSpan = secondRang[1] - secondRang[0] + 1; int second = Math.abs(rand.nextInt()) % secondSpan + secondRang[0]; int sssSpan = sssRang[1] - sssRang[0] + 1; int sss = Math.abs(rand.nextInt()) % sssSpan + sssRang[0]; java.util.Calendar cl = Calendar.getInstance(); cl.set(Calendar.YEAR, year); cl.set(Calendar.MONTH, month); cl.set(Calendar.DATE, day); cl.set(Calendar.HOUR_OF_DAY, hour); cl.set(Calendar.MINUTE, minute); cl.set(Calendar.SECOND, second); cl.set(Calendar.MILLISECOND, sss); return new java.text.SimpleDateFormat(format).format(cl.getTime()); } @Override public String toString() { return "DateVarItem [format=" + format + ", yearRang=" + Arrays.toString(yearRang) + ", monRang=" + Arrays.toString(monRang) + ", dayRang=" + Arrays.toString(dayRang) + "]"; } }