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  import org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyException;
26  import org.apache.hadoop.hbase.util.Addressing;
27  
28  import java.util.Collection;
29  import java.util.HashMap;
30  import java.util.HashSet;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.Set;
34  
35  /**
36   * This subclass of {@link org.apache.hadoop.hbase.client.RetriesExhaustedException}
37   * is thrown when we have more information about which rows were causing which
38   * exceptions on what servers.  You can call {@link #mayHaveClusterIssues()}
39   * and if the result is false, you have input error problems, otherwise you
40   * may have cluster issues.  You can iterate over the causes, rows and last
41   * known server addresses via {@link #getNumExceptions()} and
42   * {@link #getCause(int)}, {@link #getRow(int)} and {@link #getAddress(int)}.
43   */
44  @SuppressWarnings("serial")
45  public class RetriesExhaustedWithDetailsException
46  extends RetriesExhaustedException {
47    List<Throwable> exceptions;
48    List<Row> actions;
49    List<String> hostnameAndPort;
50  
51    public RetriesExhaustedWithDetailsException(List<Throwable> exceptions,
52                                                List<Row> actions,
53                                                List<String> hostnameAndPort) {
54      super("Failed " + exceptions.size() + " action" +
55          pluralize(exceptions) + ": " +
56          getDesc(exceptions, actions, hostnameAndPort));
57  
58      this.exceptions = exceptions;
59      this.actions = actions;
60      this.hostnameAndPort = hostnameAndPort;
61    }
62  
63    public List<Throwable> getCauses() {
64      return exceptions;
65    }
66  
67    public int getNumExceptions() {
68      return exceptions.size();
69    }
70  
71    public Throwable getCause(int i) {
72      return exceptions.get(i);
73    }
74  
75    public Row getRow(int i) {
76      return actions.get(i);
77    }
78  
79    public HServerAddress getAddress(int i) {
80      return new HServerAddress(Addressing.createInetSocketAddressFromHostAndPortStr(getHostnamePort(i)));
81    }
82  
83    public String getHostnamePort(final int i) {
84      return this.hostnameAndPort.get(i);
85    }
86  
87    public boolean mayHaveClusterIssues() {
88      boolean res = false;
89  
90      // If all of the exceptions are DNRIOE not exception
91      for (Throwable t : exceptions) {
92        if ( !(t instanceof DoNotRetryIOException)) {
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<Row> actions,
110                                List<String> hostnamePort) {
111     String s = getDesc(classifyExs(exceptions));
112     s += "servers with issues: ";
113     Set<String> uniqAddr = new HashSet<String>();
114     uniqAddr.addAll(hostnamePort);
115     for(String addr : uniqAddr) {
116       s += addr + ", ";
117     }
118     return s;
119   }
120 
121   public static Map<String, Integer> classifyExs(List<Throwable> ths) {
122     Map<String, Integer> cls = new HashMap<String, Integer>();
123     for (Throwable t : ths) {
124       if (t == null) continue;
125       String name = "";
126       if (t instanceof DoNotRetryIOException) {
127         name = t.getMessage();
128       } else {
129         name = t.getClass().getSimpleName();
130       }
131       Integer i = cls.get(name);
132       if (i == null) {
133         i = 0;
134       }
135       i += 1;
136       cls.put(name, i);
137     }
138     return cls;
139   }
140 
141   public static String getDesc(Map<String,Integer> classificaton) {
142     String s = "";
143     for (Map.Entry<String, Integer> e : classificaton.entrySet()) {
144       s += e.getKey() + ": " + e.getValue() + " time" +
145           pluralize(e.getValue()) + ", ";
146     }
147     return s;
148   }
149 
150 }