View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional information regarding
4    * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with the License. You may obtain a
6    * copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable
7    * law or agreed to in writing, software distributed under the License is distributed on an "AS IS"
8    * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
9    * for the specific language governing permissions and limitations under the License.
10   */
11  
12  package org.apache.hadoop.hbase.quotas;
13  
14  import java.util.regex.Matcher;
15  import java.util.regex.Pattern;
16  
17  import org.apache.hadoop.hbase.classification.InterfaceAudience;
18  import org.apache.hadoop.hbase.classification.InterfaceStability;
19  
20  /**
21   * Describe the throttling result. TODO: At some point this will be handled on the client side to
22   * prevent operation to go on the server if the waitInterval is grater than the one got as result of
23   * this exception.
24   * @deprecated  replaced by {@link RpcThrottlingException}
25   */
26  @InterfaceAudience.Public
27  @InterfaceStability.Evolving
28  public class ThrottlingException extends QuotaExceededException {
29    private static final long serialVersionUID = 1406576492085155743L;
30  
31    @InterfaceAudience.Public
32    @InterfaceStability.Evolving
33    public enum Type {
34      NumRequestsExceeded, RequestSizeExceeded, NumReadRequestsExceeded, NumWriteRequestsExceeded,
35      WriteSizeExceeded, ReadSizeExceeded,
36    }
37  
38    private static final String[] MSG_TYPE =
39        new String[] { "number of requests exceeded", "request size limit exceeded",
40            "number of read requests exceeded", "number of write requests exceeded",
41            "write size limit exceeded", "read size limit exceeded", };
42  
43    private static final String MSG_WAIT = " - wait ";
44  
45    private long waitInterval;
46    private Type type;
47  
48    public ThrottlingException(String msg) {
49      super(msg);
50  
51      // Dirty workaround to get the information after
52      // ((RemoteException)e.getCause()).unwrapRemoteException()
53      for (int i = 0; i < MSG_TYPE.length; ++i) {
54        int index = msg.indexOf(MSG_TYPE[i]);
55        if (index >= 0) {
56          String waitTimeStr = msg.substring(index + MSG_TYPE[i].length() + MSG_WAIT.length());
57          type = Type.values()[i];
58          waitInterval = timeFromString(waitTimeStr);
59          break;
60        }
61      }
62    }
63  
64    public ThrottlingException(final Type type, final long waitInterval, final String msg) {
65      super(msg);
66      this.waitInterval = waitInterval;
67      this.type = type;
68    }
69  
70    public Type getType() {
71      return this.type;
72    }
73  
74    public long getWaitInterval() {
75      return this.waitInterval;
76    }
77  
78    public static void throwNumRequestsExceeded(final long waitInterval) throws ThrottlingException {
79      throwThrottlingException(Type.NumRequestsExceeded, waitInterval);
80    }
81    
82    public static void throwRequestSizeExceeded(final long waitInterval)
83        throws ThrottlingException {
84      throwThrottlingException(Type.RequestSizeExceeded, waitInterval);
85    }
86  
87    public static void throwNumReadRequestsExceeded(final long waitInterval)
88        throws ThrottlingException {
89      throwThrottlingException(Type.NumReadRequestsExceeded, waitInterval);
90    }
91  
92    public static void throwNumWriteRequestsExceeded(final long waitInterval)
93        throws ThrottlingException {
94      throwThrottlingException(Type.NumWriteRequestsExceeded, waitInterval);
95    }
96  
97    public static void throwWriteSizeExceeded(final long waitInterval) throws ThrottlingException {
98      throwThrottlingException(Type.WriteSizeExceeded, waitInterval);
99    }
100 
101   public static void throwReadSizeExceeded(final long waitInterval) throws ThrottlingException {
102     throwThrottlingException(Type.ReadSizeExceeded, waitInterval);
103   }
104 
105   private static void throwThrottlingException(final Type type, final long waitInterval)
106       throws ThrottlingException {
107     String msg = MSG_TYPE[type.ordinal()] + MSG_WAIT + formatTime(waitInterval);
108     throw new ThrottlingException(type, waitInterval, msg);
109   }
110 
111   public static String formatTime(long timeDiff) {
112     StringBuilder buf = new StringBuilder();
113     long hours = timeDiff / (60 * 60 * 1000);
114     long rem = (timeDiff % (60 * 60 * 1000));
115     long minutes = rem / (60 * 1000);
116     rem = rem % (60 * 1000);
117     float seconds = rem / 1000.0f;
118 
119     if (hours != 0) {
120       buf.append(hours);
121       buf.append("hrs, ");
122     }
123     if (minutes != 0) {
124       buf.append(minutes);
125       buf.append("mins, ");
126     }
127     buf.append(String.format("%.2fsec", seconds));
128     return buf.toString();
129   }
130 
131   private static long timeFromString(String timeDiff) {
132     Pattern[] patterns =
133         new Pattern[] { Pattern.compile("^(\\d+\\.\\d\\d)sec"),
134             Pattern.compile("^(\\d+)mins, (\\d+\\.\\d\\d)sec"),
135             Pattern.compile("^(\\d+)hrs, (\\d+)mins, (\\d+\\.\\d\\d)sec") };
136 
137     for (int i = 0; i < patterns.length; ++i) {
138       Matcher m = patterns[i].matcher(timeDiff);
139       if (m.find()) {
140         long time = Math.round(Float.parseFloat(m.group(1 + i)) * 1000);
141         if (i > 0) {
142           time += Long.parseLong(m.group(i)) * (60 * 1000);
143         }
144         if (i > 1) {
145           time += Long.parseLong(m.group(i - 1)) * (60 * 60 * 1000);
146         }
147         return time;
148       }
149     }
150 
151     return -1;
152   }
153 }