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 public void checkQuotaToSplitRegion(HRegionInfo hri) throws IOException {
96 if (!stateManager.isInitialized()) {
97 throw new IOException(
98 "Split operation is being performed even before namespace auditor is initialized.");
99 } else if (!stateManager.checkAndUpdateNamespaceRegionCount(hri.getTable(),
100 hri.getRegionName(), 1)) {
101 throw new QuotaExceededException("Region split not possible for :" + hri.getEncodedName()
102 + " as quota limits are exceeded ");
103 }
104 }
105
106 public void updateQuotaForRegionMerge(HRegionInfo hri) throws IOException {
107 if (!stateManager.isInitialized()) {
108 throw new IOException(
109 "Merge operation is being performed even before namespace auditor is initialized.");
110 } else if (!stateManager
111 .checkAndUpdateNamespaceRegionCount(hri.getTable(), hri.getRegionName(), -1)) {
112 throw new QuotaExceededException("Region split not possible for :" + hri.getEncodedName()
113 + " as quota limits are exceeded ");
114 }
115 }
116
117 public void addNamespace(NamespaceDescriptor ns) throws IOException {
118 stateManager.addNamespace(ns.getName());
119 }
120
121 public void deleteNamespace(String namespace) throws IOException {
122 stateManager.deleteNamespace(namespace);
123 }
124
125 public void removeFromNamespaceUsage(TableName tableName) throws IOException {
126 stateManager.removeTable(tableName);
127 }
128
129 public void removeRegionFromNamespaceUsage(HRegionInfo hri) throws IOException {
130 stateManager.removeRegionFromTable(hri);
131 }
132
133
134
135
136
137
138 @VisibleForTesting
139 NamespaceTableAndRegionInfo getState(String namespace) {
140 if (stateManager.isInitialized()) {
141 return stateManager.getState(namespace);
142 }
143 return null;
144 }
145
146
147
148
149
150 public boolean isInitialized() {
151 return stateManager.isInitialized();
152 }
153 }