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; 019 020import java.util.Collections; 021import java.util.Comparator; 022import java.util.HashSet; 023import java.util.Map; 024import java.util.Set; 025import java.util.TreeMap; 026import java.util.TreeSet; 027import org.apache.hadoop.hbase.util.Bytes; 028import org.apache.yetus.audience.InterfaceAudience; 029 030/** 031 * Namespace POJO class. Used to represent and define namespaces. Descriptors will be persisted in 032 * an hbase table. This works since namespaces are essentially metadata of a group of tables as 033 * opposed to a more tangible container. 034 */ 035@InterfaceAudience.Public 036public class NamespaceDescriptor { 037 038 /** System namespace name. */ 039 public static final byte[] SYSTEM_NAMESPACE_NAME = Bytes.toBytes("hbase"); 040 public static final String SYSTEM_NAMESPACE_NAME_STR = Bytes.toString(SYSTEM_NAMESPACE_NAME); 041 /** Default namespace name. */ 042 public static final byte[] DEFAULT_NAMESPACE_NAME = Bytes.toBytes("default"); 043 public static final String DEFAULT_NAMESPACE_NAME_STR = Bytes.toString(DEFAULT_NAMESPACE_NAME); 044 /** Backup namespace name. */ 045 public static final byte[] BACKUP_NAMESPACE_NAME = Bytes.toBytes("backup"); 046 public static final String BACKUP_NAMESPACE_NAME_STR = Bytes.toString(BACKUP_NAMESPACE_NAME); 047 048 public static final NamespaceDescriptor DEFAULT_NAMESPACE = 049 NamespaceDescriptor.create(DEFAULT_NAMESPACE_NAME_STR).build(); 050 public static final NamespaceDescriptor SYSTEM_NAMESPACE = 051 NamespaceDescriptor.create(SYSTEM_NAMESPACE_NAME_STR).build(); 052 053 public final static Set<String> RESERVED_NAMESPACES; 054 static { 055 Set<String> set = new HashSet<>(); 056 set.add(NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR); 057 set.add(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR); 058 RESERVED_NAMESPACES = Collections.unmodifiableSet(set); 059 } 060 public final static Set<byte[]> RESERVED_NAMESPACES_BYTES; 061 static { 062 Set<byte[]> set = new TreeSet<>(Bytes.BYTES_RAWCOMPARATOR); 063 for (String name : RESERVED_NAMESPACES) { 064 set.add(Bytes.toBytes(name)); 065 } 066 RESERVED_NAMESPACES_BYTES = Collections.unmodifiableSet(set); 067 } 068 069 private String name; 070 private Map<String, String> configuration; 071 072 public static final Comparator<NamespaceDescriptor> NAMESPACE_DESCRIPTOR_COMPARATOR = 073 new Comparator<NamespaceDescriptor>() { 074 @Override 075 public int compare(NamespaceDescriptor namespaceDescriptor, 076 NamespaceDescriptor namespaceDescriptor2) { 077 return namespaceDescriptor.getName().compareTo(namespaceDescriptor2.getName()); 078 } 079 }; 080 081 private NamespaceDescriptor() { 082 } 083 084 private NamespaceDescriptor(String name) { 085 this.name = name; 086 } 087 088 public String getName() { 089 return name; 090 } 091 092 /** 093 * Getter for accessing the configuration value by key 094 */ 095 public String getConfigurationValue(String key) { 096 return configuration.get(key); 097 } 098 099 /** 100 * Getter for fetching an unmodifiable {@link #configuration} map. 101 */ 102 public Map<String, String> getConfiguration() { 103 // shallow pointer copy 104 return Collections.unmodifiableMap(configuration); 105 } 106 107 /** 108 * Setter for storing a configuration setting in {@link #configuration} map. 109 * @param key Config key. Same as XML config key e.g. hbase.something.or.other. 110 * @param value String value. If null, removes the setting. 111 */ 112 public void setConfiguration(String key, String value) { 113 if (value == null) { 114 removeConfiguration(key); 115 } else { 116 configuration.put(key, value); 117 } 118 } 119 120 /** 121 * Remove a config setting represented by the key from the {@link #configuration} map 122 */ 123 public void removeConfiguration(final String key) { 124 configuration.remove(key); 125 } 126 127 @Override 128 public String toString() { 129 StringBuilder s = new StringBuilder(); 130 s.append('{'); 131 s.append(HConstants.NAME); 132 s.append(" => '"); 133 s.append(name); 134 s.append("'"); 135 for (Map.Entry<String, String> e : configuration.entrySet()) { 136 String key = e.getKey(); 137 String value = e.getValue(); 138 if (key == null) { 139 continue; 140 } 141 s.append(", "); 142 s.append(key); 143 s.append(" => '"); 144 s.append(value); 145 s.append("'"); 146 } 147 s.append('}'); 148 return s.toString(); 149 } 150 151 public static Builder create(String name) { 152 return new Builder(name); 153 } 154 155 public static Builder create(NamespaceDescriptor ns) { 156 return new Builder(ns); 157 } 158 159 @InterfaceAudience.Public 160 public static class Builder { 161 private String bName; 162 private Map<String, String> bConfiguration = new TreeMap<>(); 163 164 private Builder(NamespaceDescriptor ns) { 165 this.bName = ns.name; 166 this.bConfiguration.putAll(ns.configuration); 167 } 168 169 private Builder(String name) { 170 this.bName = name; 171 } 172 173 public Builder addConfiguration(Map<String, String> configuration) { 174 this.bConfiguration.putAll(configuration); 175 return this; 176 } 177 178 public Builder addConfiguration(String key, String value) { 179 this.bConfiguration.put(key, value); 180 return this; 181 } 182 183 public Builder removeConfiguration(String key) { 184 this.bConfiguration.remove(key); 185 return this; 186 } 187 188 public NamespaceDescriptor build() { 189 if (this.bName == null) { 190 throw new IllegalArgumentException("A name has to be specified in a namespace."); 191 } 192 193 NamespaceDescriptor desc = new NamespaceDescriptor(this.bName); 194 desc.configuration = this.bConfiguration; 195 return desc; 196 } 197 } 198}