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.io.IOException;
021import java.util.Collection;
022import java.util.Collections;
023import java.util.Map;
024import java.util.Optional;
025import java.util.Set;
026import java.util.stream.Collectors;
027import java.util.stream.Stream;
028import org.apache.hadoop.fs.Path;
029import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
030import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder.ModifyableColumnFamilyDescriptor;
031import org.apache.hadoop.hbase.client.CoprocessorDescriptor;
032import org.apache.hadoop.hbase.client.CoprocessorDescriptorBuilder;
033import org.apache.hadoop.hbase.client.Durability;
034import org.apache.hadoop.hbase.client.TableDescriptor;
035import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
036import org.apache.hadoop.hbase.client.TableDescriptorBuilder.ModifyableTableDescriptor;
037import org.apache.hadoop.hbase.exceptions.DeserializationException;
038import org.apache.hadoop.hbase.exceptions.HBaseException;
039import org.apache.hadoop.hbase.security.User;
040import org.apache.hadoop.hbase.util.Bytes;
041import org.apache.yetus.audience.InterfaceAudience;
042
043/**
044 * HTableDescriptor contains the details about an HBase table such as the descriptors of all the
045 * column families, is the table a catalog table, <code> hbase:meta </code>, if the table is read
046 * only, the maximum size of the memstore, when the region split should occur, coprocessors
047 * associated with it etc...
048 * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use
049 *             {@link TableDescriptorBuilder} to build {@link HTableDescriptor}.
050 */
051@Deprecated
052@InterfaceAudience.Public
053public class HTableDescriptor implements TableDescriptor, Comparable<HTableDescriptor> {
054  public static final String SPLIT_POLICY = TableDescriptorBuilder.SPLIT_POLICY;
055  public static final String MAX_FILESIZE = TableDescriptorBuilder.MAX_FILESIZE;
056  public static final String OWNER = TableDescriptorBuilder.OWNER;
057  public static final Bytes OWNER_KEY = TableDescriptorBuilder.OWNER_KEY;
058  public static final String READONLY = TableDescriptorBuilder.READONLY;
059  public static final String COMPACTION_ENABLED = TableDescriptorBuilder.COMPACTION_ENABLED;
060  public static final String SPLIT_ENABLED = TableDescriptorBuilder.SPLIT_ENABLED;
061  public static final String MERGE_ENABLED = TableDescriptorBuilder.MERGE_ENABLED;
062  public static final String MEMSTORE_FLUSHSIZE = TableDescriptorBuilder.MEMSTORE_FLUSHSIZE;
063  public static final String FLUSH_POLICY = TableDescriptorBuilder.FLUSH_POLICY;
064  public static final String IS_ROOT = "IS_ROOT";
065  public static final String IS_META = TableDescriptorBuilder.IS_META;
066  public static final String DURABILITY = TableDescriptorBuilder.DURABILITY;
067  public static final String REGION_REPLICATION = TableDescriptorBuilder.REGION_REPLICATION;
068  public static final String REGION_MEMSTORE_REPLICATION =
069    TableDescriptorBuilder.REGION_MEMSTORE_REPLICATION;
070  public static final String NORMALIZATION_ENABLED = TableDescriptorBuilder.NORMALIZATION_ENABLED;
071  public static final boolean DEFAULT_NORMALIZATION_ENABLED =
072    TableDescriptorBuilder.DEFAULT_NORMALIZATION_ENABLED;
073  public static final String NORMALIZER_TARGET_REGION_COUNT =
074    TableDescriptorBuilder.NORMALIZER_TARGET_REGION_COUNT;
075  public static final String NORMALIZER_TARGET_REGION_SIZE =
076    TableDescriptorBuilder.NORMALIZER_TARGET_REGION_SIZE;
077  public static final String NORMALIZER_TARGET_REGION_SIZE_MB =
078    TableDescriptorBuilder.NORMALIZER_TARGET_REGION_SIZE_MB;
079  public static final String PRIORITY = TableDescriptorBuilder.PRIORITY;
080  public static final boolean DEFAULT_READONLY = TableDescriptorBuilder.DEFAULT_READONLY;
081  public static final boolean DEFAULT_COMPACTION_ENABLED =
082    TableDescriptorBuilder.DEFAULT_COMPACTION_ENABLED;
083  public static final long DEFAULT_MEMSTORE_FLUSH_SIZE =
084    TableDescriptorBuilder.DEFAULT_MEMSTORE_FLUSH_SIZE;
085  public static final int DEFAULT_REGION_REPLICATION =
086    TableDescriptorBuilder.DEFAULT_REGION_REPLICATION;
087  public static final boolean DEFAULT_REGION_MEMSTORE_REPLICATION =
088    TableDescriptorBuilder.DEFAULT_REGION_MEMSTORE_REPLICATION;
089  protected final ModifyableTableDescriptor delegatee;
090
091  /**
092   * Construct a table descriptor specifying a TableName object
093   * @param name Table name.
094   * @see <a href="https://issues.apache.org/jira/browse/HBASE-174">HADOOP-1581 HBASE: (HBASE-174)
095   *      Un-openable tablename bug</a>
096   */
097  public HTableDescriptor(final TableName name) {
098    this(new ModifyableTableDescriptor(name));
099  }
100
101  /**
102   * Construct a table descriptor by cloning the descriptor passed as a parameter.
103   * <p>
104   * Makes a deep copy of the supplied descriptor. Can make a modifiable descriptor from an
105   * ImmutableHTableDescriptor.
106   * @param desc The descriptor.
107   */
108  public HTableDescriptor(final HTableDescriptor desc) {
109    this(desc, true);
110  }
111
112  protected HTableDescriptor(final HTableDescriptor desc, boolean deepClone) {
113    this(deepClone ? new ModifyableTableDescriptor(desc.getTableName(), desc) : desc.delegatee);
114  }
115
116  public HTableDescriptor(final TableDescriptor desc) {
117    this(new ModifyableTableDescriptor(desc.getTableName(), desc));
118  }
119
120  /**
121   * Construct a table descriptor by cloning the descriptor passed as a parameter but using a
122   * different table name.
123   * <p>
124   * Makes a deep copy of the supplied descriptor. Can make a modifiable descriptor from an
125   * ImmutableHTableDescriptor.
126   * @param name Table name.
127   * @param desc The descriptor.
128   */
129  public HTableDescriptor(final TableName name, final HTableDescriptor desc) {
130    this(new ModifyableTableDescriptor(name, desc));
131  }
132
133  protected HTableDescriptor(ModifyableTableDescriptor delegatee) {
134    this.delegatee = delegatee;
135  }
136
137  /**
138   * This is vestigial API. It will be removed in 3.0.
139   * @return always return the false
140   */
141  public boolean isRootRegion() {
142    return false;
143  }
144
145  /**
146   * Checks if this table is <code> hbase:meta </code> region.
147   * @return true if this table is <code> hbase:meta </code> region
148   */
149  @Override
150  public boolean isMetaRegion() {
151    return delegatee.isMetaRegion();
152  }
153
154  /**
155   * Checks if the table is a <code>hbase:meta</code> table
156   * @return true if table is <code> hbase:meta </code> region.
157   */
158  @Override
159  public boolean isMetaTable() {
160    return delegatee.isMetaTable();
161  }
162
163  /** Returns Getter for fetching an unmodifiable map. */
164  @Override
165  public Map<Bytes, Bytes> getValues() {
166    return delegatee.getValues();
167  }
168
169  /**
170   * Setter for storing metadata as a (key, value) pair in map
171   * @param key   The key.
172   * @param value The value. If null, removes the setting.
173   */
174  public HTableDescriptor setValue(byte[] key, byte[] value) {
175    getDelegateeForModification().setValue(key, value);
176    return this;
177  }
178
179  /*
180   * Setter for storing metadata as a (key, value) pair in map
181   * @param key The key.
182   * @param value The value. If null, removes the setting.
183   */
184  public HTableDescriptor setValue(final Bytes key, final Bytes value) {
185    getDelegateeForModification().setValue(key, value);
186    return this;
187  }
188
189  /**
190   * Setter for storing metadata as a (key, value) pair in map
191   * @param key   The key.
192   * @param value The value. If null, removes the setting.
193   */
194  public HTableDescriptor setValue(String key, String value) {
195    getDelegateeForModification().setValue(key, value);
196    return this;
197  }
198
199  /**
200   * Remove metadata represented by the key from the map
201   * @param key Key whose key and value we're to remove from HTableDescriptor parameters.
202   */
203  public void remove(final String key) {
204    getDelegateeForModification().removeValue(Bytes.toBytes(key));
205  }
206
207  /**
208   * Remove metadata represented by the key from the map
209   * @param key Key whose key and value we're to remove from HTableDescriptor parameters.
210   */
211  public void remove(Bytes key) {
212    getDelegateeForModification().removeValue(key);
213  }
214
215  /**
216   * Remove metadata represented by the key from the map
217   * @param key Key whose key and value we're to remove from HTableDescriptor parameters.
218   */
219  public void remove(final byte[] key) {
220    getDelegateeForModification().removeValue(key);
221  }
222
223  /**
224   * Check if the readOnly flag of the table is set. If the readOnly flag is set then the contents
225   * of the table can only be read from but not modified.
226   * @return true if all columns in the table should be read only
227   */
228  @Override
229  public boolean isReadOnly() {
230    return delegatee.isReadOnly();
231  }
232
233  /**
234   * Setting the table as read only sets all the columns in the table as read only. By default all
235   * tables are modifiable, but if the readOnly flag is set to true then the contents of the table
236   * can only be read but not modified.
237   * @param readOnly True if all of the columns in the table should be read only.
238   */
239  public HTableDescriptor setReadOnly(final boolean readOnly) {
240    getDelegateeForModification().setReadOnly(readOnly);
241    return this;
242  }
243
244  /**
245   * Check if the compaction enable flag of the table is true. If flag is false then no minor/major
246   * compactions will be done in real.
247   * @return true if table compaction enabled
248   */
249  @Override
250  public boolean isCompactionEnabled() {
251    return delegatee.isCompactionEnabled();
252  }
253
254  /**
255   * Setting the table compaction enable flag.
256   * @param isEnable True if enable compaction.
257   */
258  public HTableDescriptor setCompactionEnabled(final boolean isEnable) {
259    getDelegateeForModification().setCompactionEnabled(isEnable);
260    return this;
261  }
262
263  /**
264   * Check if the region split enable flag of the table is true. If flag is false then no split will
265   * be done.
266   * @return true if table region split enabled
267   */
268  @Override
269  public boolean isSplitEnabled() {
270    return delegatee.isSplitEnabled();
271  }
272
273  /**
274   * Setting the table region split enable flag.
275   * @param isEnable True if enable split.
276   */
277  public HTableDescriptor setSplitEnabled(final boolean isEnable) {
278    getDelegateeForModification().setSplitEnabled(isEnable);
279    return this;
280  }
281
282  /**
283   * Check if the region merge enable flag of the table is true. If flag is false then no merge will
284   * be done.
285   * @return true if table region merge enabled
286   */
287  @Override
288  public boolean isMergeEnabled() {
289    return delegatee.isMergeEnabled();
290  }
291
292  /**
293   * Setting the table region merge enable flag.
294   * @param isEnable True if enable merge.
295   */
296  public HTableDescriptor setMergeEnabled(final boolean isEnable) {
297    getDelegateeForModification().setMergeEnabled(isEnable);
298    return this;
299  }
300
301  /**
302   * Check if normalization enable flag of the table is true. If flag is false then no region
303   * normalizer won't attempt to normalize this table.
304   * @return true if region normalization is enabled for this table
305   */
306  @Override
307  public boolean isNormalizationEnabled() {
308    return delegatee.isNormalizationEnabled();
309  }
310
311  /**
312   * Setting the table normalization enable flag.
313   * @param isEnable True if enable normalization.
314   */
315  public HTableDescriptor setNormalizationEnabled(final boolean isEnable) {
316    getDelegateeForModification().setNormalizationEnabled(isEnable);
317    return this;
318  }
319
320  @Override
321  public int getNormalizerTargetRegionCount() {
322    return getDelegateeForModification().getNormalizerTargetRegionCount();
323  }
324
325  public HTableDescriptor setNormalizerTargetRegionCount(final int regionCount) {
326    getDelegateeForModification().setNormalizerTargetRegionCount(regionCount);
327    return this;
328  }
329
330  @Override
331  public long getNormalizerTargetRegionSize() {
332    return getDelegateeForModification().getNormalizerTargetRegionSize();
333  }
334
335  public HTableDescriptor setNormalizerTargetRegionSize(final long regionSize) {
336    getDelegateeForModification().setNormalizerTargetRegionSize(regionSize);
337    return this;
338  }
339
340  /**
341   * Sets the {@link Durability} setting for the table. This defaults to Durability.USE_DEFAULT.
342   * @param durability enum value
343   */
344  public HTableDescriptor setDurability(Durability durability) {
345    getDelegateeForModification().setDurability(durability);
346    return this;
347  }
348
349  /**
350   * Returns the durability setting for the table.
351   * @return durability setting for the table.
352   */
353  @Override
354  public Durability getDurability() {
355    return delegatee.getDurability();
356  }
357
358  /**
359   * Get the name of the table n
360   */
361  @Override
362  public TableName getTableName() {
363    return delegatee.getTableName();
364  }
365
366  /**
367   * Get the name of the table as a String
368   * @return name of table as a String
369   */
370  public String getNameAsString() {
371    return delegatee.getTableName().getNameAsString();
372  }
373
374  /**
375   * This sets the class associated with the region split policy which determines when a region
376   * split should occur. The class used by default is defined in
377   * org.apache.hadoop.hbase.regionserver.RegionSplitPolicy
378   * @param clazz the class name
379   */
380  public HTableDescriptor setRegionSplitPolicyClassName(String clazz) {
381    getDelegateeForModification().setRegionSplitPolicyClassName(clazz);
382    return this;
383  }
384
385  /**
386   * This gets the class associated with the region split policy which determines when a region
387   * split should occur. The class used by default is defined in
388   * org.apache.hadoop.hbase.regionserver.RegionSplitPolicy
389   * @return the class name of the region split policy for this table. If this returns null, the
390   *         default split policy is used.
391   */
392  @Override
393  public String getRegionSplitPolicyClassName() {
394    return delegatee.getRegionSplitPolicyClassName();
395  }
396
397  /**
398   * Returns the maximum size upto which a region can grow to after which a region split is
399   * triggered. The region size is represented by the size of the biggest store file in that region.
400   * @return max hregion size for table, -1 if not set.
401   * @see #setMaxFileSize(long)
402   */
403  @Override
404  public long getMaxFileSize() {
405    return delegatee.getMaxFileSize();
406  }
407
408  /**
409   * Sets the maximum size upto which a region can grow to after which a region split is triggered.
410   * The region size is represented by the size of the biggest store file in that region, i.e. If
411   * the biggest store file grows beyond the maxFileSize, then the region split is triggered. This
412   * defaults to a value of 256 MB.
413   * <p>
414   * This is not an absolute value and might vary. Assume that a single row exceeds the maxFileSize
415   * then the storeFileSize will be greater than maxFileSize since a single row cannot be split
416   * across multiple regions
417   * </p>
418   * @param maxFileSize The maximum file size that a store file can grow to before a split is
419   *                    triggered.
420   */
421  public HTableDescriptor setMaxFileSize(long maxFileSize) {
422    getDelegateeForModification().setMaxFileSize(maxFileSize);
423    return this;
424  }
425
426  public HTableDescriptor setMaxFileSize(String maxFileSize) throws HBaseException {
427    getDelegateeForModification().setMaxFileSize(maxFileSize);
428    return this;
429  }
430
431  /**
432   * Returns the size of the memstore after which a flush to filesystem is triggered.
433   * @return memory cache flush size for each hregion, -1 if not set.
434   * @see #setMemStoreFlushSize(long)
435   */
436  @Override
437  public long getMemStoreFlushSize() {
438    return delegatee.getMemStoreFlushSize();
439  }
440
441  /**
442   * Represents the maximum size of the memstore after which the contents of the memstore are
443   * flushed to the filesystem. This defaults to a size of 64 MB.
444   * @param memstoreFlushSize memory cache flush size for each hregion
445   */
446  public HTableDescriptor setMemStoreFlushSize(long memstoreFlushSize) {
447    getDelegateeForModification().setMemStoreFlushSize(memstoreFlushSize);
448    return this;
449  }
450
451  public HTableDescriptor setMemStoreFlushSize(String memStoreFlushSize) throws HBaseException {
452    getDelegateeForModification().setMemStoreFlushSize(memStoreFlushSize);
453    return this;
454  }
455
456  /**
457   * This sets the class associated with the flush policy which determines determines the stores
458   * need to be flushed when flushing a region. The class used by default is defined in
459   * org.apache.hadoop.hbase.regionserver.FlushPolicy.
460   * @param clazz the class name
461   */
462  public HTableDescriptor setFlushPolicyClassName(String clazz) {
463    getDelegateeForModification().setFlushPolicyClassName(clazz);
464    return this;
465  }
466
467  /**
468   * This gets the class associated with the flush policy which determines the stores need to be
469   * flushed when flushing a region. The class used by default is defined in
470   * org.apache.hadoop.hbase.regionserver.FlushPolicy.
471   * @return the class name of the flush policy for this table. If this returns null, the default
472   *         flush policy is used.
473   */
474  @Override
475  public String getFlushPolicyClassName() {
476    return delegatee.getFlushPolicyClassName();
477  }
478
479  /**
480   * Adds a column family. For the updating purpose please use
481   * {@link #modifyFamily(HColumnDescriptor)} instead.
482   * @param family HColumnDescriptor of family to add.
483   */
484  public HTableDescriptor addFamily(final HColumnDescriptor family) {
485    getDelegateeForModification().setColumnFamily(family);
486    return this;
487  }
488
489  /**
490   * Modifies the existing column family.
491   * @param family HColumnDescriptor of family to update
492   * @return this (for chained invocation)
493   */
494  public HTableDescriptor modifyFamily(final HColumnDescriptor family) {
495    getDelegateeForModification().modifyColumnFamily(family);
496    return this;
497  }
498
499  /**
500   * Checks to see if this table contains the given column family
501   * @param familyName Family name or column name.
502   * @return true if the table contains the specified family name
503   */
504  public boolean hasFamily(final byte[] familyName) {
505    return delegatee.hasColumnFamily(familyName);
506  }
507
508  /**
509   * @return Name of this table and then a map of all of the column family descriptors.
510   * @see #getNameAsString()
511   */
512  @Override
513  public String toString() {
514    return delegatee.toString();
515  }
516
517  /**
518   * @return Name of this table and then a map of all of the column family descriptors (with only
519   *         the non-default column family attributes)
520   */
521  @Override
522  public String toStringCustomizedValues() {
523    return delegatee.toStringCustomizedValues();
524  }
525
526  /** Returns map of all table attributes formatted into string. */
527  public String toStringTableAttributes() {
528    return delegatee.toStringTableAttributes();
529  }
530
531  /**
532   * Compare the contents of the descriptor with another one passed as a parameter. Checks if the
533   * obj passed is an instance of HTableDescriptor, if yes then the contents of the descriptors are
534   * compared.
535   * @return true if the contents of the the two descriptors exactly match
536   * @see java.lang.Object#equals(java.lang.Object)
537   */
538  @Override
539  public boolean equals(Object obj) {
540    if (this == obj) {
541      return true;
542    }
543    if (obj instanceof HTableDescriptor) {
544      return delegatee.equals(((HTableDescriptor) obj).delegatee);
545    }
546    return false;
547  }
548
549  /**
550   * @see java.lang.Object#hashCode()
551   */
552  @Override
553  public int hashCode() {
554    return delegatee.hashCode();
555  }
556
557  // Comparable
558
559  /**
560   * Compares the descriptor with another descriptor which is passed as a parameter. This compares
561   * the content of the two descriptors and not the reference.
562   * @return 0 if the contents of the descriptors are exactly matching, 1 if there is a mismatch in
563   *         the contents
564   */
565  @Override
566  public int compareTo(final HTableDescriptor other) {
567    return TableDescriptor.COMPARATOR.compare(this, other);
568  }
569
570  /**
571   * Returns an unmodifiable collection of all the {@link HColumnDescriptor} of all the column
572   * families of the table.
573   * @deprecated since 2.0.0 and will be removed in 3.0.0. Use {@link #getColumnFamilies()} instead.
574   * @return Immutable collection of {@link HColumnDescriptor} of all the column families.
575   * @see #getColumnFamilies()
576   * @see <a href="https://issues.apache.org/jira/browse/HBASE-18008">HBASE-18008</a>
577   */
578  @Deprecated
579  public Collection<HColumnDescriptor> getFamilies() {
580    return Stream.of(delegatee.getColumnFamilies()).map(this::toHColumnDescriptor)
581      .collect(Collectors.toList());
582  }
583
584  /**
585   * Returns the configured replicas per region
586   */
587  @Override
588  public int getRegionReplication() {
589    return delegatee.getRegionReplication();
590  }
591
592  /**
593   * Sets the number of replicas per region.
594   * @param regionReplication the replication factor per region
595   */
596  public HTableDescriptor setRegionReplication(int regionReplication) {
597    getDelegateeForModification().setRegionReplication(regionReplication);
598    return this;
599  }
600
601  /**
602   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use
603   *             {@link #hasRegionMemStoreReplication()} instead
604   */
605  @Deprecated
606  public boolean hasRegionMemstoreReplication() {
607    return hasRegionMemStoreReplication();
608  }
609
610  /** Returns true if the read-replicas memstore replication is enabled. */
611  @Override
612  public boolean hasRegionMemStoreReplication() {
613    return delegatee.hasRegionMemStoreReplication();
614  }
615
616  /**
617   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use
618   *             {@link #setRegionMemStoreReplication(boolean)} instead
619   */
620  @Deprecated
621  public HTableDescriptor setRegionMemstoreReplication(boolean memstoreReplication) {
622    return setRegionMemStoreReplication(memstoreReplication);
623  }
624
625  /**
626   * Enable or Disable the memstore replication from the primary region to the replicas. The
627   * replication will be used only for meta operations (e.g. flush, compaction, ...)
628   * @param memstoreReplication true if the new data written to the primary region should be
629   *                            replicated. false if the secondaries can tollerate to have new data
630   *                            only when the primary flushes the memstore.
631   */
632  public HTableDescriptor setRegionMemStoreReplication(boolean memstoreReplication) {
633    getDelegateeForModification().setRegionMemStoreReplication(memstoreReplication);
634    return this;
635  }
636
637  public HTableDescriptor setPriority(int priority) {
638    getDelegateeForModification().setPriority(priority);
639    return this;
640  }
641
642  @Override
643  public int getPriority() {
644    return delegatee.getPriority();
645  }
646
647  /**
648   * Returns all the column family names of the current table. The map of HTableDescriptor contains
649   * mapping of family name to HColumnDescriptors. This returns all the keys of the family map which
650   * represents the column family names of the table.
651   * @return Immutable sorted set of the keys of the families.
652   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0
653   *             (<a href="https://issues.apache.org/jira/browse/HBASE-18008">HBASE-18008</a>). Use
654   *             {@link #getColumnFamilyNames()}.
655   */
656  @Deprecated
657  public Set<byte[]> getFamiliesKeys() {
658    return delegatee.getColumnFamilyNames();
659  }
660
661  /**
662   * Returns the count of the column families of the table.
663   * @return Count of column families of the table
664   */
665  @Override
666  public int getColumnFamilyCount() {
667    return delegatee.getColumnFamilyCount();
668  }
669
670  /**
671   * Returns an array all the {@link HColumnDescriptor} of the column families of the table.
672   * @return Array of all the HColumnDescriptors of the current table
673   * @deprecated since 2.0.0 and will be removed in 3.0.0.
674   * @see #getFamilies()
675   * @see <a href="https://issues.apache.org/jira/browse/HBASE-18008">HBASE-18008</a>
676   */
677  @Deprecated
678  @Override
679  public HColumnDescriptor[] getColumnFamilies() {
680    return Stream.of(delegatee.getColumnFamilies()).map(this::toHColumnDescriptor)
681      .toArray(size -> new HColumnDescriptor[size]);
682  }
683
684  /**
685   * Returns the HColumnDescriptor for a specific column family with name as specified by the
686   * parameter column.
687   * @param column Column family name
688   * @return Column descriptor for the passed family name or the family on passed in column.
689   * @deprecated since 2.0.0 and will be removed in 3.0.0. Use {@link #getColumnFamily(byte[])}
690   *             instead.
691   * @see #getColumnFamily(byte[])
692   * @see <a href="https://issues.apache.org/jira/browse/HBASE-18008">HBASE-18008</a>
693   */
694  @Deprecated
695  public HColumnDescriptor getFamily(final byte[] column) {
696    return toHColumnDescriptor(delegatee.getColumnFamily(column));
697  }
698
699  /**
700   * Removes the HColumnDescriptor with name specified by the parameter column from the table
701   * descriptor
702   * @param column Name of the column family to be removed.
703   * @return Column descriptor for the passed family name or the family on passed in column.
704   */
705  public HColumnDescriptor removeFamily(final byte[] column) {
706    return toHColumnDescriptor(getDelegateeForModification().removeColumnFamily(column));
707  }
708
709  /**
710   * Return a HColumnDescriptor for user to keep the compatibility as much as possible.
711   * @param desc read-only ColumnFamilyDescriptor
712   * @return The older implementation of ColumnFamilyDescriptor
713   */
714  protected HColumnDescriptor toHColumnDescriptor(ColumnFamilyDescriptor desc) {
715    if (desc == null) {
716      return null;
717    } else if (desc instanceof ModifyableColumnFamilyDescriptor) {
718      return new HColumnDescriptor((ModifyableColumnFamilyDescriptor) desc);
719    } else if (desc instanceof HColumnDescriptor) {
720      return (HColumnDescriptor) desc;
721    } else {
722      return new HColumnDescriptor(new ModifyableColumnFamilyDescriptor(desc));
723    }
724  }
725
726  /**
727   * Add a table coprocessor to this table. The coprocessor type must be
728   * org.apache.hadoop.hbase.coprocessor.RegionCoprocessor. It won't check if the class can be
729   * loaded or not. Whether a coprocessor is loadable or not will be determined when a region is
730   * opened.
731   * @param className Full class name. n
732   */
733  public HTableDescriptor addCoprocessor(String className) throws IOException {
734    getDelegateeForModification().setCoprocessor(className);
735    return this;
736  }
737
738  /**
739   * Add a table coprocessor to this table. The coprocessor type must be
740   * org.apache.hadoop.hbase.coprocessor.RegionCoprocessor. It won't check if the class can be
741   * loaded or not. Whether a coprocessor is loadable or not will be determined when a region is
742   * opened.
743   * @param jarFilePath Path of the jar file. If it's null, the class will be loaded from default
744   *                    classloader.
745   * @param className   Full class name.
746   * @param priority    Priority
747   * @param kvs         Arbitrary key-value parameter pairs passed into the coprocessor. n
748   */
749  public HTableDescriptor addCoprocessor(String className, Path jarFilePath, int priority,
750    final Map<String, String> kvs) throws IOException {
751    getDelegateeForModification().setCoprocessor(CoprocessorDescriptorBuilder.newBuilder(className)
752      .setJarPath(jarFilePath == null ? null : jarFilePath.toString()).setPriority(priority)
753      .setProperties(kvs == null ? Collections.emptyMap() : kvs).build());
754    return this;
755  }
756
757  /**
758   * Add a table coprocessor to this table. The coprocessor type must be
759   * org.apache.hadoop.hbase.coprocessor.RegionCoprocessor. It won't check if the class can be
760   * loaded or not. Whether a coprocessor is loadable or not will be determined when a region is
761   * opened.
762   * @param specStr The Coprocessor specification all in in one String formatted so matches
763   *                {@link HConstants#CP_HTD_ATTR_VALUE_PATTERN} n
764   */
765  public HTableDescriptor addCoprocessorWithSpec(final String specStr) throws IOException {
766    getDelegateeForModification().setCoprocessorWithSpec(specStr);
767    return this;
768  }
769
770  /**
771   * Check if the table has an attached co-processor represented by the name className
772   * @param classNameToMatch - Class name of the co-processor
773   * @return true of the table has a co-processor className
774   */
775  @Override
776  public boolean hasCoprocessor(String classNameToMatch) {
777    return delegatee.hasCoprocessor(classNameToMatch);
778  }
779
780  @Override
781  public Collection<CoprocessorDescriptor> getCoprocessorDescriptors() {
782    return delegatee.getCoprocessorDescriptors();
783  }
784
785  /**
786   * Remove a coprocessor from those set on the table
787   * @param className Class name of the co-processor
788   */
789  public void removeCoprocessor(String className) {
790    getDelegateeForModification().removeCoprocessor(className);
791  }
792
793  public final static String NAMESPACE_FAMILY_INFO = TableDescriptorBuilder.NAMESPACE_FAMILY_INFO;
794  public final static byte[] NAMESPACE_FAMILY_INFO_BYTES =
795    TableDescriptorBuilder.NAMESPACE_FAMILY_INFO_BYTES;
796  public final static byte[] NAMESPACE_COL_DESC_BYTES =
797    TableDescriptorBuilder.NAMESPACE_COL_DESC_BYTES;
798
799  /** Table descriptor for namespace table */
800  public static final HTableDescriptor NAMESPACE_TABLEDESC =
801    new HTableDescriptor(TableDescriptorBuilder.NAMESPACE_TABLEDESC);
802
803  /**
804   * Set the table owner.
805   * @deprecated since 0.94.1
806   * @see <a href="https://issues.apache.org/jira/browse/HBASE-6188">HBASE-6188</a>
807   */
808  @Deprecated
809  public HTableDescriptor setOwner(User owner) {
810    getDelegateeForModification().setOwner(owner);
811    return this;
812  }
813
814  /**
815   * Set the table owner.
816   * @deprecated since 0.94.1
817   * @see <a href="https://issues.apache.org/jira/browse/HBASE-6188">HBASE-6188</a>
818   */
819  // used by admin.rb:alter(table_name,*args) to update owner.
820  @Deprecated
821  public HTableDescriptor setOwnerString(String ownerString) {
822    getDelegateeForModification().setOwnerString(ownerString);
823    return this;
824  }
825
826  /**
827   * Get the table owner.
828   * @deprecated since 0.94.1
829   * @see <a href="https://issues.apache.org/jira/browse/HBASE-6188">HBASE-6188</a>
830   */
831  @Override
832  @Deprecated
833  public String getOwnerString() {
834    return delegatee.getOwnerString();
835  }
836
837  /**
838   * Returns This instance serialized with pb with pb magic prefix
839   */
840  public byte[] toByteArray() {
841    return TableDescriptorBuilder.toByteArray(delegatee);
842  }
843
844  /**
845   * Parse the serialized representation of a {@link HTableDescriptor}
846   * @param bytes A pb serialized {@link HTableDescriptor} instance with pb magic prefix
847   * @return An instance of {@link HTableDescriptor} made from <code>bytes</code> nn * @see
848   *         #toByteArray()
849   */
850  public static HTableDescriptor parseFrom(final byte[] bytes)
851    throws DeserializationException, IOException {
852    TableDescriptor desc = TableDescriptorBuilder.parseFrom(bytes);
853    if (desc instanceof ModifyableTableDescriptor) {
854      return new HTableDescriptor((ModifyableTableDescriptor) desc);
855    } else {
856      return new HTableDescriptor(desc);
857    }
858  }
859
860  /**
861   * Getter for accessing the configuration value by key
862   */
863  public String getConfigurationValue(String key) {
864    return delegatee.getValue(key);
865  }
866
867  /**
868   * Getter for fetching an unmodifiable map.
869   */
870  public Map<String, String> getConfiguration() {
871    return delegatee.getValues().entrySet().stream().collect(Collectors.toMap(
872      e -> Bytes.toString(e.getKey().get(), e.getKey().getOffset(), e.getKey().getLength()),
873      e -> Bytes.toString(e.getValue().get(), e.getValue().getOffset(), e.getValue().getLength())));
874  }
875
876  /**
877   * Setter for storing a configuration setting in map.
878   * @param key   Config key. Same as XML config key e.g. hbase.something.or.other.
879   * @param value String value. If null, removes the setting.
880   */
881  public HTableDescriptor setConfiguration(String key, String value) {
882    getDelegateeForModification().setValue(key, value);
883    return this;
884  }
885
886  /**
887   * Remove a config setting represented by the key from the map
888   */
889  public void removeConfiguration(final String key) {
890    getDelegateeForModification().removeValue(Bytes.toBytes(key));
891  }
892
893  @Override
894  public Bytes getValue(Bytes key) {
895    return delegatee.getValue(key);
896  }
897
898  @Override
899  public String getValue(String key) {
900    return delegatee.getValue(key);
901  }
902
903  @Override
904  public byte[] getValue(byte[] key) {
905    return delegatee.getValue(key);
906  }
907
908  @Override
909  public Set<byte[]> getColumnFamilyNames() {
910    return delegatee.getColumnFamilyNames();
911  }
912
913  @Override
914  public boolean hasColumnFamily(byte[] name) {
915    return delegatee.hasColumnFamily(name);
916  }
917
918  @Override
919  public ColumnFamilyDescriptor getColumnFamily(byte[] name) {
920    return delegatee.getColumnFamily(name);
921  }
922
923  protected ModifyableTableDescriptor getDelegateeForModification() {
924    return delegatee;
925  }
926
927  @Override
928  public Optional<String> getRegionServerGroup() {
929    return delegatee.getRegionServerGroup();
930  }
931}