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