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;
019
020import java.io.IOException;
021
022import org.apache.yetus.audience.InterfaceAudience;
023import org.apache.hadoop.hbase.exceptions.DeserializationException;
024import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
025import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;
026import org.apache.hadoop.hbase.shaded.protobuf.generated.ZooKeeperProtos;
027import org.apache.hadoop.hbase.util.Bytes;
028
029/**
030 * State of a WAL log split during distributed splitting.  State is kept up in zookeeper.
031 * Encapsulates protobuf serialization/deserialization so we don't leak generated pb outside of
032 * this class.  Used by regionserver and master packages.
033 * <p>Immutable
034 * @deprecated since 2.4.0 and in 3.0.0, to be removed in 4.0.0, replaced by procedure-based
035 *   distributed WAL splitter, see SplitWALManager
036 */
037@Deprecated
038@InterfaceAudience.Private
039public class SplitLogTask {
040  private final ServerName originServer;
041  private final ZooKeeperProtos.SplitLogTask.State state;
042
043  public static class Unassigned extends SplitLogTask {
044    public Unassigned(final ServerName originServer) {
045      super(originServer, ZooKeeperProtos.SplitLogTask.State.UNASSIGNED);
046    }
047  }
048
049  public static class Owned extends SplitLogTask {
050    public Owned(final ServerName originServer) {
051      super(originServer, ZooKeeperProtos.SplitLogTask.State.OWNED);
052    }
053  }
054
055  public static class Resigned extends SplitLogTask {
056    public Resigned(final ServerName originServer) {
057      super(originServer, ZooKeeperProtos.SplitLogTask.State.RESIGNED);
058    }
059  }
060
061  public static class Done extends SplitLogTask {
062    public Done(final ServerName originServer) {
063      super(originServer, ZooKeeperProtos.SplitLogTask.State.DONE);
064    }
065  }
066
067  public static class Err extends SplitLogTask {
068    public Err(final ServerName originServer) {
069      super(originServer, ZooKeeperProtos.SplitLogTask.State.ERR);
070    }
071  }
072
073  SplitLogTask(final ZooKeeperProtos.SplitLogTask slt) {
074    this.originServer = ProtobufUtil.toServerName(slt.getServerName());
075    this.state = slt.getState();
076  }
077
078  SplitLogTask(final ServerName originServer, final ZooKeeperProtos.SplitLogTask.State state) {
079    this.originServer = originServer;
080    this.state = state;
081  }
082
083  public ServerName getServerName() {
084    return this.originServer;
085  }
086
087  public boolean isUnassigned(final ServerName sn) {
088    return this.originServer.equals(sn) && isUnassigned();
089  }
090
091  public boolean isUnassigned() {
092    return this.state == ZooKeeperProtos.SplitLogTask.State.UNASSIGNED;
093  }
094
095  public boolean isOwned(final ServerName sn) {
096    return this.originServer.equals(sn) && isOwned();
097  }
098
099  public boolean isOwned() {
100    return this.state == ZooKeeperProtos.SplitLogTask.State.OWNED;
101  }
102
103  public boolean isResigned(final ServerName sn) {
104    return this.originServer.equals(sn) && isResigned();
105  }
106
107  public boolean isResigned() {
108    return this.state == ZooKeeperProtos.SplitLogTask.State.RESIGNED;
109  }
110
111  public boolean isDone(final ServerName sn) {
112    return this.originServer.equals(sn) && isDone();
113  }
114
115  public boolean isDone() {
116    return this.state == ZooKeeperProtos.SplitLogTask.State.DONE;
117  }
118
119  public boolean isErr(final ServerName sn) {
120    return this.originServer.equals(sn) && isErr();
121  }
122
123  public boolean isErr() {
124    return this.state == ZooKeeperProtos.SplitLogTask.State.ERR;
125  }
126
127  @Override
128  public String toString() {
129    return this.state.toString() + " " + this.originServer.toString();
130  }
131
132  @Override
133  public boolean equals(Object obj) {
134    if (!(obj instanceof SplitLogTask)) return false;
135    SplitLogTask other = (SplitLogTask)obj;
136    return other.state.equals(this.state) && other.originServer.equals(this.originServer);
137  }
138
139  @Override
140  public int hashCode() {
141    int hash = 7;
142    hash = 31 * hash + this.state.hashCode();
143    return 31 * hash + this.originServer.hashCode();
144  }
145
146  /**
147   * @param data Serialized date to parse.
148   * @return An SplitLogTaskState instance made of the passed <code>data</code>
149   * @throws DeserializationException
150   * @see #toByteArray()
151   */
152  public static SplitLogTask parseFrom(final byte [] data) throws DeserializationException {
153    ProtobufUtil.expectPBMagicPrefix(data);
154    try {
155      int prefixLen = ProtobufUtil.lengthOfPBMagic();
156      ZooKeeperProtos.SplitLogTask.Builder builder = ZooKeeperProtos.SplitLogTask.newBuilder();
157      ProtobufUtil.mergeFrom(builder, data, prefixLen, data.length - prefixLen);
158      return new SplitLogTask(builder.build());
159    } catch (IOException e) {
160      throw new DeserializationException(Bytes.toStringBinary(data, 0, 64), e);
161    }
162  }
163
164  /**
165   * @return This instance serialized into a byte array
166   * @see #parseFrom(byte[])
167   */
168  public byte [] toByteArray() {
169    // First create a pb ServerName.  Then create a ByteString w/ the TaskState
170    // bytes in it.  Finally create a SplitLogTaskState passing in the two
171    // pbs just created.
172    HBaseProtos.ServerName snpb = ProtobufUtil.toServerName(this.originServer);
173    ZooKeeperProtos.SplitLogTask slts =
174      ZooKeeperProtos.SplitLogTask.newBuilder().setServerName(snpb).setState(this.state).build();
175    return ProtobufUtil.prependPBMagic(slts.toByteArray());
176  }
177}