1 21 22 package org.continuent.sequoia.console.text.commands.dbadmin; 23 24 import java.io.IOException ; 25 import java.util.ArrayList ; 26 import java.util.Collection ; 27 import java.util.Collections ; 28 import java.util.Comparator ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.StringTokenizer ; 32 33 import javax.management.openmbean.CompositeData ; 34 import javax.management.openmbean.TabularData ; 35 36 import org.continuent.sequoia.common.i18n.ConsoleTranslate; 37 import org.continuent.sequoia.common.jmx.mbeans.RecoveryLogControlMBean; 38 import org.continuent.sequoia.console.text.formatter.TableFormatter; 39 import org.continuent.sequoia.console.text.module.VirtualDatabaseAdmin; 40 41 44 public class DumpRecoveryLog extends AbstractAdminCommand 45 { 46 51 public DumpRecoveryLog(VirtualDatabaseAdmin module) 52 { 53 super(module); 54 } 55 56 59 public void parse(String commandText) throws Exception 60 { 61 if ("indexes".equals(commandText.trim())) { 63 printIndexes(); 64 return; 65 } 66 StringTokenizer tokenizer = new StringTokenizer (commandText.trim()); 67 68 long min = 0; 69 if (tokenizer.hasMoreTokens()) 70 { 71 String minStr = tokenizer.nextToken(); 72 try 73 { 74 min = Long.parseLong(minStr); 75 } 76 catch (NumberFormatException e) 77 { 78 console.printError(getUsage()); 79 return; 80 } 81 } 82 83 RecoveryLogControlMBean recoveryLog = jmxClient.getRecoveryLog(dbName, 84 user, password); 85 86 long max; 87 String maxStr; 88 if (tokenizer.hasMoreTokens()) 89 { 90 maxStr = tokenizer.nextToken(); 91 try 92 { 93 max = Long.parseLong(maxStr); 94 } 95 catch (NumberFormatException e) 96 { 97 console.printError(getUsage()); 98 return; 99 } 100 } 101 else 102 { 103 max = recoveryLog.getIndexes()[1]; 104 } 105 106 if (min < 0 || max < 0) 107 { 108 console.printError("Negative indexes are not allowed"); 109 return; 110 } 111 112 String [] headers = recoveryLog.getHeaders(); 113 final String idKey = headers[0]; 115 TabularData logEntries = recoveryLog.dump(min); 116 117 if (logEntries.isEmpty()) 118 { 119 console.printInfo(ConsoleTranslate.get("DumpRecoveryLog.empty")); return; 121 } 122 long lastIndex = 0; 123 while (!logEntries.isEmpty()) 124 { 125 List entries = sortEntriesById(logEntries, idKey); 126 lastIndex = getIndexOfLastEntry(entries, idKey); 127 if (lastIndex > max) 128 { 129 removeAfterIndex(entries, max, idKey); 130 } 131 String [][] entriesStr = from(entries, headers); 132 console.println(TableFormatter.format(headers, entriesStr, true)); 133 134 if (lastIndex > max) 135 { 136 break; 137 } 138 logEntries = recoveryLog.dump(lastIndex + 1); 139 } 140 } 141 142 145 private void removeAfterIndex(List entries, long index, String idKey) 146 { 147 Iterator iter = entries.iterator(); 148 while (iter.hasNext()) 149 { 150 CompositeData data = (CompositeData ) iter.next(); 151 String idStr = (String ) data.get(idKey); 152 long id = Long.parseLong(idStr); 153 if (id > index) 154 { 155 iter.remove(); 156 } 157 } 158 } 159 160 private void printIndexes() 161 { 162 try 163 { 164 RecoveryLogControlMBean recoveryLog = jmxClient.getRecoveryLog(dbName, 165 user, password); 166 long[] indexes = recoveryLog.getIndexes(); 167 String minIndex = (indexes != null) 168 ? Long.toString(indexes[0]) 169 : ConsoleTranslate.get("DumpRecoveryLog.notAvailable"); String maxIndex = (indexes != null) 171 ? Long.toString(indexes[1]) 172 : ConsoleTranslate.get("DumpRecoveryLog.notAvailable"); console.println(ConsoleTranslate 174 .get("DumpRecoveryLog.minIndex", minIndex)); console.println(ConsoleTranslate 176 .get("DumpRecoveryLog.maxIndex", maxIndex)); console.println(ConsoleTranslate.get( 178 "DumpRecoveryLog.numberOfEntries", recoveryLog.getEntries())); } 180 catch (IOException e) 181 { 182 console.printError(e.getMessage()); 183 } 184 } 185 186 194 private static List sortEntriesById(TabularData logEntries, final String idKey) 195 { 196 List entries = new ArrayList (logEntries.values()); 197 Collections.sort(entries, new Comparator () 198 { 199 200 public int compare(Object o1, Object o2) 201 { 202 CompositeData entry1 = (CompositeData ) o1; 203 CompositeData entry2 = (CompositeData ) o2; 204 205 String idStr1 = (String ) entry1.get(idKey); 206 String idStr2 = (String ) entry2.get(idKey); 207 208 int id1 = Integer.parseInt(idStr1); 209 int id2 = Integer.parseInt(idStr2); 210 return id1 - id2; 211 } 212 }); 213 return entries; 214 } 215 216 223 private static int getIndexOfLastEntry(List entries, String idKey) 224 { 225 CompositeData data = (CompositeData ) entries.get(entries.size() - 1); 226 String idStr = (String ) data.get(idKey); 227 return Integer.parseInt(idStr); 228 } 229 230 238 private static String [][] from(Collection collection, String [] headers) 239 { 240 String [][] entries = new String [collection.size()][]; 241 Iterator iter = collection.iterator(); 242 int i = 0; 243 while (iter.hasNext()) 244 { 245 CompositeData logEntry = (CompositeData ) iter.next(); 246 Object [] logEntryItems = logEntry.getAll(headers); 247 String [] entry = new String [logEntryItems.length]; 248 for (int j = 0; j < entry.length; j++) 249 { 250 entry[j] = logEntryItems[j].toString(); 251 } 252 entries[i] = entry; 253 i++; 254 } 255 return entries; 256 } 257 258 261 public String getCommandName() 262 { 263 264 return "dump recoverylog"; } 266 267 270 public String getCommandParameters() 271 { 272 return "([indexes] | (<min>* <max>*))"; } 274 275 278 public String getCommandDescription() 279 { 280 return ConsoleTranslate.get("DumpRecoveryLog.description"); } 282 } 283 | Popular Tags |