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