001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019package org.apache.hadoop.hbase.quotas; 020 021import java.util.regex.Matcher; 022import java.util.regex.Pattern; 023 024import org.apache.yetus.audience.InterfaceAudience; 025 026/** 027 * Describe the throttling result. 028 * 029 * TODO: At some point this will be handled on the client side to prevent 030 * operation to go on the server if the waitInterval is grater than the one got 031 * as result of this exception. 032 * 033 * @deprecated replaced by {@link RpcThrottlingException} since hbase-2.0.0. 034 */ 035@Deprecated 036@InterfaceAudience.Public 037public class ThrottlingException extends QuotaExceededException { 038 private static final long serialVersionUID = 1406576492085155743L; 039 040 @InterfaceAudience.Public 041 public enum Type { 042 NumRequestsExceeded, 043 RequestSizeExceeded, 044 NumReadRequestsExceeded, 045 NumWriteRequestsExceeded, 046 WriteSizeExceeded, 047 ReadSizeExceeded, 048 } 049 050 private static final String[] MSG_TYPE = new String[] { 051 "number of requests exceeded", 052 "request size limit exceeded", 053 "number of read requests exceeded", 054 "number of write requests exceeded", 055 "write size limit exceeded", 056 "read size limit exceeded", 057 }; 058 059 private static final String MSG_WAIT = " - wait "; 060 061 private long waitInterval; 062 private Type type; 063 064 public ThrottlingException(String msg) { 065 super(msg); 066 067 // Dirty workaround to get the information after 068 // ((RemoteException)e.getCause()).unwrapRemoteException() 069 for (int i = 0; i < MSG_TYPE.length; ++i) { 070 int index = msg.indexOf(MSG_TYPE[i]); 071 if (index >= 0) { 072 String waitTimeStr = msg.substring(index + MSG_TYPE[i].length() + MSG_WAIT.length()); 073 type = Type.values()[i]; 074 waitInterval = timeFromString(waitTimeStr); 075 break; 076 } 077 } 078 } 079 080 public ThrottlingException(final Type type, final long waitInterval, final String msg) { 081 super(msg); 082 this.waitInterval = waitInterval; 083 this.type = type; 084 } 085 086 public Type getType() { 087 return this.type; 088 } 089 090 public long getWaitInterval() { 091 return this.waitInterval; 092 } 093 094 public static void throwNumRequestsExceeded(final long waitInterval) 095 throws ThrottlingException { 096 throwThrottlingException(Type.NumRequestsExceeded, waitInterval); 097 } 098 099 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}