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