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 */
018
019package org.apache.hadoop.hbase.client;
020
021import java.io.IOException;
022
023import org.apache.hadoop.hbase.TableName;
024import org.apache.hadoop.hbase.ipc.HBaseRpcController;
025import org.apache.hadoop.hbase.ipc.RpcControllerFactory;
026import org.apache.hadoop.hbase.util.Bytes;
027import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
028import org.apache.yetus.audience.InterfaceAudience;
029import org.slf4j.Logger;
030import org.slf4j.LoggerFactory;
031import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter;
032import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.FlushRegionRequest;
033import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.FlushRegionResponse;
034
035/**
036 * A Callable for flushRegion() RPC.
037 */
038@InterfaceAudience.Private
039public class FlushRegionCallable extends RegionAdminServiceCallable<FlushRegionResponse> {
040  private static final Logger LOG = LoggerFactory.getLogger(FlushRegionCallable.class);
041  private final byte[] regionName;
042  private final boolean writeFlushWalMarker;
043  private boolean reload;
044
045  public FlushRegionCallable(ClusterConnection connection,
046      RpcControllerFactory rpcControllerFactory, TableName tableName, byte[] regionName,
047      byte[] regionStartKey, boolean writeFlushWalMarker) {
048    super(connection, rpcControllerFactory, tableName, regionStartKey);
049    this.regionName = regionName;
050    this.writeFlushWalMarker = writeFlushWalMarker;
051  }
052
053  public FlushRegionCallable(ClusterConnection connection,
054      RpcControllerFactory rpcControllerFactory, RegionInfo regionInfo,
055      boolean writeFlushWalMarker) {
056    this(connection, rpcControllerFactory, regionInfo.getTable(), regionInfo.getRegionName(),
057      regionInfo.getStartKey(), writeFlushWalMarker);
058  }
059
060  @Override
061  public void prepare(boolean reload) throws IOException {
062    super.prepare(reload);
063    this.reload = reload;
064  }
065
066  @Override
067  protected FlushRegionResponse call(HBaseRpcController controller) throws Exception {
068    // Check whether we should still do the flush to this region. If the regions are changed due
069    // to splits or merges, etc return success
070    if (!Bytes.equals(location.getRegionInfo().getRegionName(), regionName)) {
071      if (!reload) {
072        throw new IOException("Cached location seems to be different than requested region.");
073      }
074      LOG.info("Skipping flush region, because the located region "
075          + Bytes.toStringBinary(location.getRegionInfo().getRegionName()) + " is different than "
076          + " requested region " + Bytes.toStringBinary(regionName));
077      return FlushRegionResponse.newBuilder()
078          .setLastFlushTime(EnvironmentEdgeManager.currentTime())
079          .setFlushed(false)
080          .setWroteFlushWalMarker(false)
081          .build();
082    }
083
084    FlushRegionRequest request =
085        RequestConverter.buildFlushRegionRequest(regionName, writeFlushWalMarker);
086    return stub.flushRegion(controller, request);
087  }
088}