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