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