001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to you under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.hadoop.hbase.quotas; 018 019import java.io.IOException; 020import java.util.Optional; 021 022import org.apache.hadoop.conf.Configuration; 023import org.apache.hadoop.hbase.CoprocessorEnvironment; 024import org.apache.hadoop.hbase.TableName; 025import org.apache.hadoop.hbase.client.Admin; 026import org.apache.hadoop.hbase.client.Connection; 027import org.apache.hadoop.hbase.coprocessor.MasterCoprocessor; 028import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment; 029import org.apache.hadoop.hbase.coprocessor.MasterObserver; 030import org.apache.hadoop.hbase.coprocessor.ObserverContext; 031import org.apache.yetus.audience.InterfaceAudience; 032import org.apache.hadoop.hbase.shaded.protobuf.generated.QuotaProtos.Quotas; 033 034/** 035 * An observer to automatically delete quotas when a table/namespace 036 * is deleted. 037 */ 038@InterfaceAudience.Private 039public class MasterQuotasObserver implements MasterCoprocessor, MasterObserver { 040 public static final String REMOVE_QUOTA_ON_TABLE_DELETE = "hbase.quota.remove.on.table.delete"; 041 public static final boolean REMOVE_QUOTA_ON_TABLE_DELETE_DEFAULT = true; 042 043 private CoprocessorEnvironment cpEnv; 044 private Configuration conf; 045 private boolean quotasEnabled = false; 046 047 @Override 048 public Optional<MasterObserver> getMasterObserver() { 049 return Optional.of(this); 050 } 051 052 @Override 053 public void start(CoprocessorEnvironment ctx) throws IOException { 054 this.cpEnv = ctx; 055 this.conf = cpEnv.getConfiguration(); 056 this.quotasEnabled = QuotaUtil.isQuotaEnabled(conf); 057 } 058 059 @Override 060 public void postDeleteTable( 061 ObserverContext<MasterCoprocessorEnvironment> ctx, TableName tableName) throws IOException { 062 // Do nothing if quotas aren't enabled 063 if (!quotasEnabled) { 064 return; 065 } 066 final Connection conn = ctx.getEnvironment().getConnection(); 067 Quotas quotas = QuotaUtil.getTableQuota(conn, tableName); 068 if (quotas != null){ 069 if (quotas.hasSpace()){ 070 QuotaSettings settings = QuotaSettingsFactory.removeTableSpaceLimit(tableName); 071 try (Admin admin = conn.getAdmin()) { 072 admin.setQuota(settings); 073 } 074 } 075 if (quotas.hasThrottle()){ 076 QuotaSettings settings = QuotaSettingsFactory.unthrottleTable(tableName); 077 try (Admin admin = conn.getAdmin()) { 078 admin.setQuota(settings); 079 } 080 } 081 } 082 } 083 084 @Override 085 public void postDeleteNamespace( 086 ObserverContext<MasterCoprocessorEnvironment> ctx, String namespace) throws IOException { 087 // Do nothing if quotas aren't enabled 088 if (!quotasEnabled) { 089 return; 090 } 091 final Connection conn = ctx.getEnvironment().getConnection(); 092 Quotas quotas = QuotaUtil.getNamespaceQuota(conn, namespace); 093 if (quotas != null) { 094 if (quotas.hasSpace()) { 095 QuotaSettings settings = QuotaSettingsFactory.removeNamespaceSpaceLimit(namespace); 096 try (Admin admin = conn.getAdmin()) { 097 admin.setQuota(settings); 098 } 099 } 100 if (quotas.hasThrottle()) { 101 QuotaSettings settings = QuotaSettingsFactory.unthrottleNamespace(namespace); 102 try (Admin admin = conn.getAdmin()) { 103 admin.setQuota(settings); 104 } 105 } 106 } 107 } 108}