1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.quotas;
20
21 import java.util.regex.Matcher;
22 import java.util.regex.Pattern;
23
24 import org.apache.hadoop.hbase.classification.InterfaceAudience;
25 import org.apache.hadoop.hbase.classification.InterfaceStability;
26
27
28
29
30
31
32
33
34 @InterfaceAudience.Public
35 @InterfaceStability.Evolving
36 public class ThrottlingException extends QuotaExceededException {
37 private static final long serialVersionUID = 1406576492085155743L;
38
39 @InterfaceAudience.Public
40 @InterfaceStability.Evolving
41 public enum Type {
42 NumRequestsExceeded,
43 RequestSizeExceeded,
44 NumReadRequestsExceeded,
45 NumWriteRequestsExceeded,
46 WriteSizeExceeded,
47 ReadSizeExceeded,
48 }
49
50 private static final String[] MSG_TYPE = new String[] {
51 "number of requests exceeded",
52 "request size limit exceeded",
53 "number of read requests exceeded",
54 "number of write requests exceeded",
55 "write size limit exceeded",
56 "read size limit exceeded",
57 };
58
59 private static final String MSG_WAIT = " - wait ";
60
61 private long waitInterval;
62 private Type type;
63
64 public ThrottlingException(String msg) {
65 super(msg);
66
67
68
69 for (int i = 0; i < MSG_TYPE.length; ++i) {
70 int index = msg.indexOf(MSG_TYPE[i]);
71 if (index >= 0) {
72 String waitTimeStr = msg.substring(index + MSG_TYPE[i].length() + MSG_WAIT.length());
73 type = Type.values()[i];;
74 waitInterval = timeFromString(waitTimeStr);
75 break;
76 }
77 }
78 }
79
80 public ThrottlingException(final Type type, final long waitInterval, final String msg) {
81 super(msg);
82 this.waitInterval = waitInterval;
83 this.type = type;
84 }
85
86 public Type getType() {
87 return this.type;
88 }
89
90 public long getWaitInterval() {
91 return this.waitInterval;
92 }
93
94 public static void throwNumRequestsExceeded(final long waitInterval)
95 throws ThrottlingException {
96 throwThrottlingException(Type.NumRequestsExceeded, waitInterval);
97 }
98
99 public static void throwRequestSizeExceeded(final long waitInterval)
100 throws ThrottlingException {
101 throwThrottlingException(Type.RequestSizeExceeded, waitInterval);
102 }
103
104 public static void throwNumReadRequestsExceeded(final long waitInterval)
105 throws ThrottlingException {
106 throwThrottlingException(Type.NumReadRequestsExceeded, waitInterval);
107 }
108
109 public static void throwNumWriteRequestsExceeded(final long waitInterval)
110 throws ThrottlingException {
111 throwThrottlingException(Type.NumWriteRequestsExceeded, waitInterval);
112 }
113
114 public static void throwWriteSizeExceeded(final long waitInterval)
115 throws ThrottlingException {
116 throwThrottlingException(Type.WriteSizeExceeded, waitInterval);
117 }
118
119 public static void throwReadSizeExceeded(final long waitInterval)
120 throws ThrottlingException {
121 throwThrottlingException(Type.ReadSizeExceeded, waitInterval);
122 }
123
124 private static void throwThrottlingException(final Type type, final long waitInterval)
125 throws ThrottlingException {
126 String msg = MSG_TYPE[type.ordinal()] + MSG_WAIT + formatTime(waitInterval);
127 throw new ThrottlingException(type, waitInterval, msg);
128 }
129
130 public static String formatTime(long timeDiff) {
131 StringBuilder buf = new StringBuilder();
132 long hours = timeDiff / (60*60*1000);
133 long rem = (timeDiff % (60*60*1000));
134 long minutes = rem / (60*1000);
135 rem = rem % (60*1000);
136 float seconds = rem / 1000.0f;
137
138 if (hours != 0){
139 buf.append(hours);
140 buf.append("hrs, ");
141 }
142 if (minutes != 0){
143 buf.append(minutes);
144 buf.append("mins, ");
145 }
146 buf.append(String.format("%.2fsec", seconds));
147 return buf.toString();
148 }
149
150 private static long timeFromString(String timeDiff) {
151 Pattern[] patterns = new Pattern[] {
152 Pattern.compile("^(\\d+\\.\\d\\d)sec"),
153 Pattern.compile("^(\\d+)mins, (\\d+\\.\\d\\d)sec"),
154 Pattern.compile("^(\\d+)hrs, (\\d+)mins, (\\d+\\.\\d\\d)sec")
155 };
156
157 for (int i = 0; i < patterns.length; ++i) {
158 Matcher m = patterns[i].matcher(timeDiff);
159 if (m.find()) {
160 long time = Math.round(Float.parseFloat(m.group(1 + i)) * 1000);
161 if (i > 0) {
162 time += Long.parseLong(m.group(i)) * (60 * 1000);
163 }
164 if (i > 1) {
165 time += Long.parseLong(m.group(i - 1)) * (60 * 60 * 1000);
166 }
167 return time;
168 }
169 }
170
171 return -1;
172 }
173 }