View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to you under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    * http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.hadoop.hbase.quotas;
18  
19  
20  import org.apache.commons.logging.Log;
21  import org.apache.commons.logging.LogFactory;
22  import org.apache.hadoop.hbase.classification.InterfaceAudience;
23  import org.apache.hadoop.hbase.classification.InterfaceStability;
24  
25  /**
26   * An Exception that is thrown when a space quota is in violation.
27   */
28  @InterfaceAudience.Public
29  @InterfaceStability.Evolving
30  public class SpaceLimitingException extends QuotaExceededException {
31    private static final long serialVersionUID = 2319438922387583600L;
32    private static final Log LOG = LogFactory.getLog(SpaceLimitingException.class);
33    private static final String MESSAGE_PREFIX = SpaceLimitingException.class.getName() + ": ";
34  
35    private final String policyName;
36  
37    public SpaceLimitingException(String msg) {
38      super(parseMessage(msg));
39  
40      // Hack around ResponseConverter expecting to invoke a single-arg String constructor
41      // on this class
42      if (msg != null) {
43        for (SpaceViolationPolicy definedPolicy : SpaceViolationPolicy.values()) {
44          if (msg.indexOf(definedPolicy.name()) != -1) {
45            policyName = definedPolicy.name();
46            return;
47          }
48        }
49      }
50      policyName = null;
51    }
52  
53    public SpaceLimitingException(String policyName, String msg) {
54      super(msg);
55      this.policyName = policyName;
56    }
57  
58    public SpaceLimitingException(String policyName, String msg, Throwable e) {
59      super(msg, e);
60      this.policyName = policyName;
61    }
62  
63    /**
64     * Returns the violation policy in effect.
65     *
66     * @return The violation policy in effect.
67     */
68    public String getViolationPolicy() {
69      return this.policyName;
70    }
71  
72    private static String parseMessage(String originalMessage) {
73      // Serialization of the exception places a duplicate class name. Try to strip that off if it
74      // exists. Best effort... Looks something like:
75      // "org.apache.hadoop.hbase.quotas.SpaceLimitingException: NO_INSERTS A Put is disallowed due
76      // to a space quota."
77      if (originalMessage != null && originalMessage.startsWith(MESSAGE_PREFIX)) {
78        // If it starts with the class name, rip off the policy too.
79        try {
80          int index = originalMessage.indexOf(' ', MESSAGE_PREFIX.length());
81          return originalMessage.substring(index + 1);
82        } catch (Exception e) {
83          if (LOG.isTraceEnabled()) {
84            LOG.trace("Failed to trim exception message", e);
85          }
86        }
87      }
88      return originalMessage;
89    }
90  
91    @Override
92    public String getMessage() {
93      return (policyName == null ? "(unknown policy)" : policyName) + " " + super.getMessage();
94    }
95  }