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