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.master;
019
020import java.io.IOException;
021import org.apache.hadoop.conf.Configuration;
022import org.apache.hadoop.hbase.client.MasterSwitchType;
023import org.apache.hadoop.hbase.exceptions.DeserializationException;
024import org.apache.hadoop.hbase.master.region.MasterRegion;
025import org.apache.hadoop.hbase.zookeeper.ZKWatcher;
026import org.apache.hadoop.hbase.zookeeper.ZNodePaths;
027import org.apache.yetus.audience.InterfaceAudience;
028import org.apache.zookeeper.KeeperException;
029
030import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
031import org.apache.hadoop.hbase.shaded.protobuf.generated.ZooKeeperProtos;
032
033/**
034 * Tracks the switch of split and merge states.
035 */
036@InterfaceAudience.Private
037public class SplitOrMergeStateStore {
038
039  private static final String SPLIT_STATE_NAME = "split_enabled";
040
041  private static final String MERGE_STATE_NAME = "merge_enabled";
042
043  private SwitchStateStore splitStateStore;
044  private SwitchStateStore mergeStateStore;
045
046  public SplitOrMergeStateStore(MasterRegion masterRegion, ZKWatcher watcher, Configuration conf)
047    throws IOException, KeeperException, DeserializationException {
048    @SuppressWarnings("deprecation")
049    String splitZnode = ZNodePaths.joinZNode(watcher.getZNodePaths().switchZNode,
050      conf.get("zookeeper.znode.switch.split", "split"));
051    @SuppressWarnings("deprecation")
052    String mergeZnode = ZNodePaths.joinZNode(watcher.getZNodePaths().switchZNode,
053      conf.get("zookeeper.znode.switch.merge", "merge"));
054    splitStateStore = new SwitchStateStore(masterRegion, SPLIT_STATE_NAME, watcher, splitZnode);
055    mergeStateStore = new SwitchStateStore(masterRegion, MERGE_STATE_NAME, watcher, mergeZnode);
056  }
057
058  public boolean isSplitOrMergeEnabled(MasterSwitchType switchType) {
059    switch (switchType) {
060      case SPLIT:
061        return splitStateStore.get();
062      case MERGE:
063        return mergeStateStore.get();
064      default:
065        break;
066    }
067    return false;
068  }
069
070  public void setSplitOrMergeEnabled(boolean enabled, MasterSwitchType switchType)
071    throws IOException {
072    switch (switchType) {
073      case SPLIT:
074        splitStateStore.set(enabled);
075        break;
076      case MERGE:
077        mergeStateStore.set(enabled);
078        break;
079      default:
080        break;
081    }
082  }
083
084  private static final class SwitchStateStore extends BooleanStateStore {
085
086    public SwitchStateStore(MasterRegion masterRegion, String stateName, ZKWatcher watcher,
087      String zkPath) throws IOException, KeeperException, DeserializationException {
088      super(masterRegion, stateName, watcher, zkPath);
089    }
090
091    @Override
092    protected byte[] toByteArray(boolean enabled) {
093      ZooKeeperProtos.SwitchState.Builder builder = ZooKeeperProtos.SwitchState.newBuilder();
094      builder.setEnabled(enabled);
095      return ProtobufUtil.prependPBMagic(builder.build().toByteArray());
096    }
097
098    @Override
099    protected boolean parseFrom(byte[] bytes) throws DeserializationException {
100      ProtobufUtil.expectPBMagicPrefix(bytes);
101      ZooKeeperProtos.SwitchState.Builder builder = ZooKeeperProtos.SwitchState.newBuilder();
102      try {
103        int magicLen = ProtobufUtil.lengthOfPBMagic();
104        ProtobufUtil.mergeFrom(builder, bytes, magicLen, bytes.length - magicLen);
105      } catch (IOException e) {
106        throw new DeserializationException(e);
107      }
108      return builder.build().getEnabled();
109    }
110  }
111}