View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase;
19  
20  import org.apache.hadoop.classification.InterfaceAudience;
21  import org.apache.hadoop.hbase.exceptions.DeserializationException;
22  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
23  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos;
24  import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos;
25  import org.apache.hadoop.hbase.util.Bytes;
26  
27  import com.google.protobuf.InvalidProtocolBufferException;
28  
29  /**
30   * State of a WAL log split during distributed splitting.  State is kept up in zookeeper.
31   * Encapsulates protobuf serialization/deserialization so we don't leak generated pb outside of
32   * this class.  Used by regionserver and master packages.
33   * <p>Immutable
34   */
35  @InterfaceAudience.Private
36  public class SplitLogTask {
37    private final ServerName originServer;
38    private final ZooKeeperProtos.SplitLogTask.State state;
39  
40    public static class Unassigned extends SplitLogTask {
41      public Unassigned(final ServerName originServer) {
42        super(originServer, ZooKeeperProtos.SplitLogTask.State.UNASSIGNED);
43      }
44    }
45  
46    public static class Owned extends SplitLogTask {
47      public Owned(final ServerName originServer) {
48        super(originServer, ZooKeeperProtos.SplitLogTask.State.OWNED);
49      }
50    }
51  
52    public static class Resigned extends SplitLogTask {
53      public Resigned(final ServerName originServer) {
54        super(originServer, ZooKeeperProtos.SplitLogTask.State.RESIGNED);
55      }
56    }
57  
58    public static class Done extends SplitLogTask {
59      public Done(final ServerName originServer) {
60        super(originServer, ZooKeeperProtos.SplitLogTask.State.DONE);
61      }
62    }
63  
64    public static class Err extends SplitLogTask {
65      public Err(final ServerName originServer) {
66        super(originServer, ZooKeeperProtos.SplitLogTask.State.ERR);
67      }
68    }
69  
70    SplitLogTask(final ZooKeeperProtos.SplitLogTask slt) {
71      this(ProtobufUtil.toServerName(slt.getServerName()), slt.getState());
72    }
73  
74    SplitLogTask(final ServerName originServer, final ZooKeeperProtos.SplitLogTask.State state) {
75      this.originServer = originServer;
76      this.state = state;
77    }
78  
79    public ServerName getServerName() {
80      return this.originServer;
81    }
82  
83    public boolean isUnassigned(final ServerName sn) {
84      return this.originServer.equals(sn) && isUnassigned();
85    }
86  
87    public boolean isUnassigned() {
88      return this.state == ZooKeeperProtos.SplitLogTask.State.UNASSIGNED;
89    }
90  
91    public boolean isOwned(final ServerName sn) {
92      return this.originServer.equals(sn) && isOwned();
93    }
94  
95    public boolean isOwned() {
96      return this.state == ZooKeeperProtos.SplitLogTask.State.OWNED;
97    }
98  
99    public boolean isResigned(final ServerName sn) {
100     return this.originServer.equals(sn) && isResigned();
101   }
102 
103   public boolean isResigned() {
104     return this.state == ZooKeeperProtos.SplitLogTask.State.RESIGNED;
105   }
106 
107   public boolean isDone(final ServerName sn) {
108     return this.originServer.equals(sn) && isDone();
109   }
110 
111   public boolean isDone() {
112     return this.state == ZooKeeperProtos.SplitLogTask.State.DONE;
113   }
114 
115   public boolean isErr(final ServerName sn) {
116     return this.originServer.equals(sn) && isErr();
117   }
118 
119   public boolean isErr() {
120     return this.state == ZooKeeperProtos.SplitLogTask.State.ERR;
121   }
122 
123   @Override
124   public String toString() {
125     return this.state.toString() + " " + this.originServer.toString();
126   }
127 
128   @Override
129   public boolean equals(Object obj) {
130     if (!(obj instanceof SplitLogTask)) return false;
131     SplitLogTask other = (SplitLogTask)obj;
132     return other.state.equals(this.state) && other.originServer.equals(this.originServer);
133   }
134 
135   @Override
136   public int hashCode() {
137     int hash = 7;
138     hash = 31 * hash + this.state.hashCode();
139     return 31 * hash + this.originServer.hashCode();
140   }
141 
142   /**
143    * @param data Serialized date to parse.
144    * @return An SplitLogTaskState instance made of the passed <code>data</code>
145    * @throws DeserializationException 
146    * @see #toByteArray()
147    */
148   public static SplitLogTask parseFrom(final byte [] data) throws DeserializationException {
149     ProtobufUtil.expectPBMagicPrefix(data);
150     try {
151       int prefixLen = ProtobufUtil.lengthOfPBMagic();
152       ZooKeeperProtos.SplitLogTask slt = ZooKeeperProtos.SplitLogTask.newBuilder().
153         mergeFrom(data, prefixLen, data.length - prefixLen).build();
154       return new SplitLogTask(slt);
155     } catch (InvalidProtocolBufferException e) {
156       throw new DeserializationException(Bytes.toStringBinary(data, 0, 64), e);
157     }
158   }
159 
160   /**
161    * @return This instance serialized into a byte array
162    * @see #parseFrom(byte[])
163    */
164   public byte [] toByteArray() {
165     // First create a pb ServerName.  Then create a ByteString w/ the TaskState
166     // bytes in it.  Finally create a SplitLogTaskState passing in the two
167     // pbs just created.
168     HBaseProtos.ServerName snpb = ProtobufUtil.toServerName(this.originServer);
169     ZooKeeperProtos.SplitLogTask slts =
170       ZooKeeperProtos.SplitLogTask.newBuilder().setServerName(snpb).setState(this.state).build();
171     return ProtobufUtil.prependPBMagic(slts.toByteArray());
172   }
173 }