View Javadoc

1   /*
2    * Copyright 2010 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.hadoop.hbase.client;
22  
23  import org.apache.hadoop.hbase.DoNotRetryIOException;
24  import org.apache.hadoop.hbase.HServerAddress;
25  
26  import java.util.Collection;
27  import java.util.HashMap;
28  import java.util.HashSet;
29  import java.util.List;
30  import java.util.Map;
31  import java.util.Set;
32  
33  /**
34   * This subclass of {@link org.apache.hadoop.hbase.client.RetriesExhaustedException}
35   * is thrown when we have more information about which rows were causing which
36   * exceptions on what servers.  You can call {@link #mayHaveClusterIssues()}
37   * and if the result is false, you have input error problems, otherwise you
38   * may have cluster issues.  You can iterate over the causes, rows and last
39   * known server addresses via {@link #getNumExceptions()} and
40   * {@link #getCause(int)}, {@link #getRow(int)} and {@link #getAddress(int)}.
41   */
42  public class RetriesExhaustedWithDetailsException extends RetriesExhaustedException {
43  
44    List<Throwable> exceptions;
45    List<Row> actions;
46    List<HServerAddress> addresses;
47  
48    public RetriesExhaustedWithDetailsException(List<Throwable> exceptions,
49                                                List<Row> actions,
50                                                List<HServerAddress> addresses) {
51      super("Failed " + exceptions.size() + " action" +
52          pluralize(exceptions) + ": " +
53          getDesc(exceptions,actions,addresses));
54  
55      this.exceptions = exceptions;
56      this.actions = actions;
57      this.addresses = addresses;
58    }
59  
60    public List<Throwable> getCauses() {
61      return exceptions;
62    }
63  
64    public int getNumExceptions() {
65      return exceptions.size();
66    }
67  
68    public Throwable getCause(int i) {
69      return exceptions.get(i);
70    }
71  
72    public Row getRow(int i) {
73      return actions.get(i);
74    }
75  
76    public HServerAddress getAddress(int i) {
77      return addresses.get(i);
78    }
79  
80    public boolean mayHaveClusterIssues() {
81      boolean res = false;
82  
83      // If all of the exceptions are DNRIOE not exception
84      for (Throwable t : exceptions) {
85        if ( !(t instanceof DoNotRetryIOException)) {
86          res = true;
87        }
88      }
89      return res;
90    }
91  
92  
93    public static String pluralize(Collection<?> c) {
94      return pluralize(c.size());
95    }
96  
97    public static String pluralize(int c) {
98      return c > 1 ? "s" : "";
99    }
100 
101   public static String getDesc(List<Throwable> exceptions,
102                                List<Row> actions,
103                                List<HServerAddress> addresses) {
104     String s = getDesc(classifyExs(exceptions));
105     s += "servers with issues: ";
106     Set<HServerAddress> uniqAddr = new HashSet<HServerAddress>();
107     uniqAddr.addAll(addresses);
108     for(HServerAddress addr : uniqAddr) {
109       s += addr + ", ";
110     }
111     return s;
112   }
113 
114   public static Map<String, Integer> classifyExs(List<Throwable> ths) {
115     Map<String, Integer> cls = new HashMap<String, Integer>();
116     for (Throwable t : ths) {
117       if (t == null) continue;
118       String name = t.getClass().getSimpleName();
119       Integer i = cls.get(name);
120       if (i == null) {
121         i = 0;
122       }
123       i += 1;
124       cls.put(name, i);
125     }
126     return cls;
127   }
128 
129   public static String getDesc(Map<String,Integer> classificaton) {
130     String s = "";
131     for (Map.Entry<String, Integer> e : classificaton.entrySet()) {
132       s += e.getKey() + ": " + e.getValue() + " time" +
133           pluralize(e.getValue()) + ", ";
134     }
135     return s;
136   }
137 
138 }