View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase;
20  
21  import org.apache.hadoop.hbase.classification.InterfaceAudience;
22  import org.apache.hadoop.hbase.classification.InterfaceStability;
23  import org.apache.hadoop.hbase.util.Bytes;
24  
25  import java.util.Collections;
26  import java.util.Comparator;
27  import java.util.HashSet;
28  import java.util.Map;
29  import java.util.Set;
30  import java.util.TreeMap;
31  import java.util.TreeSet;
32  
33  /**
34   * Namespace POJO class. Used to represent and define namespaces.
35   *
36   * Descriptors will be persisted in an hbase table.
37   * This works since namespaces are essentially metadata of a group of tables
38   * as opposed to a more tangible container.
39   */
40  @InterfaceAudience.Public
41  @InterfaceStability.Evolving
42  public class NamespaceDescriptor {
43  
44    /** System namespace name. */
45    public static final byte [] SYSTEM_NAMESPACE_NAME = Bytes.toBytes("hbase");
46    public static final String SYSTEM_NAMESPACE_NAME_STR =
47        Bytes.toString(SYSTEM_NAMESPACE_NAME);
48    /** Default namespace name. */
49    public static final byte [] DEFAULT_NAMESPACE_NAME = Bytes.toBytes("default");
50    public static final String DEFAULT_NAMESPACE_NAME_STR =
51        Bytes.toString(DEFAULT_NAMESPACE_NAME);
52  
53    public static final NamespaceDescriptor DEFAULT_NAMESPACE = NamespaceDescriptor.create(
54      DEFAULT_NAMESPACE_NAME_STR).build();
55    public static final NamespaceDescriptor SYSTEM_NAMESPACE = NamespaceDescriptor.create(
56      SYSTEM_NAMESPACE_NAME_STR).build();
57  
58    public final static Set<String> RESERVED_NAMESPACES;
59    static {
60      Set<String> set = new HashSet<String>();
61      set.add(NamespaceDescriptor.DEFAULT_NAMESPACE_NAME_STR);
62      set.add(NamespaceDescriptor.SYSTEM_NAMESPACE_NAME_STR);
63      RESERVED_NAMESPACES = Collections.unmodifiableSet(set);
64    }
65    public final static Set<byte[]> RESERVED_NAMESPACES_BYTES;
66    static {
67      Set<byte[]> set = new TreeSet<byte[]>(Bytes.BYTES_RAWCOMPARATOR);
68      for(String name: RESERVED_NAMESPACES) {
69        set.add(Bytes.toBytes(name));
70      }
71      RESERVED_NAMESPACES_BYTES = Collections.unmodifiableSet(set);
72    }
73  
74    private String name;
75    private Map<String, String> configuration;
76  
77    public static final Comparator<NamespaceDescriptor> NAMESPACE_DESCRIPTOR_COMPARATOR =
78        new Comparator<NamespaceDescriptor>() {
79      @Override
80      public int compare(NamespaceDescriptor namespaceDescriptor,
81          NamespaceDescriptor namespaceDescriptor2) {
82        return namespaceDescriptor.getName().compareTo(namespaceDescriptor2.getName());
83      }
84    };
85  
86    private NamespaceDescriptor() {
87    }
88  
89    private NamespaceDescriptor(String name) {
90      this.name = name;
91    }
92  
93    public String getName() {
94      return name;
95    }
96  
97    /**
98     * Getter for accessing the configuration value by key
99     */
100   public String getConfigurationValue(String key) {
101     return configuration.get(key);
102   }
103 
104   /**
105    * Getter for fetching an unmodifiable {@link #configuration} map.
106    */
107   public Map<String, String> getConfiguration() {
108     // shallow pointer copy
109     return Collections.unmodifiableMap(configuration);
110   }
111 
112   /**
113    * Setter for storing a configuration setting in {@link #configuration} map.
114    * @param key Config key. Same as XML config key e.g. hbase.something.or.other.
115    * @param value String value. If null, removes the setting.
116    */
117   public void setConfiguration(String key, String value) {
118     if (value == null) {
119       removeConfiguration(key);
120     } else {
121       configuration.put(key, value);
122     }
123   }
124 
125   /**
126    * Remove a config setting represented by the key from the {@link #configuration} map
127    */
128   public void removeConfiguration(final String key) {
129     configuration.remove(key);
130   }
131 
132   @Override
133   public String toString() {
134     StringBuilder s = new StringBuilder();
135     s.append('{');
136     s.append(HConstants.NAME);
137     s.append(" => '");
138     s.append(name);
139     s.append("'");
140     for (Map.Entry<String, String> e : configuration.entrySet()) {
141       String key = e.getKey();
142       String value = e.getValue();
143       if (key == null) {
144         continue;
145       }
146       s.append(", ");
147       s.append(key);
148       s.append(" => '");
149       s.append(value);
150       s.append("'");
151     }
152     s.append('}');
153     return s.toString();
154   }
155 
156   public static Builder create(String name) {
157     return new Builder(name);
158   }
159 
160   public static Builder create(NamespaceDescriptor ns) {
161     return new Builder(ns);
162   }
163 
164   @InterfaceAudience.Public
165   @InterfaceStability.Evolving
166   public static class Builder {
167     private String bName;
168     private Map<String, String> bConfiguration = new TreeMap<String, String>();
169 
170     private Builder(NamespaceDescriptor ns) {
171       this.bName = ns.name;
172       this.bConfiguration = ns.configuration;
173     }
174 
175     private Builder(String name) {
176       this.bName = name;
177     }
178 
179     public Builder addConfiguration(Map<String, String> configuration) {
180       this.bConfiguration.putAll(configuration);
181       return this;
182     }
183 
184     public Builder addConfiguration(String key, String value) {
185       this.bConfiguration.put(key, value);
186       return this;
187     }
188 
189     public Builder removeConfiguration(String key) {
190       this.bConfiguration.remove(key);
191       return this;
192     }
193 
194     public NamespaceDescriptor build() {
195       if (this.bName == null){
196          throw new IllegalArgumentException("A name has to be specified in a namespace.");
197       }
198 
199       NamespaceDescriptor desc = new NamespaceDescriptor(this.bName);
200       desc.configuration = this.bConfiguration;
201       return desc;
202     }
203   }
204 }