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