public static void createHFile(Configuration configuration, FileSystem fs, Path path,
    DataBlockEncoding encoding, byte[] family, byte[] qualifier, byte[] startKey, byte[] endKey,
    int numRows, boolean withTag) throws IOException {
    HFileContext meta = new HFileContextBuilder().withIncludesTags(withTag)
      .withDataBlockEncoding(encoding).withColumnFamily(family).build();
    HFile.Writer writer = HFile.getWriterFactory(configuration, new CacheConfig(configuration))
      .withPath(fs, path).withFileContext(meta).create();
    long now = EnvironmentEdgeManager.currentTime();
    try {
      // subtract 2 since iterateOnSplits doesn't include boundary keys
      for (byte[] key : Bytes.iterateOnSplits(startKey, endKey, numRows - 2)) {
        ExtendedCell kv = new KeyValue(key, family, qualifier, now, key);
        if (withTag) {
          // add a tag. Arbitrarily chose mob tag since we have a helper already.
          Tag tableNameTag = new ArrayBackedTag(TagType.MOB_TABLE_NAME_TAG_TYPE, key);
          kv = MobUtils.createMobRefCell(kv, key, tableNameTag);

          // verify that the kv has the tag.
          Optional<Tag> tag = PrivateCellUtil.getTag(kv, TagType.MOB_TABLE_NAME_TAG_TYPE);
          if (!tag.isPresent()) {
            throw new IllegalStateException("Tag didn't stick to KV " + kv.toString());
          }
        }
        writer.append(kv);
      }
    } finally {
      writer.appendFileInfo(BULKLOAD_TIME_KEY, Bytes.toBytes(EnvironmentEdgeManager.currentTime()));
      writer.close();
    }
  }
Create an HFile with the given number of rows between a given start key and end key @
family:qualifier. If withTag is true, we add the rowKey as the tag value for tagtype
MOB_TABLE_NAME_TAG_TYPE
hbase-server/src/test/java/org/apache/hadoop/hbase/util/HFileTestUtil.java