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.regionserver;
019
020import java.io.IOException;
021import java.util.List;
022import java.util.stream.Collectors;
023import org.apache.hadoop.hbase.NotServingRegionException;
024import org.apache.hadoop.hbase.client.RegionInfo;
025import org.apache.hadoop.hbase.executor.EventType;
026import org.apache.hadoop.hbase.procedure2.BaseRSProcedureCallable;
027import org.apache.yetus.audience.InterfaceAudience;
028import org.slf4j.Logger;
029import org.slf4j.LoggerFactory;
030
031import org.apache.hbase.thirdparty.com.google.protobuf.ByteString;
032
033import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
034import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos.FlushRegionParameter;
035
036@InterfaceAudience.Private
037public class FlushRegionCallable extends BaseRSProcedureCallable {
038
039  private static final Logger LOG = LoggerFactory.getLogger(FlushRegionCallable.class);
040
041  private RegionInfo regionInfo;
042
043  private List<byte[]> columnFamilies;
044
045  @Override
046  protected void doCall() throws Exception {
047    HRegion region = rs.getRegion(regionInfo.getEncodedName());
048    if (region == null) {
049      throw new NotServingRegionException("region=" + regionInfo.getRegionNameAsString());
050    }
051    LOG.debug("Starting region operation on {}", region);
052    region.startRegionOperation();
053    try {
054      HRegion.FlushResult res;
055      if (columnFamilies == null) {
056        res = region.flush(true);
057      } else {
058        res = region.flushcache(columnFamilies, false, FlushLifeCycleTracker.DUMMY);
059      }
060      if (res.getResult() == HRegion.FlushResult.Result.CANNOT_FLUSH) {
061        throw new IOException("Unable to complete flush " + regionInfo);
062      }
063    } finally {
064      LOG.debug("Closing region operation on {}", region);
065      region.closeRegionOperation();
066    }
067  }
068
069  @Override
070  protected void initParameter(byte[] parameter) throws Exception {
071    FlushRegionParameter param = FlushRegionParameter.parseFrom(parameter);
072    this.regionInfo = ProtobufUtil.toRegionInfo(param.getRegion());
073    if (param.getColumnFamilyCount() > 0) {
074      this.columnFamilies = param.getColumnFamilyList().stream().filter(cf -> !cf.isEmpty())
075        .map(ByteString::toByteArray).collect(Collectors.toList());
076    }
077  }
078
079  @Override
080  public EventType getEventType() {
081    return EventType.RS_FLUSH_REGIONS;
082  }
083}