1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.client;
21
22 import org.apache.hadoop.hbase.classification.InterfaceAudience;
23 import org.apache.hadoop.hbase.classification.InterfaceStability;
24 import org.apache.hadoop.hbase.DoNotRetryIOException;
25 import org.apache.hadoop.hbase.util.Bytes;
26
27 import java.io.PrintWriter;
28 import java.io.StringWriter;
29 import java.util.Collection;
30 import java.util.HashMap;
31 import java.util.HashSet;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Set;
35
36
37
38
39
40
41
42
43
44
45 @SuppressWarnings("serial")
46 @InterfaceAudience.Public
47 @InterfaceStability.Stable
48 public class RetriesExhaustedWithDetailsException
49 extends RetriesExhaustedException {
50 List<Throwable> exceptions;
51 List<Row> actions;
52 List<String> hostnameAndPort;
53
54 public RetriesExhaustedWithDetailsException(List<Throwable> exceptions,
55 List<Row> actions,
56 List<String> hostnameAndPort) {
57 super("Failed " + exceptions.size() + " action" +
58 pluralize(exceptions) + ": " +
59 getDesc(exceptions, actions, hostnameAndPort));
60
61 this.exceptions = exceptions;
62 this.actions = actions;
63 this.hostnameAndPort = hostnameAndPort;
64 }
65
66 public List<Throwable> getCauses() {
67 return exceptions;
68 }
69
70 public int getNumExceptions() {
71 return exceptions.size();
72 }
73
74 public Throwable getCause(int i) {
75 return exceptions.get(i);
76 }
77
78 public Row getRow(int i) {
79 return actions.get(i);
80 }
81
82 public String getHostnamePort(final int i) {
83 return this.hostnameAndPort.get(i);
84 }
85
86 public boolean mayHaveClusterIssues() {
87 boolean res = false;
88
89
90 for (Throwable t : exceptions) {
91 if ( !(t instanceof DoNotRetryIOException ||
92 t instanceof NeedUnmanagedConnectionException)) {
93 res = true;
94 }
95 }
96 return res;
97 }
98
99
100 public static String pluralize(Collection<?> c) {
101 return pluralize(c.size());
102 }
103
104 public static String pluralize(int c) {
105 return c > 1 ? "s" : "";
106 }
107
108 public static String getDesc(List<Throwable> exceptions,
109 List<? extends Row> actions,
110 List<String> hostnamePort) {
111 String s = getDesc(classifyExs(exceptions));
112 StringBuilder addrs = new StringBuilder(s);
113 addrs.append("servers with issues: ");
114 Set<String> uniqAddr = new HashSet<String>();
115 uniqAddr.addAll(hostnamePort);
116
117 for (String addr : uniqAddr) {
118 addrs.append(addr).append(", ");
119 }
120 return uniqAddr.isEmpty() ? addrs.toString() : addrs.substring(0, addrs.length() - 2);
121 }
122
123 public String getExhaustiveDescription() {
124 StringWriter errorWriter = new StringWriter();
125 PrintWriter pw = new PrintWriter(errorWriter);
126 for (int i = 0; i < this.exceptions.size(); ++i) {
127 Throwable t = this.exceptions.get(i);
128 Row action = this.actions.get(i);
129 String server = this.hostnameAndPort.get(i);
130 pw.append("exception");
131 if (this.exceptions.size() > 1) {
132 pw.append(" #" + i);
133 }
134 pw.append(" from " + server + " for "
135 + ((action == null) ? "unknown key" : Bytes.toStringBinary(action.getRow())));
136 if (t != null) {
137 pw.println();
138 t.printStackTrace(pw);
139 }
140 }
141 pw.flush();
142 return errorWriter.toString();
143 }
144
145
146 public static Map<String, Integer> classifyExs(List<Throwable> ths) {
147 Map<String, Integer> cls = new HashMap<String, Integer>();
148 for (Throwable t : ths) {
149 if (t == null) continue;
150 String name = "";
151 if (t instanceof DoNotRetryIOException) {
152 name = t.getMessage();
153 } else {
154 name = t.getClass().getSimpleName();
155 }
156 Integer i = cls.get(name);
157 if (i == null) {
158 i = 0;
159 }
160 i += 1;
161 cls.put(name, i);
162 }
163 return cls;
164 }
165
166 public static String getDesc(Map<String,Integer> classificaton) {
167 StringBuilder classificatons =new StringBuilder(11);
168 for (Map.Entry<String, Integer> e : classificaton.entrySet()) {
169 classificatons.append(e.getKey());
170 classificatons.append(": ");
171 classificatons.append(e.getValue());
172 classificatons.append(" time");
173 classificatons.append(pluralize(e.getValue()));
174 classificatons.append(", ");
175 }
176 return classificatons.toString();
177 }
178
179 }