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 */ 018package org.apache.hadoop.hbase.master.procedure; 019 020import java.io.IOException; 021import java.util.function.Supplier; 022import org.apache.hadoop.hbase.NamespaceDescriptor; 023import org.apache.hadoop.hbase.TableName; 024import org.apache.hadoop.hbase.master.MasterFileSystem; 025import org.apache.hadoop.hbase.master.TableNamespaceManager; 026import org.apache.hadoop.hbase.procedure2.StateMachineProcedure; 027import org.apache.hadoop.hbase.rsgroup.RSGroupInfo; 028import org.apache.hadoop.hbase.util.CommonFSUtils; 029import org.apache.yetus.audience.InterfaceAudience; 030 031/** 032 * Base class for all the Namespace procedures that want to use a StateMachineProcedure. It provide 033 * some basic helpers like basic locking and basic toStringClassDetails(). 034 */ 035@InterfaceAudience.Private 036public abstract class AbstractStateMachineNamespaceProcedure<TState> 037 extends StateMachineProcedure<MasterProcedureEnv, TState> implements TableProcedureInterface { 038 039 private final ProcedurePrepareLatch syncLatch; 040 041 protected AbstractStateMachineNamespaceProcedure() { 042 // Required by the Procedure framework to create the procedure on replay 043 syncLatch = null; 044 } 045 046 protected AbstractStateMachineNamespaceProcedure(final MasterProcedureEnv env) { 047 this(env, null); 048 } 049 050 protected AbstractStateMachineNamespaceProcedure(final MasterProcedureEnv env, 051 final ProcedurePrepareLatch latch) { 052 this.setOwner(env.getRequestUser()); 053 this.syncLatch = latch; 054 } 055 056 protected abstract String getNamespaceName(); 057 058 @Override 059 public TableName getTableName() { 060 return DUMMY_NAMESPACE_TABLE_NAME; 061 } 062 063 @Override 064 public abstract TableOperationType getTableOperationType(); 065 066 @Override 067 public void toStringClassDetails(final StringBuilder sb) { 068 sb.append(getClass().getSimpleName()); 069 sb.append(", namespace="); 070 sb.append(getNamespaceName()); 071 } 072 073 @Override 074 protected boolean waitInitialized(MasterProcedureEnv env) { 075 return env.waitInitialized(this); 076 } 077 078 @Override 079 protected LockState acquireLock(final MasterProcedureEnv env) { 080 if (env.getProcedureScheduler().waitNamespaceExclusiveLock(this, getNamespaceName())) { 081 return LockState.LOCK_EVENT_WAIT; 082 } 083 return LockState.LOCK_ACQUIRED; 084 } 085 086 @Override 087 protected void releaseLock(final MasterProcedureEnv env) { 088 env.getProcedureScheduler().wakeNamespaceExclusiveLock(this, getNamespaceName()); 089 } 090 091 /** 092 * Insert/update the row into the ns family of meta table. 093 * @param env MasterProcedureEnv 094 */ 095 protected static void addOrUpdateNamespace(MasterProcedureEnv env, NamespaceDescriptor ns) 096 throws IOException { 097 getTableNamespaceManager(env).addOrUpdateNamespace(ns); 098 } 099 100 protected static TableNamespaceManager getTableNamespaceManager(MasterProcedureEnv env) { 101 return env.getMasterServices().getClusterSchema().getTableNamespaceManager(); 102 } 103 104 /** 105 * Create the namespace directory 106 * @param env MasterProcedureEnv 107 * @param nsDescriptor NamespaceDescriptor 108 */ 109 protected static void createDirectory(MasterProcedureEnv env, NamespaceDescriptor nsDescriptor) 110 throws IOException { 111 createDirectory(env.getMasterServices().getMasterFileSystem(), nsDescriptor); 112 } 113 114 public static void createDirectory(MasterFileSystem mfs, NamespaceDescriptor nsDescriptor) 115 throws IOException { 116 mfs.getFileSystem() 117 .mkdirs(CommonFSUtils.getNamespaceDir(mfs.getRootDir(), nsDescriptor.getName())); 118 } 119 120 protected void releaseSyncLatch() { 121 ProcedurePrepareLatch.releaseLatch(syncLatch, this); 122 } 123 124 protected final void checkNamespaceRSGroup(MasterProcedureEnv env, NamespaceDescriptor nd) 125 throws IOException { 126 Supplier<String> forWhom = () -> "namespace " + nd.getName(); 127 RSGroupInfo rsGroupInfo = MasterProcedureUtil.checkGroupExists( 128 env.getMasterServices().getRSGroupInfoManager()::getRSGroup, 129 MasterProcedureUtil.getNamespaceGroup(nd), forWhom); 130 MasterProcedureUtil.checkGroupNotEmpty(rsGroupInfo, forWhom); 131 } 132}