1
2
3
4
5
6
7
8
9
10
11 package org.apache.hadoop.hbase.namespace;
12
13 import java.io.IOException;
14
15 import org.apache.commons.logging.Log;
16 import org.apache.commons.logging.LogFactory;
17 import org.apache.hadoop.hbase.HBaseIOException;
18 import org.apache.hadoop.hbase.HRegionInfo;
19 import org.apache.hadoop.hbase.MetaTableAccessor;
20 import org.apache.hadoop.hbase.NamespaceDescriptor;
21 import org.apache.hadoop.hbase.TableExistsException;
22 import org.apache.hadoop.hbase.TableName;
23 import org.apache.hadoop.hbase.classification.InterfaceAudience;
24 import org.apache.hadoop.hbase.master.MasterServices;
25 import org.apache.hadoop.hbase.quotas.QuotaExceededException;
26
27 import com.google.common.annotations.VisibleForTesting;
28
29
30
31
32
33
34 @InterfaceAudience.Private
35 public class NamespaceAuditor {
36 private static Log LOG = LogFactory.getLog(NamespaceAuditor.class);
37 static final String NS_AUDITOR_INIT_TIMEOUT = "hbase.namespace.auditor.init.timeout";
38 static final int DEFAULT_NS_AUDITOR_INIT_TIMEOUT = 120000;
39 private NamespaceStateManager stateManager;
40 private MasterServices masterServices;
41
42 public NamespaceAuditor(MasterServices masterServices) {
43 this.masterServices = masterServices;
44 stateManager = new NamespaceStateManager(masterServices, masterServices.getZooKeeper());
45 }
46
47 public void start() throws IOException {
48 stateManager.start();
49 LOG.info("NamespaceAuditor started.");
50 }
51
52
53
54
55
56
57
58
59
60 public void checkQuotaToCreateTable(TableName tName, int regions) throws IOException {
61 if (stateManager.isInitialized()) {
62
63 if (MetaTableAccessor.tableExists(this.masterServices.getConnection(), tName)) {
64 throw new TableExistsException(tName);
65 }
66 stateManager.checkAndUpdateNamespaceTableCount(tName, regions);
67 } else {
68 checkTableTypeAndThrowException(tName);
69 }
70 }
71
72
73
74
75
76
77
78 public void checkQuotaToUpdateRegion(TableName tName, int regions) throws IOException {
79 if (stateManager.isInitialized()) {
80 stateManager.checkAndUpdateNamespaceRegionCount(tName, regions);
81 } else {
82 checkTableTypeAndThrowException(tName);
83 }
84 }
85
86 private void checkTableTypeAndThrowException(TableName name) throws IOException {
87 if (name.isSystemTable()) {
88 LOG.debug("Namespace auditor checks not performed for table " + name.getNameAsString());
89 } else {
90 throw new HBaseIOException(name
91 + " is being created even before namespace auditor has been initialized.");
92 }
93 }
94
95
96
97
98
99
100
101 public int getRegionCountOfTable(TableName tName) throws IOException {
102 if (stateManager.isInitialized()) {
103 NamespaceTableAndRegionInfo state = stateManager.getState(tName.getNamespaceAsString());
104 return state != null ? state.getRegionCountOfTable(tName) : -1;
105 }
106 checkTableTypeAndThrowException(tName);
107 return -1;
108 }
109
110 public void checkQuotaToSplitRegion(HRegionInfo hri) throws IOException {
111 if (!stateManager.isInitialized()) {
112 throw new IOException(
113 "Split operation is being performed even before namespace auditor is initialized.");
114 } else if (!stateManager.checkAndUpdateNamespaceRegionCount(hri.getTable(),
115 hri.getRegionName(), 1)) {
116 throw new QuotaExceededException("Region split not possible for :" + hri.getEncodedName()
117 + " as quota limits are exceeded ");
118 }
119 }
120
121 public void updateQuotaForRegionMerge(HRegionInfo hri) throws IOException {
122 if (!stateManager.isInitialized()) {
123 throw new IOException(
124 "Merge operation is being performed even before namespace auditor is initialized.");
125 } else if (!stateManager
126 .checkAndUpdateNamespaceRegionCount(hri.getTable(), hri.getRegionName(), -1)) {
127 throw new QuotaExceededException("Region split not possible for :" + hri.getEncodedName()
128 + " as quota limits are exceeded ");
129 }
130 }
131
132 public void addNamespace(NamespaceDescriptor ns) throws IOException {
133 stateManager.addNamespace(ns.getName());
134 }
135
136 public void deleteNamespace(String namespace) throws IOException {
137 stateManager.deleteNamespace(namespace);
138 }
139
140 public void removeFromNamespaceUsage(TableName tableName) throws IOException {
141 stateManager.removeTable(tableName);
142 }
143
144 public void removeRegionFromNamespaceUsage(HRegionInfo hri) throws IOException {
145 stateManager.removeRegionFromTable(hri);
146 }
147
148
149
150
151
152
153 @VisibleForTesting
154 NamespaceTableAndRegionInfo getState(String namespace) {
155 if (stateManager.isInitialized()) {
156 return stateManager.getState(namespace);
157 }
158 return null;
159 }
160
161
162
163
164
165 public boolean isInitialized() {
166 return stateManager.isInitialized();
167 }
168 }